Subversion Repositories fastphp

Rev

Rev 3 | Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. unit Unit1;
  2.  
  3. (*
  4.   This program requires
  5.   - Microsoft Internet Controls (TWebBrowser)
  6.     If you are using Delphi 10.1 Starter Edition, please import the ActiveX TLB
  7.     "Microsoft Internet Controls"
  8.   - SynEdit
  9.     You can obtain SynEdit via Embarcadero GetIt
  10. *)
  11.  
  12. // TODO: localize
  13.  
  14. // TODO: wieso geht copy paste im twebbrowser nicht???
  15. // Wieso dauert webbrowser1 erste kompilierung so lange???
  16.  
  17. // Future ideas
  18. // - ToDo list
  19. // - Open/Save real files
  20. // - multiple scraps?
  21. // - verschiedene php versionen?
  22. // - webbrowser1 nur laden, wenn man den tab anwählt?
  23. // - doppelklick auf tab soll diesen schließen
  24. // - Strg+S
  25. // - tastenkombo für "springe zu zeile"
  26. // - Onlinehelp aufrufen
  27.  
  28. interface
  29.  
  30. uses
  31.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  32.   Dialogs, StdCtrls, OleCtrls, ComCtrls, ExtCtrls, ToolWin, IniFiles,
  33.   SynEditHighlighter, SynHighlighterPHP, SynEdit, SHDocVw_TLB;
  34.  
  35. type
  36.   TForm1 = class(TForm)
  37.     PageControl1: TPageControl;
  38.     PlaintextTabSheet: TTabSheet;
  39.     HtmlTabSheet: TTabSheet;
  40.     Memo2: TMemo;
  41.     WebBrowser1: TWebBrowser;
  42.     Splitter1: TSplitter;
  43.     PageControl2: TPageControl;
  44.     TabSheet3: TTabSheet;
  45.     HelpTabsheet: TTabSheet;
  46.     WebBrowser2: TWebBrowser;
  47.     OpenDialog1: TOpenDialog;
  48.     Panel1: TPanel;
  49.     OpenDialog2: TOpenDialog;
  50.     OpenDialog3: TOpenDialog;
  51.     SynEdit1: TSynEdit;
  52.     SynPHPSyn1: TSynPHPSyn;
  53.     procedure Run(Sender: TObject);
  54.     procedure FormShow(Sender: TObject);
  55.     procedure Memo1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  56.     procedure FormCreate(Sender: TObject);
  57.     procedure FormDestroy(Sender: TObject);
  58.     procedure FormClose(Sender: TObject; var Action: TCloseAction);
  59.     procedure PageControl2Changing(Sender: TObject; var AllowChange: Boolean);
  60.   private
  61.     CurSearchTerm: string;
  62.     HlpPrevPageIndex: integer;
  63.     procedure Help;
  64.     procedure ApplicationOnMessage(var Msg: tagMSG; var Handled: Boolean);
  65.   protected
  66.     FastPHPConfig: TMemIniFile;
  67.     ChmIndex: TMemIniFile;
  68.     function GetScrapFile: string;
  69.   end;
  70.  
  71. var
  72.   Form1: TForm1;
  73.  
  74. implementation
  75.  
  76. {$R *.dfm}
  77.  
  78. uses
  79.   Functions;
  80.  
  81. procedure TForm1.ApplicationOnMessage(var Msg: tagMSG; var Handled: Boolean);
  82. begin                    
  83.   case Msg.message of
  84.     WM_KEYUP:
  85.     begin
  86.       case Msg.wParam of
  87.         VK_ESCAPE:
  88.         begin
  89.           // It is necessary to use Application.OnMessage, because Form1.KeyPreview does not work when TWebBrowser has the focus
  90.           if (HlpPrevPageIndex <> -1) and (PageControl2.ActivePage = HelpTabSheet) and
  91.              (HelpTabsheet.TabVisible) then
  92.           begin
  93.             PageControl2.ActivePageIndex := HlpPrevPageIndex;
  94.             HelpTabsheet.TabVisible := false;
  95.           end;
  96.           Handled := true;
  97.         end;
  98.       end;
  99.     end;
  100.   end;
  101. end;
  102.  
  103. procedure TForm1.Run(Sender: TObject);
  104. var
  105.   phpExe: string;
  106. begin
  107.   if not FileExists(phpExe) then
  108.   begin
  109.     phpExe := FastPHPConfig.ReadString('Paths', 'PHPInterpreter', '');
  110.     if not FileExists(phpExe) then
  111.     begin
  112.       if not OpenDialog2.Execute then exit;
  113.       if not FileExists(OpenDialog2.FileName) then exit;
  114.       phpExe := OpenDialog2.FileName;
  115.  
  116.       if not IsValidPHPExe(phpExe) then
  117.       begin
  118.         ShowMessage('This is not a valid PHP executable.');
  119.         exit;
  120.       end;
  121.  
  122.       FastPHPConfig.WriteString('Paths', 'PHPInterpreter', phpExe);
  123.       FastPHPConfig.UpdateFile;
  124.     end;
  125.   end;
  126.  
  127.   SynEdit1.Lines.SaveToFile(GetScrapFile);
  128.  
  129.   memo2.Lines.Text := GetDosOutput('"'+phpExe+'" "'+GetScrapFile+'"', ExtractFileDir(Application.ExeName));
  130.  
  131.   BrowseContent(Webbrowser1, memo2.Lines.Text);
  132.  
  133.   if IsTextHTML(memo2.lines.text) then
  134.     PageControl1.ActivePage := HtmlTabSheet
  135.   else
  136.     PageControl1.ActivePage := PlaintextTabSheet;
  137. end;
  138.  
  139. procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
  140. begin
  141.   SynEdit1.Lines.SaveToFile(GetScrapFile);
  142. end;
  143.  
  144. procedure TForm1.FormCreate(Sender: TObject);
  145. begin
  146.   HlpPrevPageIndex := -1;
  147.   CurSearchTerm := '';
  148.   Application.OnMessage := ApplicationOnMessage;
  149.  
  150.   FastPHPConfig := TMemIniFile.Create(ChangeFileExt(Application.ExeName, '.ini'));
  151. end;
  152.  
  153. procedure TForm1.FormDestroy(Sender: TObject);
  154. begin
  155.   if Assigned(ChmIndex) then
  156.   begin
  157.     FreeAndNil(ChmIndex);
  158.   end;
  159.  
  160.   FastPHPConfig.UpdateFile;
  161.   FreeAndNil(FastPHPConfig);
  162. end;
  163.  
  164. procedure TForm1.FormShow(Sender: TObject);
  165. var
  166.   ScrapFile: string;
  167. begin
  168.   ScrapFile := GetScrapFile;
  169.   if ScrapFile = '' then
  170.   begin
  171.     Close;
  172.     exit;
  173.   end;
  174.   SynEdit1.Lines.LoadFromFile(ScrapFile);
  175.  
  176.   PageControl1.ActivePage := PlaintextTabSheet;
  177.  
  178.   PageControl2.ActivePageIndex := 0; // Scraps
  179.   HelpTabsheet.TabVisible := false;
  180. end;
  181.  
  182. function TForm1.GetScrapFile: string;
  183. begin
  184.   result := FastPHPConfig.ReadString('Paths', 'ScrapFile', '');
  185.   if not FileExists(result) then
  186.   begin
  187.     if not OpenDialog3.Execute then
  188.     begin
  189.       result := '';
  190.       exit;
  191.     end;
  192.  
  193.     result := OpenDialog3.FileName;
  194.  
  195.     if not DirectoryExists(ExtractFilePath(result)) then
  196.     begin
  197.       ShowMessage('Path does not exist!');
  198.       result := '';
  199.       exit;
  200.     end;
  201.  
  202.     SynEdit1.Lines.Clear;
  203.     SynEdit1.Lines.SaveToFile(result);
  204.  
  205.     FastPHPConfig.WriteString('Paths', 'ScrapFile', result);
  206.   end;
  207. end;
  208.  
  209. procedure TForm1.Help;
  210. var
  211.   IndexFile, chmFile, w, url: string;
  212.   internalHtmlFile: string;
  213. begin
  214.   if not Assigned(ChmIndex) then
  215.   begin
  216.     IndexFile := FastPHPConfig.ReadString('Paths', 'HelpIndex', '');
  217.     IndexFile := ChangeFileExt(IndexFile, '.ini'); // Just to be sure. Maybe someone wrote manually the ".chm" file in there
  218.     if FileExists(IndexFile) then
  219.     begin
  220.       ChmIndex := TMemIniFile.Create(IndexFile);
  221.     end;
  222.   end;
  223.  
  224.   if Assigned(ChmIndex) then
  225.   begin
  226.     IndexFile := FastPHPConfig.ReadString('Paths', 'HelpIndex', '');
  227.     // We don't check if IndexFile still exists. It is not important since we have ChmIndex pre-loaded in memory
  228.  
  229.     chmFile := ChangeFileExt(IndexFile, '.chm');
  230.     if not FileExists(chmFile) then
  231.     begin
  232.       FreeAndNil(ChmIndex);
  233.     end;
  234.   end;
  235.  
  236.   if not Assigned(ChmIndex) then
  237.   begin
  238.     if not OpenDialog1.Execute then exit;
  239.  
  240.     chmFile := OpenDialog1.FileName;
  241.     if not FileExists(chmFile) then exit;
  242.  
  243.     IndexFile := ChangeFileExt(chmFile, '.ini');
  244.  
  245.     if not FileExists(IndexFile) then
  246.     begin
  247.       Panel1.Align := alClient;
  248.       Panel1.Visible := true;
  249.       Panel1.BringToFront;
  250.       Screen.Cursor := crHourGlass;
  251.       Application.ProcessMessages;
  252.       try
  253.         if not ParseCHM(chmFile) then
  254.         begin
  255.           ShowMessage('The CHM file is not a valid PHP documentation. Cannot use help.');
  256.           exit;
  257.         end;
  258.       finally
  259.         Screen.Cursor := crDefault;
  260.         Panel1.Visible := false;
  261.       end;
  262.  
  263.       if not FileExists(IndexFile) then
  264.       begin
  265.         ShowMessage('Unknown error. Cannot use help.');
  266.         exit;
  267.       end;
  268.     end;
  269.  
  270.     FastPHPConfig.WriteString('Paths', 'HelpIndex', IndexFile);
  271.     FastPHPConfig.UpdateFile;
  272.  
  273.     ChmIndex := TMemIniFile.Create(IndexFile);
  274.   end;
  275.  
  276.   w := GetWordUnderCaret(SynEdit1);
  277.   if w = '' then exit;
  278.   if w[1] in ['0'..'9'] then exit;  
  279.   w := StringReplace(w, '_', '-', [rfReplaceAll]);
  280.   w := LowerCase(w);
  281.   CurSearchTerm := w;
  282.  
  283.   internalHtmlFile := ChmIndex.ReadString('_HelpWords_', CurSearchTerm, '');
  284.   if internalHtmlFile = '' then
  285.   begin
  286.     HelpTabsheet.TabVisible := false;
  287.     HlpPrevPageIndex := -1;
  288.     ShowMessage('No help for "'+CurSearchTerm+'" available');
  289.     Exit;
  290.   end;
  291.  
  292.   url := 'mk:@MSITStore:'+ChmFile+'::'+internalHtmlFile;
  293.  
  294.   HlpPrevPageIndex := PageControl2.ActivePageIndex; // Return by pressing ESC
  295.   HelpTabsheet.TabVisible := true;
  296.   PageControl2.ActivePage := HelpTabsheet;
  297.   BrowseURL(WebBrowser2, url);
  298. end;
  299.  
  300. procedure TForm1.Memo1KeyDown(Sender: TObject; var Key: Word;
  301.   Shift: TShiftState);
  302. begin
  303.   if (Key = VK_F9) or (Key = VK_F5) then
  304.     Run(Sender)
  305.   else if Key = VK_F1 then
  306.     Help;
  307. end;
  308.  
  309. procedure TForm1.PageControl2Changing(Sender: TObject;
  310.   var AllowChange: Boolean);
  311. begin
  312.   if PageControl2.ActivePage = HelpTabsheet then
  313.     HlpPrevPageIndex := -1
  314.   else
  315.     HlpPrevPageIndex := PageControl2.ActivePageIndex;
  316.  
  317.   AllowChange := true;
  318. end;
  319.  
  320. end.
  321.