Subversion Repositories fastphp

Rev

Rev 4 | Go to most recent revision | Show entire file | Ignore 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;
82
begin                    
104
  lineno: integer;
-
 
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
96
          Handled := true;
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
-
 
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
107
  if not FileExists(phpExe) then
166
  memo2.Lines.Text := '';
-
 
167
  BrowseContent(Webbrowser1, memo2.Lines.Text);
-
 
168
  Screen.Cursor := crHourGlass;
-
 
169
  Application.ProcessMessages;
-
 
170
 
108
  begin
171
  try
109
    phpExe := FastPHPConfig.ReadString('Paths', 'PHPInterpreter', '');
-
 
110
    if not FileExists(phpExe) then
172
    if not FileExists(phpExe) then
111
    begin
173
    begin
112
      if not OpenDialog2.Execute then exit;
-
 
113
      if not FileExists(OpenDialog2.FileName) then exit;
174
      phpExe := FastPHPConfig.ReadString('Paths', 'PHPInterpreter', '');
114
      phpExe := OpenDialog2.FileName;
-
 
115
 
-
 
116
      if not IsValidPHPExe(phpExe) then
175
      if not FileExists(phpExe) then
117
      begin
176
      begin
-
 
177
        if not OpenDialog2.Execute then exit;
-
 
178
        if not FileExists(OpenDialog2.FileName) then exit;
-
 
179
        phpExe := OpenDialog2.FileName;
-
 
180
 
-
 
181
        if not IsValidPHPExe(phpExe) then
-
 
182
        begin
118
        ShowMessage('This is not a valid PHP executable.');
183
          ShowMessage('This is not a valid PHP executable.');
119
        exit;
184
          exit;
120
      end;
185
        end;
121
 
186
 
122
      FastPHPConfig.WriteString('Paths', 'PHPInterpreter', phpExe);
187
        FastPHPConfig.WriteString('Paths', 'PHPInterpreter', phpExe);
123
      FastPHPConfig.UpdateFile;
188
        FastPHPConfig.UpdateFile;
-
 
189
      end;
124
    end;
190
    end;
-
 
191
 
-
 
192
    SynEdit1.Lines.SaveToFile(GetScrapFile);
-
 
193
 
-
 
194
    memo2.Lines.Text := GetDosOutput('"'+phpExe+'" "'+GetScrapFile+'"', ExtractFileDir(Application.ExeName));
-
 
195
 
-
 
196
    BrowseContent(Webbrowser1, MarkUpLineReference(memo2.Lines.Text));
-
 
197
 
-
 
198
    if IsTextHTML(memo2.lines.text) then
-
 
199
      PageControl1.ActivePage := HtmlTabSheet
-
 
200
    else
-
 
201
      PageControl1.ActivePage := PlaintextTabSheet;
-
 
202
  finally
-
 
203
    Screen.Cursor := crDefault;
125
  end;
204
  end;
-
 
205
end;
126
 
206
 
-
 
207
procedure TForm1.SynEditFocusTimerTimer(Sender: TObject);
-
 
208
begin
127
  SynEdit1.Lines.SaveToFile(GetScrapFile);
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;
128
 
213
 
-
 
214
procedure TForm1.WebBrowser1BeforeNavigate2(ASender: TObject;
129
  memo2.Lines.Text := GetDosOutput('"'+phpExe+'" "'+GetScrapFile+'"', ExtractFileDir(Application.ExeName));
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;
130
 
235
 
131
  BrowseContent(Webbrowser1, memo2.Lines.Text);
236
procedure TForm1.Button1Click(Sender: TObject);
-
 
237
begin
-
 
238
  Run(Sender);
-
 
239
  SynEdit1.SetFocus;
-
 
240
end;
132
 
241
 
133
  if IsTextHTML(memo2.lines.text) then
242
procedure TForm1.Button2Click(Sender: TObject);
-
 
243
begin
-
 
244
  Help;
134
    PageControl1.ActivePage := HtmlTabSheet
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;
135
  else
255
begin
-
 
256
  InputQuery('Go to', 'Line number:', val);
136
    PageControl1.ActivePage := PlaintextTabSheet;
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
 
-
 
424
procedure TForm1.GotoLineNo(LineNo:integer);
-
 
425
var
-
 
426
  line: string;
-
 
427
  i: integer;
-
 
428
begin
-
 
429
  SynEdit1.GotoLineAndCenter(LineNo);
-
 
430
 
-
 
431
  // Skip indent
-
 
432
  line := SynEdit1.Lines[SynEdit1.CaretY];
-
 
433
  for i := 1 to Length(line) do
-
 
434
  begin
-
 
435
    if not (line[i] in [' ', #9]) then
-
 
436
    begin
-
 
437
      SynEdit1.CaretX := i-1;
-
 
438
      break;
-
 
439
    end;
-
 
440
  end;
-
 
441
 
-
 
442
  PageControl2.ActivePage := TabSheet3{Scrap};
-
 
443
  if SynEdit1.CanFocus then SynEdit1.SetFocus;
-
 
444
end;
-
 
445
 
300
procedure TForm1.Memo1KeyDown(Sender: TObject; var Key: Word;
446
procedure TForm1.Memo2DblClick(Sender: TObject);
-
 
447
var
-
 
448
  line: string;
301
  Shift: TShiftState);
449
  p, lineno: integer;
302
begin
450
begin
-
 
451
  line := memo2.Lines.Strings[Memo2.CaretPos.Y];
303
  if (Key = VK_F9) or (Key = VK_F5) then
452
  p := Pos(' on line ', line);
304
    Run(Sender)
453
  if p = 0 then exit;
-
 
454
  line := copy(line, p+length(' on line '), 99);
305
  else if Key = VK_F1 then
455
  if not TryStrToInt(line, lineno) then exit;
306
    Help;
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.