Rev 7 | Rev 10 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 7 | Rev 8 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | unit Unit1; |
1 | unit EditorMain; |
2 | 2 | ||
3 | (* |
3 | (* |
4 | This program requires |
4 | This program requires |
5 | - Microsoft Internet Controls (TWebBrowser) |
5 | - Microsoft Internet Controls (TWebBrowser) |
6 | If you are using Delphi 10.1 Starter Edition, please import the ActiveX TLB |
6 | If you are using Delphi 10.1 Starter Edition, please import the ActiveX TLB |
Line 26... | Line 26... | ||
26 | // - Open/Save real files |
26 | // - Open/Save real files |
27 | // - multiple scraps? |
27 | // - multiple scraps? |
28 | // - verschiedene php versionen? |
28 | // - verschiedene php versionen? |
29 | // - webbrowser1 nur laden, wenn man den tab anwählt? |
29 | // - webbrowser1 nur laden, wenn man den tab anwählt? |
30 | // - doppelklick auf tab soll diesen schließen |
30 | // - doppelklick auf tab soll diesen schließen |
31 | // - Strg+S |
- | |
32 | // - Onlinehelp (www) aufrufen |
31 | // - Onlinehelp (www) aufrufen |
33 | 32 | ||
34 | interface |
33 | interface |
35 | 34 | ||
36 | uses |
35 | uses |
Line 50... | Line 49... | ||
50 | TabSheet3: TTabSheet; |
49 | TabSheet3: TTabSheet; |
51 | HelpTabsheet: TTabSheet; |
50 | HelpTabsheet: TTabSheet; |
52 | WebBrowser2: TWebBrowser; |
51 | WebBrowser2: TWebBrowser; |
53 | OpenDialog1: TOpenDialog; |
52 | OpenDialog1: TOpenDialog; |
54 | Panel1: TPanel; |
53 | Panel1: TPanel; |
55 | OpenDialog2: TOpenDialog; |
- | |
56 | OpenDialog3: TOpenDialog; |
54 | OpenDialog3: TOpenDialog; |
57 | SynEdit1: TSynEdit; |
55 | SynEdit1: TSynEdit; |
58 | SynPHPSyn1: TSynPHPSyn; |
56 | SynPHPSyn1: TSynPHPSyn; |
59 | Panel2: TPanel; |
57 | Panel2: TPanel; |
60 | SynEditFocusTimer: TTimer; |
58 | SynEditFocusTimer: TTimer; |
Line 80... | Line 78... | ||
80 | HlpPrevPageIndex: integer; |
78 | HlpPrevPageIndex: integer; |
81 | procedure Help; |
79 | procedure Help; |
82 | procedure ApplicationOnMessage(var Msg: tagMSG; var Handled: Boolean); |
80 | procedure ApplicationOnMessage(var Msg: tagMSG; var Handled: Boolean); |
83 | function MarkUpLineReference(cont: string): string; |
81 | function MarkUpLineReference(cont: string): string; |
84 | protected |
82 | protected |
85 | FastPHPConfig: TMemIniFile; |
- | |
86 | ChmIndex: TMemIniFile; |
83 | ChmIndex: TMemIniFile; |
87 | procedure GotoLineNo(LineNo:integer); |
84 | procedure GotoLineNo(LineNo:integer); |
88 | function GetScrapFile: string; |
85 | function GetScrapFile: string; |
89 | end; |
86 | end; |
90 | 87 | ||
Line 94... | Line 91... | ||
94 | implementation |
91 | implementation |
95 | 92 | ||
96 | {$R *.dfm} |
93 | {$R *.dfm} |
97 | 94 | ||
98 | uses |
95 | uses |
99 | Functions, StrUtils; |
96 | Functions, StrUtils, WebBrowserUtils, FastPHPUtils; |
100 | 97 | ||
101 | procedure TForm1.ApplicationOnMessage(var Msg: tagMSG; var Handled: Boolean); |
98 | procedure TForm1.ApplicationOnMessage(var Msg: tagMSG; var Handled: Boolean); |
102 | var |
99 | var |
103 | val: string; |
100 | val: string; |
104 | lineno: integer; |
101 | lineno: integer; |
Line 119... | Line 116... | ||
119 | HelpTabsheet.TabVisible := false; |
116 | HelpTabsheet.TabVisible := false; |
120 | end; |
117 | end; |
121 | end; |
118 | end; |
122 | {$ENDREGION} |
119 | {$ENDREGION} |
123 | 120 | ||
124 | {$REGION 'Ctrl+G : Go to line'} |
121 | {$REGION 'Ctrl+G (Go to line)'} |
125 | ord('G'): |
122 | ord('G'): |
126 | begin |
123 | begin |
127 | // TODO: VK_LMENU does not work! only works with AltGr but not Alt |
124 | // TODO: VK_LMENU does not work! only works with AltGr but not Alt |
128 | // http://stackoverflow.com/questions/16828250/delphi-xe2-how-to-prevent-the-alt-key-stealing-focus ? |
125 | // http://stackoverflow.com/questions/16828250/delphi-xe2-how-to-prevent-the-alt-key-stealing-focus ? |
129 | if (GetKeyState(VK_CONTROL) < 0) then |
126 | if (GetKeyState(VK_CONTROL) < 0) then |
Line 134... | Line 131... | ||
134 | GotoLineNo(lineno); |
131 | GotoLineNo(lineno); |
135 | end; |
132 | end; |
136 | end; |
133 | end; |
137 | {$ENDREGION} |
134 | {$ENDREGION} |
138 | 135 | ||
- | 136 | {$REGION 'Ctrl+S (Save)'} |
|
- | 137 | ord('S'): |
|
- | 138 | begin |
|
- | 139 | if (GetKeyState(VK_CONTROL) < 0) and (SynEdit1.Focused) then |
|
- | 140 | begin |
|
- | 141 | Handled := true; |
|
- | 142 | SynEdit1.Lines.SaveToFile(GetScrapFile); |
|
- | 143 | end; |
|
- | 144 | end; |
|
- | 145 | {$ENDREGION} |
|
- | 146 | ||
- | 147 | {$REGION 'F1 (Help)'} |
|
139 | VK_F1: |
148 | VK_F1: |
140 | begin |
149 | begin |
141 | if SynEdit1.Focused then |
150 | if SynEdit1.Focused then |
142 | begin |
151 | begin |
143 | Handled := true; |
152 | Handled := true; |
144 | Help; |
153 | Help; |
145 | end; |
154 | end; |
146 | end; |
155 | end; |
- | 156 | {$ENDREGION} |
|
147 | 157 | ||
- | 158 | {$REGION 'F5 (Run)'} |
|
148 | VK_F5: |
159 | VK_F5: |
149 | begin |
160 | begin |
150 | Run(Self); |
161 | Run(Self); |
151 | end; |
162 | end; |
- | 163 | {$ENDREGION} |
|
152 | 164 | ||
- | 165 | {$REGION 'F9 (Run)'} |
|
153 | VK_F9: |
166 | VK_F9: |
154 | begin |
167 | begin |
155 | Run(Self); |
168 | Run(Self); |
156 | end; |
169 | end; |
- | 170 | {$ENDREGION} |
|
157 | end; |
171 | end; |
158 | end; |
172 | end; |
159 | end; |
173 | end; |
160 | end; |
174 | end; |
161 | 175 | ||
162 | procedure TForm1.Run(Sender: TObject); |
176 | procedure TForm1.Run(Sender: TObject); |
163 | var |
- | |
164 | phpExe: string; |
- | |
165 | begin |
177 | begin |
166 | memo2.Lines.Text := ''; |
178 | memo2.Lines.Text := ''; |
167 | BrowseContent(Webbrowser1, memo2.Lines.Text); |
179 | Webbrowser1.Clear; |
168 | Screen.Cursor := crHourGlass; |
180 | Screen.Cursor := crHourGlass; |
169 | Application.ProcessMessages; |
181 | Application.ProcessMessages; |
170 | 182 | ||
171 | try |
183 | try |
172 | phpExe := FastPHPConfig.ReadString('Paths', 'PHPInterpreter', ''); |
- | |
173 | if not FileExists(phpExe) then |
- | |
174 | begin |
- | |
175 | if not OpenDialog2.Execute then exit; |
- | |
176 | if not FileExists(OpenDialog2.FileName) then exit; |
- | |
177 | phpExe := OpenDialog2.FileName; |
- | |
178 | - | ||
179 | if not IsValidPHPExe(phpExe) then |
- | |
180 | begin |
- | |
181 | ShowMessage('This is not a valid PHP executable.'); |
- | |
182 | exit; |
- | |
183 | end; |
- | |
184 | - | ||
185 | FastPHPConfig.WriteString('Paths', 'PHPInterpreter', phpExe); |
- | |
186 | FastPHPConfig.UpdateFile; |
- | |
187 | end; |
- | |
188 | - | ||
189 | SynEdit1.Lines.SaveToFile(GetScrapFile); |
184 | SynEdit1.Lines.SaveToFile(GetScrapFile); |
190 | 185 | ||
191 | memo2.Lines.Text := GetDosOutput('"'+phpExe+'" "'+GetScrapFile+'"', ExtractFileDir(Application.ExeName)); |
186 | memo2.Lines.Text := RunPHPScript(GetScrapFile); |
192 | 187 | ||
193 | BrowseContent(Webbrowser1, MarkUpLineReference(memo2.Lines.Text)); |
188 | Webbrowser1.LoadHTML(MarkUpLineReference(memo2.Lines.Text), GetScrapFile); |
194 | 189 | ||
195 | if IsTextHTML(memo2.lines.text) then |
190 | if IsTextHTML(memo2.lines.text) then |
196 | PageControl1.ActivePage := HtmlTabSheet |
191 | PageControl1.ActivePage := HtmlTabSheet |
197 | else |
192 | else |
198 | PageControl1.ActivePage := PlaintextTabSheet; |
193 | PageControl1.ActivePage := PlaintextTabSheet; |
Line 209... | Line 204... | ||
209 | end; |
204 | end; |
210 | 205 | ||
211 | procedure TForm1.WebBrowser1BeforeNavigate2(ASender: TObject; |
206 | procedure TForm1.WebBrowser1BeforeNavigate2(ASender: TObject; |
212 | const pDisp: IDispatch; const URL, Flags, TargetFrameName, PostData, |
207 | const pDisp: IDispatch; const URL, Flags, TargetFrameName, PostData, |
213 | Headers: OleVariant; var Cancel: WordBool); |
208 | Headers: OleVariant; var Cancel: WordBool); |
214 | const |
- | |
215 | MAG_BEGIN = 'fastphp://gotoline/'; |
- | |
216 | var |
209 | var |
217 | s, myURL, phpExe, scrapDir: string; |
210 | s, myURL: string; |
218 | lineno: integer; |
211 | lineno: integer; |
219 | p: integer; |
212 | p: integer; |
220 | begin |
213 | begin |
221 | {$REGION 'Line number references (PHP errors and warnings)'} |
214 | {$REGION 'Line number references (PHP errors and warnings)'} |
222 | if Copy(URL, 1, length(MAG_BEGIN)) = MAG_BEGIN then |
215 | if Copy(URL, 1, length(FASTPHP_GOTO_URI_PREFIX)) = FASTPHP_GOTO_URI_PREFIX then |
223 | begin |
216 | begin |
224 | try |
217 | try |
225 | s := copy(URL, length(MAG_BEGIN)+1, 99); |
218 | s := copy(URL, length(FASTPHP_GOTO_URI_PREFIX)+1, 99); |
226 | if not TryStrToInt(s, lineno) then exit; |
219 | if not TryStrToInt(s, lineno) then exit; |
227 | GotoLineNo(lineno); |
220 | GotoLineNo(lineno); |
228 | SynEditFocusTimer.Enabled := true; |
221 | SynEditFocusTimer.Enabled := true; |
229 | finally |
222 | finally |
230 | Cancel := true; |
223 | Cancel := true; |
231 | end; |
224 | end; |
- | 225 | Exit; |
|
232 | end; |
226 | end; |
233 | {$ENDREGION} |
227 | {$ENDREGION} |
234 | 228 | ||
235 | {$REGION 'Intelligent browser'} |
229 | {$REGION 'Intelligent browser (executes PHP scripts)'} |
236 | if URL <> 'about:blank' then |
230 | if URL <> 'about:blank' then |
237 | begin |
231 | begin |
238 | p := Pos('?', URL); |
- | |
239 | myUrl := URL; |
232 | myUrl := URL; |
240 | 233 | ||
- | 234 | p := Pos('?', myUrl); |
|
241 | myURL := StringReplace(myURL, 'about:', '', []); // TODO: ??? wenn ich von about:blank komme, dann ist ein link about:xyz.php ! |
235 | if p >= 1 then myURL := copy(myURL, 1, p-1); |
242 | 236 | ||
243 | // TODO: unabhängig vom scrap verzeichnis machen! |
237 | // TODO: myURL urldecode |
244 | scrapDir := FastPHPConfig.ReadString('Paths', 'ScrapFile', ''); |
238 | // TODO: maybe we could even open that file in the editor! |
245 | myURL := ExtractFileDir({Application.ExeName}scrapDir) + '\' + myURL; |
- | |
246 | 239 | ||
247 | if p >= 1 then myURL := copy(myURL, 1, p-1); |
240 | if FileExists(myURL) and (EndsText('.php', myURL) or EndsText('.php3', myURL) or EndsText('.php4', myURL) or EndsText('.php5', myURL) or EndsText('.phps', myURL)) then |
248 | if FileExists(myURL) then |
- | |
249 | begin |
241 | begin |
250 | phpExe := FastPHPConfig.ReadString('Paths', 'PHPInterpreter', ''); // TODO: check if available (auslagern) |
- | |
251 | - | ||
252 | BrowseContent(WebBrowser1, GetDosOutput('"'+phpExe+'" "'+myURL+'"', ExtractFileDir(Application.ExeName))); |
242 | WebBrowser1.LoadHTML(GetDosOutput('"'+GetPHPExe+'" "'+myURL+'"', ExtractFileDir(Application.ExeName)), myUrl); |
253 | Cancel := true; |
243 | Cancel := true; |
254 | end; |
244 | end; |
255 | end; |
245 | end; |
256 | {$ENDREGION} |
246 | {$ENDREGION} |
257 | end; |
247 | end; |
Line 293... | Line 283... | ||
293 | procedure TForm1.FormCreate(Sender: TObject); |
283 | procedure TForm1.FormCreate(Sender: TObject); |
294 | begin |
284 | begin |
295 | HlpPrevPageIndex := -1; |
285 | HlpPrevPageIndex := -1; |
296 | CurSearchTerm := ''; |
286 | CurSearchTerm := ''; |
297 | Application.OnMessage := ApplicationOnMessage; |
287 | Application.OnMessage := ApplicationOnMessage; |
298 | - | ||
299 | FastPHPConfig := TMemIniFile.Create(ChangeFileExt(Application.ExeName, '.ini')); |
- | |
300 | end; |
288 | end; |
301 | 289 | ||
302 | procedure TForm1.FormDestroy(Sender: TObject); |
290 | procedure TForm1.FormDestroy(Sender: TObject); |
303 | begin |
291 | begin |
304 | if Assigned(ChmIndex) then |
292 | if Assigned(ChmIndex) then |
305 | begin |
293 | begin |
306 | FreeAndNil(ChmIndex); |
294 | FreeAndNil(ChmIndex); |
307 | end; |
295 | end; |
308 | - | ||
309 | FastPHPConfig.UpdateFile; |
- | |
310 | FreeAndNil(FastPHPConfig); |
- | |
311 | end; |
296 | end; |
312 | 297 | ||
313 | procedure TForm1.FormShow(Sender: TObject); |
298 | procedure TForm1.FormShow(Sender: TObject); |
314 | var |
299 | var |
315 | ScrapFile: string; |
300 | ScrapFile: string; |
Line 424... | Line 409... | ||
424 | ChmIndex := TMemIniFile.Create(IndexFile); |
409 | ChmIndex := TMemIniFile.Create(IndexFile); |
425 | end; |
410 | end; |
426 | 411 | ||
427 | w := GetWordUnderCaret(SynEdit1); |
412 | w := GetWordUnderCaret(SynEdit1); |
428 | if w = '' then exit; |
413 | if w = '' then exit; |
429 | if w[1] in ['0'..'9'] then exit; |
414 | if CharInSet(w[1], ['0'..'9']) then exit; |
430 | w := StringReplace(w, '_', '-', [rfReplaceAll]); |
415 | w := StringReplace(w, '_', '-', [rfReplaceAll]); |
431 | w := LowerCase(w); |
416 | w := LowerCase(w); |
432 | CurSearchTerm := w; |
417 | CurSearchTerm := w; |
433 | 418 | ||
434 | internalHtmlFile := ChmIndex.ReadString('_HelpWords_', CurSearchTerm, ''); |
419 | internalHtmlFile := ChmIndex.ReadString('_HelpWords_', CurSearchTerm, ''); |
Line 443... | Line 428... | ||
443 | url := 'mk:@MSITStore:'+ChmFile+'::'+internalHtmlFile; |
428 | url := 'mk:@MSITStore:'+ChmFile+'::'+internalHtmlFile; |
444 | 429 | ||
445 | HlpPrevPageIndex := PageControl2.ActivePageIndex; // Return by pressing ESC |
430 | HlpPrevPageIndex := PageControl2.ActivePageIndex; // Return by pressing ESC |
446 | HelpTabsheet.TabVisible := true; |
431 | HelpTabsheet.TabVisible := true; |
447 | PageControl2.ActivePage := HelpTabsheet; |
432 | PageControl2.ActivePage := HelpTabsheet; |
- | 433 | WebBrowser2.Navigate(url); |
|
448 | BrowseURL(WebBrowser2, url); |
434 | WebBrowser2.Wait; |
449 | end; |
435 | end; |
450 | 436 | ||
451 | procedure TForm1.GotoLineNo(LineNo:integer); |
437 | procedure TForm1.GotoLineNo(LineNo:integer); |
452 | var |
438 | var |
453 | line: string; |
439 | line: string; |
Line 457... | Line 443... | ||
457 | 443 | ||
458 | // Skip indent |
444 | // Skip indent |
459 | line := SynEdit1.Lines[SynEdit1.CaretY]; |
445 | line := SynEdit1.Lines[SynEdit1.CaretY]; |
460 | for i := 1 to Length(line) do |
446 | for i := 1 to Length(line) do |
461 | begin |
447 | begin |
462 | if not (line[i] in [' ', #9]) then |
448 | if not CharInSet(line[i], [' ', #9]) then |
463 | begin |
449 | begin |
464 | SynEdit1.CaretX := i-1; |
450 | SynEdit1.CaretX := i-1; |
465 | break; |
451 | break; |
466 | end; |
452 | end; |
467 | end; |
453 | end; |
468 | 454 | ||
469 | PageControl2.ActivePage := TabSheet3{Scrap}; |
455 | PageControl2.ActivePage := TabSheet3{Scrap}; |
470 | if SynEdit1.CanFocus then SynEdit1.SetFocus; |
456 | if SynEdit1.CanFocus then SynEdit1.SetFocus; |
471 | end; |
457 | end; |
472 | 458 | ||
- | 459 | procedure TForm1.PageControl2Changing(Sender: TObject; |
|
- | 460 | var AllowChange: Boolean); |
|
- | 461 | begin |
|
- | 462 | if PageControl2.ActivePage = HelpTabsheet then |
|
- | 463 | HlpPrevPageIndex := -1 |
|
- | 464 | else |
|
- | 465 | HlpPrevPageIndex := PageControl2.ActivePageIndex; |
|
- | 466 | ||
- | 467 | AllowChange := true; |
|
- | 468 | end; |
|
- | 469 | ||
473 | procedure TForm1.Memo2DblClick(Sender: TObject); |
470 | procedure TForm1.Memo2DblClick(Sender: TObject); |
474 | var |
471 | var |
475 | line: string; |
472 | line: string; |
476 | p, lineno: integer; |
473 | p, lineno: integer; |
477 | begin |
474 | begin |
Line 481... | Line 478... | ||
481 | line := copy(line, p+length(' on line '), 99); |
478 | line := copy(line, p+length(' on line '), 99); |
482 | if not TryStrToInt(line, lineno) then exit; |
479 | if not TryStrToInt(line, lineno) then exit; |
483 | GotoLineNo(lineno); |
480 | GotoLineNo(lineno); |
484 | end; |
481 | end; |
485 | 482 | ||
486 | procedure TForm1.PageControl2Changing(Sender: TObject; |
- | |
487 | var AllowChange: Boolean); |
- | |
488 | begin |
- | |
489 | if PageControl2.ActivePage = HelpTabsheet then |
- | |
490 | HlpPrevPageIndex := -1 |
- | |
491 | else |
- | |
492 | HlpPrevPageIndex := PageControl2.ActivePageIndex; |
- | |
493 | - | ||
494 | AllowChange := true; |
- | |
495 | end; |
- | |
496 | - | ||
497 | function TForm1.MarkUpLineReference(cont: string): string; |
483 | function TForm1.MarkUpLineReference(cont: string): string; |
498 | var |
484 | var |
499 | p, a, b: integer; |
485 | p, a, b: integer; |
500 | num: integer; |
486 | num: integer; |
501 | insert_a, insert_b: string; |
487 | insert_a, insert_b: string; |
Line 505... | Line 491... | ||
505 | while p >= 1 do |
491 | while p >= 1 do |
506 | begin |
492 | begin |
507 | a := p+1; |
493 | a := p+1; |
508 | b := p+length(' on line '); |
494 | b := p+length(' on line '); |
509 | num := 0; |
495 | num := 0; |
510 | while cont[b] in ['0'..'9'] do |
496 | while CharInSet(cont[b], ['0'..'9']) do |
511 | begin |
497 | begin |
512 | num := num*10 + StrToInt(cont[b]); |
498 | num := num*10 + StrToInt(cont[b]); |
513 | inc(b); |
499 | inc(b); |
514 | end; |
500 | end; |
515 | 501 | ||
516 | insert_b := '</a>'; |
502 | insert_b := '</a>'; |
517 | insert_a := '<a href="fastphp://gotoline/'+IntToStr(num)+'">'; |
503 | insert_a := '<a href="'+FASTPHP_GOTO_URI_PREFIX+IntToStr(num)+'">'; |
518 | 504 | ||
519 | insert(insert_b, cont, b); |
505 | insert(insert_b, cont, b); |
520 | insert(insert_a, cont, a); |
506 | insert(insert_a, cont, a); |
521 | 507 | ||
522 | p := b + Length(insert_a) + Length(insert_b); |
508 | p := b + Length(insert_a) + Length(insert_b); |