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. |