13,7 → 13,14 |
|
// TODO: wieso geht copy paste im twebbrowser nicht??? |
// Wieso dauert webbrowser1 erste kompilierung so lange??? |
// TODO: wieso kommt syntax fehler zweimal? einmal stderr einmal stdout? |
// TODO: Browser titlebar (link preview) |
|
// TODO: strg+f / h |
// TODO: font bigger |
// TODO: code in bildschirmmitte? |
// TODO: regelmäßig scrap zwischenspeichern, oder bei strg+s |
|
// Future ideas |
// - ToDo list |
// - Open/Save real files |
22,8 → 29,7 |
// - webbrowser1 nur laden, wenn man den tab anwählt? |
// - doppelklick auf tab soll diesen schließen |
// - Strg+S |
// - tastenkombo für "springe zu zeile" |
// - Onlinehelp aufrufen |
// - Onlinehelp (www) aufrufen |
|
interface |
|
50,21 → 56,35 |
OpenDialog3: TOpenDialog; |
SynEdit1: TSynEdit; |
SynPHPSyn1: TSynPHPSyn; |
Panel2: TPanel; |
SynEditFocusTimer: TTimer; |
Button1: TButton; |
Button2: TButton; |
Button3: TButton; |
procedure Run(Sender: TObject); |
procedure FormShow(Sender: TObject); |
procedure Memo1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); |
procedure FormCreate(Sender: TObject); |
procedure FormDestroy(Sender: TObject); |
procedure FormClose(Sender: TObject; var Action: TCloseAction); |
procedure PageControl2Changing(Sender: TObject; var AllowChange: Boolean); |
procedure Memo2DblClick(Sender: TObject); |
procedure WebBrowser1BeforeNavigate2(ASender: TObject; |
const pDisp: IDispatch; const URL, Flags, TargetFrameName, PostData, |
Headers: OleVariant; var Cancel: WordBool); |
procedure SynEditFocusTimerTimer(Sender: TObject); |
procedure Button1Click(Sender: TObject); |
procedure Button2Click(Sender: TObject); |
procedure Button3Click(Sender: TObject); |
private |
CurSearchTerm: string; |
HlpPrevPageIndex: integer; |
procedure Help; |
procedure ApplicationOnMessage(var Msg: tagMSG; var Handled: Boolean); |
function MarkUpLineReference(cont: string): string; |
protected |
FastPHPConfig: TMemIniFile; |
ChmIndex: TMemIniFile; |
procedure GotoLineNo(LineNo:integer); |
function GetScrapFile: string; |
end; |
|
76,16 → 96,21 |
{$R *.dfm} |
|
uses |
Functions; |
Functions, StrUtils; |
|
procedure TForm1.ApplicationOnMessage(var Msg: tagMSG; var Handled: Boolean); |
var |
val: string; |
lineno: integer; |
begin |
case Msg.message of |
WM_KEYUP: |
begin |
case Msg.wParam of |
{$REGION 'Esc'} |
VK_ESCAPE: |
begin |
Handled := true; |
// It is necessary to use Application.OnMessage, because Form1.KeyPreview does not work when TWebBrowser has the focus |
if (HlpPrevPageIndex <> -1) and (PageControl2.ActivePage = HelpTabSheet) and |
(HelpTabsheet.TabVisible) then |
93,17 → 118,57 |
PageControl2.ActivePageIndex := HlpPrevPageIndex; |
HelpTabsheet.TabVisible := false; |
end; |
end; |
{$ENDREGION} |
|
{$REGION 'Ctrl+G : Go to line'} |
ord('G'): |
begin |
// TODO: VK_LMENU does not work! only works with AltGr but not Alt |
// http://stackoverflow.com/questions/16828250/delphi-xe2-how-to-prevent-the-alt-key-stealing-focus ? |
if (GetKeyState(VK_CONTROL) < 0) then |
begin |
Handled := true; |
InputQuery('Go to', 'Line number:', val); |
if not TryStrToInt(val, lineno) then exit; |
GotoLineNo(lineno); |
end; |
end; |
{$ENDREGION} |
|
VK_F1: |
begin |
if SynEdit1.Focused then |
begin |
Handled := true; |
Help; |
end; |
end; |
|
VK_F5: |
begin |
Run(Self); |
end; |
|
VK_F9: |
begin |
Run(Self); |
end; |
end; |
end; |
end; |
end; |
|
procedure TForm1.Run(Sender: TObject); |
var |
phpExe: string; |
begin |
memo2.Lines.Text := ''; |
BrowseContent(Webbrowser1, memo2.Lines.Text); |
Screen.Cursor := crHourGlass; |
Application.ProcessMessages; |
|
try |
if not FileExists(phpExe) then |
begin |
phpExe := FastPHPConfig.ReadString('Paths', 'PHPInterpreter', ''); |
128,14 → 193,71 |
|
memo2.Lines.Text := GetDosOutput('"'+phpExe+'" "'+GetScrapFile+'"', ExtractFileDir(Application.ExeName)); |
|
BrowseContent(Webbrowser1, memo2.Lines.Text); |
BrowseContent(Webbrowser1, MarkUpLineReference(memo2.Lines.Text)); |
|
if IsTextHTML(memo2.lines.text) then |
PageControl1.ActivePage := HtmlTabSheet |
else |
PageControl1.ActivePage := PlaintextTabSheet; |
finally |
Screen.Cursor := crDefault; |
end; |
end; |
|
procedure TForm1.SynEditFocusTimerTimer(Sender: TObject); |
begin |
SynEditFocusTimer.Enabled := false; |
Button1.SetFocus; // Workaround for weird bug... This (and the timer) is necessary to get the focus to SynEdit1 |
SynEdit1.SetFocus; |
end; |
|
procedure TForm1.WebBrowser1BeforeNavigate2(ASender: TObject; |
const pDisp: IDispatch; const URL, Flags, TargetFrameName, PostData, |
Headers: OleVariant; var Cancel: WordBool); |
const |
MAG_BEGIN = 'fastphp://gotoline/'; |
var |
s: string; |
lineno: integer; |
begin |
if Copy(URL, 1, length(MAG_BEGIN)) = MAG_BEGIN then |
begin |
try |
s := copy(URL, length(MAG_BEGIN)+1, 99); |
if not TryStrToInt(s, lineno) then exit; |
GotoLineNo(lineno); |
SynEditFocusTimer.Enabled := true; |
finally |
Cancel := true; |
end; |
end; |
end; |
|
procedure TForm1.Button1Click(Sender: TObject); |
begin |
Run(Sender); |
SynEdit1.SetFocus; |
end; |
|
procedure TForm1.Button2Click(Sender: TObject); |
begin |
Help; |
if PageControl2.ActivePage = HelpTabsheet then |
WebBrowser2.SetFocus |
else if PageControl2.ActivePage = TabSheet3{Scrap} then |
SynEdit1.SetFocus; |
end; |
|
procedure TForm1.Button3Click(Sender: TObject); |
var |
val: string; |
lineno: integer; |
begin |
InputQuery('Go to', 'Line number:', val); |
if not TryStrToInt(val, lineno) then exit; |
GotoLineNo(lineno); |
end; |
|
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); |
begin |
SynEdit1.Lines.SaveToFile(GetScrapFile); |
177,6 → 299,8 |
|
PageControl2.ActivePageIndex := 0; // Scraps |
HelpTabsheet.TabVisible := false; |
|
SynEdit1.SetFocus; |
end; |
|
function TForm1.GetScrapFile: string; |
297,15 → 421,41 |
BrowseURL(WebBrowser2, url); |
end; |
|
procedure TForm1.Memo1KeyDown(Sender: TObject; var Key: Word; |
Shift: TShiftState); |
procedure TForm1.GotoLineNo(LineNo:integer); |
var |
line: string; |
i: integer; |
begin |
if (Key = VK_F9) or (Key = VK_F5) then |
Run(Sender) |
else if Key = VK_F1 then |
Help; |
SynEdit1.GotoLineAndCenter(LineNo); |
|
// Skip indent |
line := SynEdit1.Lines[SynEdit1.CaretY]; |
for i := 1 to Length(line) do |
begin |
if not (line[i] in [' ', #9]) then |
begin |
SynEdit1.CaretX := i-1; |
break; |
end; |
end; |
|
PageControl2.ActivePage := TabSheet3{Scrap}; |
if SynEdit1.CanFocus then SynEdit1.SetFocus; |
end; |
|
procedure TForm1.Memo2DblClick(Sender: TObject); |
var |
line: string; |
p, lineno: integer; |
begin |
line := memo2.Lines.Strings[Memo2.CaretPos.Y]; |
p := Pos(' on line ', line); |
if p = 0 then exit; |
line := copy(line, p+length(' on line '), 99); |
if not TryStrToInt(line, lineno) then exit; |
GotoLineNo(lineno); |
end; |
|
procedure TForm1.PageControl2Changing(Sender: TObject; |
var AllowChange: Boolean); |
begin |
317,4 → 467,37 |
AllowChange := true; |
end; |
|
function TForm1.MarkUpLineReference(cont: string): string; |
var |
p, a, b: integer; |
num: integer; |
insert_a, insert_b: string; |
begin |
// TODO: make it more specific to PHP error messages. "on line" is too broad. |
p := Pos(' on line ', cont); |
while p >= 1 do |
begin |
a := p+1; |
b := p+length(' on line '); |
num := 0; |
while cont[b] in ['0'..'9'] do |
begin |
num := num*10 + StrToInt(cont[b]); |
inc(b); |
end; |
|
insert_b := '</a>'; |
insert_a := '<a href="fastphp://gotoline/'+IntToStr(num)+'">'; |
|
insert(insert_b, cont, b); |
insert(insert_a, cont, a); |
|
p := b + Length(insert_a) + Length(insert_b); |
|
p := PosEx(' on line ', cont, p+1); |
end; |
|
result := cont; |
end; |
|
end. |