Subversion Repositories fastphp

Rev

Rev 3 | Rev 5 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 daniel-mar 1
unit Unit1;
2
 
4 daniel-mar 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
 
2 daniel-mar 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
4 daniel-mar 20
// - multiple scraps?
2 daniel-mar 21
// - verschiedene php versionen?
22
// - webbrowser1 nur laden, wenn man den tab anwählt?
23
// - doppelklick auf tab soll diesen schließen
4 daniel-mar 24
// - Strg+S
3 daniel-mar 25
// - tastenkombo für "springe zu zeile"
26
// - Onlinehelp aufrufen
2 daniel-mar 27
 
28
interface
29
 
30
uses
31
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
4 daniel-mar 32
  Dialogs, StdCtrls, OleCtrls, ComCtrls, ExtCtrls, ToolWin, IniFiles,
33
  SynEditHighlighter, SynHighlighterPHP, SynEdit, SHDocVw_TLB;
2 daniel-mar 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;
4 daniel-mar 51
    SynEdit1: TSynEdit;
52
    SynPHPSyn1: TSynPHPSyn;
2 daniel-mar 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
 
4 daniel-mar 127
  SynEdit1.Lines.SaveToFile(GetScrapFile);
2 daniel-mar 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
4 daniel-mar 141
  SynEdit1.Lines.SaveToFile(GetScrapFile);
2 daniel-mar 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;
4 daniel-mar 174
  SynEdit1.Lines.LoadFromFile(ScrapFile);
2 daniel-mar 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
 
4 daniel-mar 202
    SynEdit1.Lines.Clear;
203
    SynEdit1.Lines.SaveToFile(result);
2 daniel-mar 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
 
4 daniel-mar 276
  w := GetWordUnderCaret(SynEdit1);
2 daniel-mar 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.