Rev 4 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4 | Rev 5 | ||
---|---|---|---|
Line 11... | Line 11... | ||
11 | 11 | ||
12 | // TODO: localize |
12 | // TODO: localize |
13 | 13 | ||
14 | // TODO: wieso geht copy paste im twebbrowser nicht??? |
14 | // TODO: wieso geht copy paste im twebbrowser nicht??? |
15 | // Wieso dauert webbrowser1 erste kompilierung so lange??? |
15 | // Wieso dauert webbrowser1 erste kompilierung so lange??? |
- | 16 | // TODO: wieso kommt syntax fehler zweimal? einmal stderr einmal stdout? |
|
- | 17 | // TODO: Browser titlebar (link preview) |
|
- | 18 | ||
- | 19 | // TODO: strg+f / h |
|
- | 20 | // TODO: font bigger |
|
- | 21 | // TODO: code in bildschirmmitte? |
|
- | 22 | // TODO: regelmäßig scrap zwischenspeichern, oder bei strg+s |
|
16 | 23 | ||
17 | // Future ideas |
24 | // Future ideas |
18 | // - ToDo list |
25 | // - ToDo list |
19 | // - Open/Save real files |
26 | // - Open/Save real files |
20 | // - multiple scraps? |
27 | // - multiple scraps? |
21 | // - verschiedene php versionen? |
28 | // - verschiedene php versionen? |
22 | // - webbrowser1 nur laden, wenn man den tab anwählt? |
29 | // - webbrowser1 nur laden, wenn man den tab anwählt? |
23 | // - doppelklick auf tab soll diesen schließen |
30 | // - doppelklick auf tab soll diesen schließen |
24 | // - Strg+S |
31 | // - Strg+S |
25 | // - tastenkombo für "springe zu zeile" |
- | |
26 | // - Onlinehelp aufrufen |
32 | // - Onlinehelp (www) aufrufen |
27 | 33 | ||
28 | interface |
34 | interface |
29 | 35 | ||
30 | uses |
36 | uses |
31 | Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, |
37 | Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, |
Line 48... | Line 54... | ||
48 | Panel1: TPanel; |
54 | Panel1: TPanel; |
49 | OpenDialog2: TOpenDialog; |
55 | OpenDialog2: TOpenDialog; |
50 | OpenDialog3: TOpenDialog; |
56 | OpenDialog3: TOpenDialog; |
51 | SynEdit1: TSynEdit; |
57 | SynEdit1: TSynEdit; |
52 | SynPHPSyn1: TSynPHPSyn; |
58 | SynPHPSyn1: TSynPHPSyn; |
- | 59 | Panel2: TPanel; |
|
- | 60 | SynEditFocusTimer: TTimer; |
|
- | 61 | Button1: TButton; |
|
- | 62 | Button2: TButton; |
|
- | 63 | Button3: TButton; |
|
53 | procedure Run(Sender: TObject); |
64 | procedure Run(Sender: TObject); |
54 | procedure FormShow(Sender: TObject); |
65 | procedure FormShow(Sender: TObject); |
55 | procedure Memo1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); |
- | |
56 | procedure FormCreate(Sender: TObject); |
66 | procedure FormCreate(Sender: TObject); |
57 | procedure FormDestroy(Sender: TObject); |
67 | procedure FormDestroy(Sender: TObject); |
58 | procedure FormClose(Sender: TObject; var Action: TCloseAction); |
68 | procedure FormClose(Sender: TObject; var Action: TCloseAction); |
59 | procedure PageControl2Changing(Sender: TObject; var AllowChange: Boolean); |
69 | procedure PageControl2Changing(Sender: TObject; var AllowChange: Boolean); |
- | 70 | procedure Memo2DblClick(Sender: TObject); |
|
- | 71 | procedure WebBrowser1BeforeNavigate2(ASender: TObject; |
|
- | 72 | const pDisp: IDispatch; const URL, Flags, TargetFrameName, PostData, |
|
- | 73 | Headers: OleVariant; var Cancel: WordBool); |
|
- | 74 | procedure SynEditFocusTimerTimer(Sender: TObject); |
|
- | 75 | procedure Button1Click(Sender: TObject); |
|
- | 76 | procedure Button2Click(Sender: TObject); |
|
- | 77 | procedure Button3Click(Sender: TObject); |
|
60 | private |
78 | private |
61 | CurSearchTerm: string; |
79 | CurSearchTerm: string; |
62 | HlpPrevPageIndex: integer; |
80 | HlpPrevPageIndex: integer; |
63 | procedure Help; |
81 | procedure Help; |
64 | procedure ApplicationOnMessage(var Msg: tagMSG; var Handled: Boolean); |
82 | procedure ApplicationOnMessage(var Msg: tagMSG; var Handled: Boolean); |
- | 83 | function MarkUpLineReference(cont: string): string; |
|
65 | protected |
84 | protected |
66 | FastPHPConfig: TMemIniFile; |
85 | FastPHPConfig: TMemIniFile; |
67 | ChmIndex: TMemIniFile; |
86 | ChmIndex: TMemIniFile; |
- | 87 | procedure GotoLineNo(LineNo:integer); |
|
68 | function GetScrapFile: string; |
88 | function GetScrapFile: string; |
69 | end; |
89 | end; |
70 | 90 | ||
71 | var |
91 | var |
72 | Form1: TForm1; |
92 | Form1: TForm1; |
Line 74... | Line 94... | ||
74 | implementation |
94 | implementation |
75 | 95 | ||
76 | {$R *.dfm} |
96 | {$R *.dfm} |
77 | 97 | ||
78 | uses |
98 | uses |
79 | Functions; |
99 | Functions, StrUtils; |
80 | 100 | ||
81 | procedure TForm1.ApplicationOnMessage(var Msg: tagMSG; var Handled: Boolean); |
101 | procedure TForm1.ApplicationOnMessage(var Msg: tagMSG; var Handled: Boolean); |
- | 102 | var |
|
- | 103 | val: string; |
|
- | 104 | lineno: integer; |
|
82 | begin |
105 | begin |
83 | case Msg.message of |
106 | case Msg.message of |
84 | WM_KEYUP: |
107 | WM_KEYUP: |
85 | begin |
108 | begin |
86 | case Msg.wParam of |
109 | case Msg.wParam of |
- | 110 | {$REGION 'Esc'} |
|
87 | VK_ESCAPE: |
111 | VK_ESCAPE: |
88 | begin |
112 | begin |
- | 113 | Handled := true; |
|
89 | // It is necessary to use Application.OnMessage, because Form1.KeyPreview does not work when TWebBrowser has the focus |
114 | // 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 |
115 | if (HlpPrevPageIndex <> -1) and (PageControl2.ActivePage = HelpTabSheet) and |
91 | (HelpTabsheet.TabVisible) then |
116 | (HelpTabsheet.TabVisible) then |
92 | begin |
117 | begin |
93 | PageControl2.ActivePageIndex := HlpPrevPageIndex; |
118 | PageControl2.ActivePageIndex := HlpPrevPageIndex; |
94 | HelpTabsheet.TabVisible := false; |
119 | HelpTabsheet.TabVisible := false; |
95 | end; |
120 | end; |
- | 121 | end; |
|
- | 122 | {$ENDREGION} |
|
- | 123 | ||
- | 124 | {$REGION 'Ctrl+G : Go to line'} |
|
- | 125 | ord('G'): |
|
- | 126 | begin |
|
- | 127 | // 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 ? |
|
- | 129 | if (GetKeyState(VK_CONTROL) < 0) then |
|
- | 130 | begin |
|
- | 131 | Handled := true; |
|
- | 132 | InputQuery('Go to', 'Line number:', val); |
|
- | 133 | if not TryStrToInt(val, lineno) then exit; |
|
- | 134 | GotoLineNo(lineno); |
|
- | 135 | end; |
|
- | 136 | end; |
|
- | 137 | {$ENDREGION} |
|
- | 138 | ||
- | 139 | VK_F1: |
|
- | 140 | begin |
|
- | 141 | if SynEdit1.Focused then |
|
- | 142 | begin |
|
96 | Handled := true; |
143 | Handled := true; |
- | 144 | Help; |
|
- | 145 | end; |
|
- | 146 | end; |
|
- | 147 | ||
- | 148 | VK_F5: |
|
- | 149 | begin |
|
- | 150 | Run(Self); |
|
- | 151 | end; |
|
- | 152 | ||
- | 153 | VK_F9: |
|
- | 154 | begin |
|
- | 155 | Run(Self); |
|
97 | end; |
156 | end; |
98 | end; |
157 | end; |
99 | end; |
158 | end; |
100 | end; |
159 | end; |
101 | end; |
160 | end; |
102 | 161 | ||
103 | procedure TForm1.Run(Sender: TObject); |
162 | procedure TForm1.Run(Sender: TObject); |
104 | var |
163 | var |
105 | phpExe: string; |
164 | phpExe: string; |
106 | begin |
165 | begin |
- | 166 | memo2.Lines.Text := ''; |
|
- | 167 | BrowseContent(Webbrowser1, memo2.Lines.Text); |
|
- | 168 | Screen.Cursor := crHourGlass; |
|
- | 169 | Application.ProcessMessages; |
|
- | 170 | ||
- | 171 | try |
|
107 | if not FileExists(phpExe) then |
172 | if not FileExists(phpExe) then |
108 | begin |
173 | begin |
109 | phpExe := FastPHPConfig.ReadString('Paths', 'PHPInterpreter', ''); |
174 | phpExe := FastPHPConfig.ReadString('Paths', 'PHPInterpreter', ''); |
110 | if not FileExists(phpExe) then |
175 | if not FileExists(phpExe) then |
111 | begin |
176 | begin |
Line 126... | Line 191... | ||
126 | 191 | ||
127 | SynEdit1.Lines.SaveToFile(GetScrapFile); |
192 | SynEdit1.Lines.SaveToFile(GetScrapFile); |
128 | 193 | ||
129 | memo2.Lines.Text := GetDosOutput('"'+phpExe+'" "'+GetScrapFile+'"', ExtractFileDir(Application.ExeName)); |
194 | memo2.Lines.Text := GetDosOutput('"'+phpExe+'" "'+GetScrapFile+'"', ExtractFileDir(Application.ExeName)); |
130 | 195 | ||
131 | BrowseContent(Webbrowser1, memo2.Lines.Text); |
196 | BrowseContent(Webbrowser1, MarkUpLineReference(memo2.Lines.Text)); |
132 | 197 | ||
133 | if IsTextHTML(memo2.lines.text) then |
198 | if IsTextHTML(memo2.lines.text) then |
134 | PageControl1.ActivePage := HtmlTabSheet |
199 | PageControl1.ActivePage := HtmlTabSheet |
135 | else |
200 | else |
136 | PageControl1.ActivePage := PlaintextTabSheet; |
201 | PageControl1.ActivePage := PlaintextTabSheet; |
- | 202 | finally |
|
- | 203 | Screen.Cursor := crDefault; |
|
- | 204 | end; |
|
- | 205 | end; |
|
- | 206 | ||
- | 207 | procedure TForm1.SynEditFocusTimerTimer(Sender: TObject); |
|
- | 208 | begin |
|
- | 209 | SynEditFocusTimer.Enabled := false; |
|
- | 210 | Button1.SetFocus; // Workaround for weird bug... This (and the timer) is necessary to get the focus to SynEdit1 |
|
- | 211 | SynEdit1.SetFocus; |
|
- | 212 | end; |
|
- | 213 | ||
- | 214 | procedure TForm1.WebBrowser1BeforeNavigate2(ASender: TObject; |
|
- | 215 | const pDisp: IDispatch; const URL, Flags, TargetFrameName, PostData, |
|
- | 216 | Headers: OleVariant; var Cancel: WordBool); |
|
- | 217 | const |
|
- | 218 | MAG_BEGIN = 'fastphp://gotoline/'; |
|
- | 219 | var |
|
- | 220 | s: string; |
|
- | 221 | lineno: integer; |
|
- | 222 | begin |
|
- | 223 | if Copy(URL, 1, length(MAG_BEGIN)) = MAG_BEGIN then |
|
- | 224 | begin |
|
- | 225 | try |
|
- | 226 | s := copy(URL, length(MAG_BEGIN)+1, 99); |
|
- | 227 | if not TryStrToInt(s, lineno) then exit; |
|
- | 228 | GotoLineNo(lineno); |
|
- | 229 | SynEditFocusTimer.Enabled := true; |
|
- | 230 | finally |
|
- | 231 | Cancel := true; |
|
- | 232 | end; |
|
- | 233 | end; |
|
- | 234 | end; |
|
- | 235 | ||
- | 236 | procedure TForm1.Button1Click(Sender: TObject); |
|
- | 237 | begin |
|
- | 238 | Run(Sender); |
|
- | 239 | SynEdit1.SetFocus; |
|
- | 240 | end; |
|
- | 241 | ||
- | 242 | procedure TForm1.Button2Click(Sender: TObject); |
|
- | 243 | begin |
|
- | 244 | Help; |
|
- | 245 | if PageControl2.ActivePage = HelpTabsheet then |
|
- | 246 | WebBrowser2.SetFocus |
|
- | 247 | else if PageControl2.ActivePage = TabSheet3{Scrap} then |
|
- | 248 | SynEdit1.SetFocus; |
|
- | 249 | end; |
|
- | 250 | ||
- | 251 | procedure TForm1.Button3Click(Sender: TObject); |
|
- | 252 | var |
|
- | 253 | val: string; |
|
- | 254 | lineno: integer; |
|
- | 255 | begin |
|
- | 256 | InputQuery('Go to', 'Line number:', val); |
|
- | 257 | if not TryStrToInt(val, lineno) then exit; |
|
- | 258 | GotoLineNo(lineno); |
|
137 | end; |
259 | end; |
138 | 260 | ||
139 | procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); |
261 | procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); |
140 | begin |
262 | begin |
141 | SynEdit1.Lines.SaveToFile(GetScrapFile); |
263 | SynEdit1.Lines.SaveToFile(GetScrapFile); |
Line 175... | Line 297... | ||
175 | 297 | ||
176 | PageControl1.ActivePage := PlaintextTabSheet; |
298 | PageControl1.ActivePage := PlaintextTabSheet; |
177 | 299 | ||
178 | PageControl2.ActivePageIndex := 0; // Scraps |
300 | PageControl2.ActivePageIndex := 0; // Scraps |
179 | HelpTabsheet.TabVisible := false; |
301 | HelpTabsheet.TabVisible := false; |
- | 302 | ||
- | 303 | SynEdit1.SetFocus; |
|
180 | end; |
304 | end; |
181 | 305 | ||
182 | function TForm1.GetScrapFile: string; |
306 | function TForm1.GetScrapFile: string; |
183 | begin |
307 | begin |
184 | result := FastPHPConfig.ReadString('Paths', 'ScrapFile', ''); |
308 | result := FastPHPConfig.ReadString('Paths', 'ScrapFile', ''); |
Line 295... | Line 419... | ||
295 | HelpTabsheet.TabVisible := true; |
419 | HelpTabsheet.TabVisible := true; |
296 | PageControl2.ActivePage := HelpTabsheet; |
420 | PageControl2.ActivePage := HelpTabsheet; |
297 | BrowseURL(WebBrowser2, url); |
421 | BrowseURL(WebBrowser2, url); |
298 | end; |
422 | end; |
299 | 423 | ||
300 | procedure TForm1.Memo1KeyDown(Sender: TObject; var Key: Word; |
424 | procedure TForm1.GotoLineNo(LineNo:integer); |
- | 425 | var |
|
- | 426 | line: string; |
|
301 | Shift: TShiftState); |
427 | i: integer; |
302 | begin |
428 | begin |
303 | if (Key = VK_F9) or (Key = VK_F5) then |
429 | SynEdit1.GotoLineAndCenter(LineNo); |
- | 430 | ||
304 | Run(Sender) |
431 | // Skip indent |
- | 432 | line := SynEdit1.Lines[SynEdit1.CaretY]; |
|
- | 433 | for i := 1 to Length(line) do |
|
- | 434 | begin |
|
305 | else if Key = VK_F1 then |
435 | if not (line[i] in [' ', #9]) then |
- | 436 | begin |
|
- | 437 | SynEdit1.CaretX := i-1; |
|
- | 438 | break; |
|
306 | Help; |
439 | end; |
- | 440 | end; |
|
- | 441 | ||
- | 442 | PageControl2.ActivePage := TabSheet3{Scrap}; |
|
- | 443 | if SynEdit1.CanFocus then SynEdit1.SetFocus; |
|
- | 444 | end; |
|
- | 445 | ||
- | 446 | procedure TForm1.Memo2DblClick(Sender: TObject); |
|
- | 447 | var |
|
- | 448 | line: string; |
|
- | 449 | p, lineno: integer; |
|
- | 450 | begin |
|
- | 451 | line := memo2.Lines.Strings[Memo2.CaretPos.Y]; |
|
- | 452 | p := Pos(' on line ', line); |
|
- | 453 | if p = 0 then exit; |
|
- | 454 | line := copy(line, p+length(' on line '), 99); |
|
- | 455 | if not TryStrToInt(line, lineno) then exit; |
|
- | 456 | GotoLineNo(lineno); |
|
307 | end; |
457 | end; |
308 | 458 | ||
309 | procedure TForm1.PageControl2Changing(Sender: TObject; |
459 | procedure TForm1.PageControl2Changing(Sender: TObject; |
310 | var AllowChange: Boolean); |
460 | var AllowChange: Boolean); |
311 | begin |
461 | begin |
Line 315... | Line 465... | ||
315 | HlpPrevPageIndex := PageControl2.ActivePageIndex; |
465 | HlpPrevPageIndex := PageControl2.ActivePageIndex; |
316 | 466 | ||
317 | AllowChange := true; |
467 | AllowChange := true; |
318 | end; |
468 | end; |
319 | 469 | ||
- | 470 | function TForm1.MarkUpLineReference(cont: string): string; |
|
- | 471 | var |
|
- | 472 | p, a, b: integer; |
|
- | 473 | num: integer; |
|
- | 474 | insert_a, insert_b: string; |
|
- | 475 | begin |
|
- | 476 | // TODO: make it more specific to PHP error messages. "on line" is too broad. |
|
- | 477 | p := Pos(' on line ', cont); |
|
- | 478 | while p >= 1 do |
|
- | 479 | begin |
|
- | 480 | a := p+1; |
|
- | 481 | b := p+length(' on line '); |
|
- | 482 | num := 0; |
|
- | 483 | while cont[b] in ['0'..'9'] do |
|
- | 484 | begin |
|
- | 485 | num := num*10 + StrToInt(cont[b]); |
|
- | 486 | inc(b); |
|
- | 487 | end; |
|
- | 488 | ||
- | 489 | insert_b := '</a>'; |
|
- | 490 | insert_a := '<a href="fastphp://gotoline/'+IntToStr(num)+'">'; |
|
- | 491 | ||
- | 492 | insert(insert_b, cont, b); |
|
- | 493 | insert(insert_a, cont, a); |
|
- | 494 | ||
- | 495 | p := b + Length(insert_a) + Length(insert_b); |
|
- | 496 | ||
- | 497 | p := PosEx(' on line ', cont, p+1); |
|
- | 498 | end; |
|
- | 499 | ||
- | 500 | result := cont; |
|
- | 501 | end; |
|
- | 502 | ||
320 | end. |
503 | end. |