Subversion Repositories fastphp

Rev

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);