This commit is contained in:
Basile Burg 2014-06-25 14:04:00 +02:00
parent 9b96382a64
commit dde99ecd0c
9 changed files with 635 additions and 94 deletions

View File

@ -126,7 +126,7 @@
<PackageName Value="LCL"/> <PackageName Value="LCL"/>
</Item5> </Item5>
</RequiredPackages> </RequiredPackages>
<Units Count="14"> <Units Count="15">
<Unit0> <Unit0>
<Filename Value="coedit.lpr"/> <Filename Value="coedit.lpr"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
@ -218,6 +218,14 @@
<ResourceBaseClass Value="Form"/> <ResourceBaseClass Value="Form"/>
<UnitName Value="ce_staticexplorer"/> <UnitName Value="ce_staticexplorer"/>
</Unit13> </Unit13>
<Unit14>
<Filename Value="..\src\ce_search.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="CESearchWidget"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="ce_search"/>
</Unit14>
</Units> </Units>
</ProjectOptions> </ProjectOptions>
<CompilerOptions> <CompilerOptions>

View File

@ -9,7 +9,7 @@ uses
Interfaces, Forms, lazcontrols, runtimetypeinfocontrols, ce_widget, Interfaces, Forms, lazcontrols, runtimetypeinfocontrols, ce_widget,
ce_dmdwrap, ce_common, ce_synmemo, ce_main, ce_messages, ce_editor, ce_dmdwrap, ce_common, ce_synmemo, ce_main, ce_messages, ce_editor,
ce_projinspect, ce_projconf, jsonparser, ce_project, ce_projinspect, ce_projconf, jsonparser, ce_project,
ce_widgettypes, ce_staticexplorer; ce_widgettypes, ce_staticexplorer, ce_search;
{$R *.res} {$R *.res}

View File

@ -7,6 +7,33 @@ interface
uses uses
Classes, SysUtils, ActnList, dialogs, forms; Classes, SysUtils, ActnList, dialogs, forms;
type
(**
* MRU list for strings
*)
TMRUList = class(TStringList)
private
fMaxCount: Integer;
protected
procedure setMaxCount(aValue: Integer);
function checkItem(const S: string): boolean; virtual;
procedure Put(Index: Integer; const S: string); override;
published
property maxCount: Integer read fMaxCount write setMaxCount;
public
constructor Create;
procedure Insert(Index: Integer; const S: string); override;
end;
(**
* MRU list for filenames
*)
TMRUFileList = class(TMRUList)
protected
function checkItem(const S: string): boolean; override;
end;
(** (**
* Save a component with a readable aspect. * Save a component with a readable aspect.
*) *)
@ -45,9 +72,45 @@ uses
*) *)
function uniqueObjStr(const aObject: Tobject): string; function uniqueObjStr(const aObject: Tobject): string;
implementation implementation
constructor TMRUList.Create;
begin
fMaxCount := 10;
end;
procedure TMRUList.setMaxCount(aValue: Integer);
begin
if aValue < 0 then aValue := 0;
if fMaxCount = aValue then exit;
while Count > fMaxCount do delete(Count-1);
end;
function TMRUList.checkItem(const S: string): boolean;
begin
exit( indexOf(S) = -1 );
end;
procedure TMRUList.Put(Index: Integer; const S: string);
begin
if not (checkItem(S)) then exit;
inherited;
while Count > fMaxCount do delete(Count-1);
end;
procedure TMRUList.Insert(Index: Integer; const S: string);
begin
if not (checkItem(S)) then exit;
inherited;
while Count > fMaxCount do delete(Count-1);
end;
function TMRUFileList.checkItem(const S: string): boolean;
begin
exit( inherited checkItem(S) and fileExists(S));
end;
procedure saveCompToTxtFile(const aComp: TComponent; const aFilename: string); procedure saveCompToTxtFile(const aComp: TComponent; const aFilename: string);
var var
str1, str2: TMemoryStream; str1, str2: TMemoryStream;
@ -102,71 +165,34 @@ begin
end; end;
function patchPlateformPath(const aPath: string): string; function patchPlateformPath(const aPath: string): string;
function patchProc(const src: string; const invalid: char): string;
var var
i: Integer; i: Integer;
begin
result := src;
i := pos(invalid, result);
if i <> 0 then
begin
repeat
result[i] := directorySeparator;
i := pos(invalid,result);
until
i = 0;
end;
end;
begin begin
result := aPath; result := aPath;
{$IFDEF MSWINDOWS} {$IFDEF MSWINDOWS}
i := pos('/',result); result := patchProc(result,'/');
if i <> 0 then result := patchProc(result,':');
begin
repeat
result[i] := directorySeparator;
i := pos('/',result);
until
i = 0;
end;
i := pos(':',result);
if i <> 0 then
begin
repeat
result[i] := directorySeparator;
i := pos(':',result);
until
i = 0;
end;
{$ENDIF} {$ENDIF}
{$IFDEF LINUX} {$IFDEF LINUX}
i := pos('\',result); result := patchProc(result,'\');
if i <> 0 then result := patchProc(result,':');
begin
repeat
result[i] := directorySeparator;
i := pos('\',result);
until
i = 0;
end;
i := pos(':',result);
if i <> 0 then
begin
repeat
result[i] := directorySeparator;
i := pos(':',result);
until
i = 0;
end;
{$ENDIF} {$ENDIF}
{$IFDEF MACOS} {$IFDEF MACOS}
i := pos('\',result); result := patchProc(result,'\');
if i <> 0 then result := patchProc(result,'/');
begin
repeat
result[i] := directorySeparator;
i := pos('\',result);
until
i = 0;
end;
i := pos('/',result);
if i <> 0 then
begin
repeat
result[i] := directorySeparator;
i := pos('/',result);
until
i = 0;
end;
{$ENDIF} {$ENDIF}
end; end;
@ -249,4 +275,9 @@ begin
{$HINTS ON}{$WARNINGS ON} {$HINTS ON}{$WARNINGS ON}
end; end;
operator =(lhs,rhs: TPoint): boolean;
begin
exit( (lhs.x = rhs.x) and (lhs.y = rhs.y) );
end;
end. end.

View File

@ -44,11 +44,12 @@ type
values: array of string; values: array of string;
end; end;
// TODO: rather gperf ?
TD2Dictionary = object TD2Dictionary = object
private private
fLongest: NativeInt; fLongest: NativeInt;
fEntries: array[0..1023] of TD2DictionaryEntry; fEntries: array[0..255] of TD2DictionaryEntry;
function toHash(const aValue: string): word; function toHash(const aValue: string): Byte;
procedure addEntry(const aValue: string); procedure addEntry(const aValue: string);
public public
constructor create; constructor create;
@ -227,20 +228,14 @@ begin
end; end;
{$IFDEF DEBUG}{$R-}{$ENDIF} {$IFDEF DEBUG}{$R-}{$ENDIF}
function TD2Dictionary.toHash(const aValue: string): word; function TD2Dictionary.toHash(const aValue: string): Byte;
var var
i, len: Integer; i, len: Integer;
prev: word;
begin begin
result := 0; result := 0;
prev := 0;
len := length(aValue); len := length(aValue);
for i := 1 to len do for i := 1 to len do
begin result += (Byte(aValue[i]) shl i) xor 63;
result += ((Byte(aValue[i]) + 64) shl i) xor prev;
prev := Byte(aValue[i]);
end;
result := result and 1023;
end; end;
{$IFDEF DEBUG}{$R+}{$ENDIF} {$IFDEF DEBUG}{$R+}{$ENDIF}
@ -458,6 +453,8 @@ TODO:
- comments: correct nested comments handling. - comments: correct nested comments handling.
} }
procedure TSynD2Syn.next; procedure TSynD2Syn.next;
label
_postString1;
begin begin
fTokStart := fTokStop; fTokStart := fTokStop;
@ -613,8 +610,8 @@ begin
begin begin
if not (readNext = '"') then if not (readNext = '"') then
begin begin
fTokKind := tkIdent; Dec(fTokStop);
exit; // warning: a goto is avoided but any other r/x is not detectable since it's truncated as tkIdent goto _postString1;
end; end;
end; end;
// go to end of string/eol // go to end of string/eol
@ -631,6 +628,7 @@ begin
exit; exit;
end; end;
end; end;
_postString1:
// string 2 // string 2
if fRange = rkString2 then if fRange = rkString2 then

View File

@ -7,9 +7,9 @@ interface
uses uses
Classes, SysUtils, FileUtil, SynEditKeyCmds, SynHighlighterLFM, Forms, Classes, SysUtils, FileUtil, SynEditKeyCmds, SynHighlighterLFM, Forms,
AnchorDocking, AnchorDockStorage, AnchorDockOptionsDlg, Controls, Graphics, AnchorDocking, AnchorDockStorage, AnchorDockOptionsDlg, Controls, Graphics,
Dialogs, Menus, ActnList, ExtCtrls, ComCtrls, process, Dialogs, Menus, ActnList, ExtCtrls, process,
ce_common, ce_dmdwrap, ce_project, ce_synmemo, ce_widget, ce_messages, ce_common, ce_dmdwrap, ce_project, ce_synmemo, ce_widget, ce_messages,
ce_editor, ce_projinspect, ce_projconf, ce_staticexplorer; ce_editor, ce_projinspect, ce_projconf, ce_staticexplorer, ce_search;
type type
@ -142,6 +142,7 @@ type
fProjWidg: TCEProjectInspectWidget; fProjWidg: TCEProjectInspectWidget;
fPrjCfWidg: TCEProjectConfigurationWidget; fPrjCfWidg: TCEProjectConfigurationWidget;
fStExpWidg: TCEStaticExplorerWidget; fStExpWidg: TCEStaticExplorerWidget;
fFindWidg: TCESearchWidget;
// widget interfaces subroutines // widget interfaces subroutines
procedure checkWidgetActions(const aWidget: TCEWidget); procedure checkWidgetActions(const aWidget: TCEWidget);
@ -207,12 +208,14 @@ begin
fProjWidg := TCEProjectInspectWidget.create(nil); fProjWidg := TCEProjectInspectWidget.create(nil);
fPrjCfWidg:= TCEProjectConfigurationWidget.create(nil); fPrjCfWidg:= TCEProjectConfigurationWidget.create(nil);
fStExpWidg:= TCEStaticExplorerWidget.create(nil); fStExpWidg:= TCEStaticExplorerWidget.create(nil);
fFindWidg := TCESearchWidget.create(nil);
fWidgList.addWidget(@fMesgWidg); fWidgList.addWidget(@fMesgWidg);
fWidgList.addWidget(@fEditWidg); fWidgList.addWidget(@fEditWidg);
fWidgList.addWidget(@fProjWidg); fWidgList.addWidget(@fProjWidg);
fWidgList.addWidget(@fPrjCfWidg); fWidgList.addWidget(@fPrjCfWidg);
fWidgList.addWidget(@fStExpWidg); fWidgList.addWidget(@fStExpWidg);
fWidgList.addWidget(@fFindWidg);
for widg in fWidgList do widg.Show; for widg in fWidgList do widg.Show;
@ -252,6 +255,7 @@ begin
fProjWidg.Free; fProjWidg.Free;
fPrjCfWidg.Free; fPrjCfWidg.Free;
fStExpWidg.Free; fStExpWidg.Free;
fFindWidg.Free;
fProject.Free; fProject.Free;
// //
inherited; inherited;
@ -698,23 +702,28 @@ begin
{$IFDEF RELEASE} {$IFDEF RELEASE}
dmdProc.ShowWindow := swoHIDE; dmdProc.ShowWindow := swoHIDE;
{$ENDIF} {$ENDIF}
dmdproc.Options:= [poWaitOnExit, poStdErrToOutput, poUsePipes]; dmdproc.Options:= [poStdErrToOutput, poUsePipes];
dmdproc.Executable:= 'dmd'; dmdproc.Executable:= 'dmd';
dmdproc.Parameters.Add(fname + '.d'); dmdproc.Parameters.Add(fname + '.d');
try try
dmdproc.Execute; dmdproc.Execute;
while dmdproc.Running do if dmdproc.ExitStatus <> 0 then break;
ProcessOutputToMsg(dmdproc); ProcessOutputToMsg(dmdproc);
finally finally
DeleteFile(fname + '.d'); DeleteFile(fname + '.d');
end; end;
{$IFDEF MSWINDOWS}
if (dmdProc.ExitStatus = 0) or (dmdProc.ExitStatus = 259) then
{$ELSE}
if dmdProc.ExitStatus = 0 then if dmdProc.ExitStatus = 0 then
{$ENDIF}
begin begin
fMesgWidg.addCeInf( fEditWidg.editor[edIndex].fileName fMesgWidg.addCeInf( fEditWidg.editor[edIndex].fileName
+ ' successfully compiled' ); + ' successfully compiled' );
runproc.Options:= [poWaitOnExit, poStderrToOutPut, poUsePipes]; runproc.Options:= [poStderrToOutPut, poUsePipes];
{$IFDEF MSWINDOWS} {$IFDEF MSWINDOWS}
runproc.Executable := fname + '.exe'; runproc.Executable := fname + '.exe';
runproc.Parameters.Text := runArgs; runproc.Parameters.Text := runArgs;
@ -722,10 +731,8 @@ begin
runproc.Executable := fname; runproc.Executable := fname;
{$ENDIF} {$ENDIF}
runproc.Execute; runproc.Execute;
repeat while runproc.Running do if runproc.ExitStatus <> 0 then break;
ProcessOutputToMsg(runproc); ProcessOutputToMsg(runproc);
until
not runproc.Active;
{$IFDEF MSWINDOWS} {$IFDEF MSWINDOWS}
DeleteFile(fname + '.exe'); DeleteFile(fname + '.exe');
DeleteFile(fname + '.obj'); DeleteFile(fname + '.obj');
@ -749,12 +756,6 @@ procedure TCEMainForm.compileProject(const aProject: TCEProject);
var var
dmdproc: TProcess; dmdproc: TProcess;
olddir, prjpath: string; olddir, prjpath: string;
const
// option -v causes a hang if poWaitOnExit is included
procopts: array[boolean] of TProcessOptions = (
[poWaitOnExit, poStdErrToOutput, poUsePipes],
[poStdErrToOutput, poUsePipes]
);
begin begin
if aProject.Sources.Count = 0 then if aProject.Sources.Count = 0 then
@ -776,16 +777,20 @@ begin
{$IFDEF RELEASE} {$IFDEF RELEASE}
dmdProc.ShowWindow := swoHIDE; dmdProc.ShowWindow := swoHIDE;
{$ENDIF} {$ENDIF}
dmdproc.Options := dmdproc.Options := [poStdErrToOutput, poUsePipes];
procopts[aProject.currentConfiguration.messagesOptions.verbose];
dmdproc.Executable := 'dmd'; dmdproc.Executable := 'dmd';
aProject.getOpts(dmdproc.Parameters); aProject.getOpts(dmdproc.Parameters);
try try
dmdproc.Execute; dmdproc.Execute;
while dmdproc.Running do if dmdproc.ExitStatus <> 0 then break;
ProcessOutputToMsg(dmdproc); ProcessOutputToMsg(dmdproc);
finally finally
{$IFDEF MSWINDOWS} // STILL_ACTIVE ambiguity
if (dmdProc.ExitStatus = 0) or (dmdProc.ExitStatus = 259) then
{$ELSE}
if dmdProc.ExitStatus = 0 then if dmdProc.ExitStatus = 0 then
{$ENDIF}
fMesgWidg.addCeInf( aProject.fileName fMesgWidg.addCeInf( aProject.fileName
+ ' successfully compiled' ) + ' successfully compiled' )
else else
@ -833,6 +838,7 @@ begin
runproc.Executable := procname; runproc.Executable := procname;
runproc.Parameters.Text := runArgs; runproc.Parameters.Text := runArgs;
runproc.Execute; runproc.Execute;
while runproc.Running do if runproc.ExitStatus <> 0 then break;
finally finally
runproc.Free; runproc.Free;
@ -856,8 +862,8 @@ begin
if fEditWidg.editorIndex < 0 then exit; if fEditWidg.editorIndex < 0 then exit;
// //
runargs := ''; runargs := '';
if InputQuery('Execution arguments', 'enter switches and arguments', if InputQuery('Execution arguments', '', runargs) then
runargs) then compileAndRunFile(fEditWidg.editorIndex, runargs); compileAndRunFile(fEditWidg.editorIndex, runargs);
end; end;
procedure TCEMainForm.actProjCompileExecute(Sender: TObject); procedure TCEMainForm.actProjCompileExecute(Sender: TObject);
@ -878,8 +884,8 @@ begin
compileProject(fProject); compileProject(fProject);
// //
runargs := ''; runargs := '';
if InputQuery('Execution arguments', 'enter switches and arguments', if InputQuery('Execution arguments', '', runargs) then
runargs) then runProject(fProject, runargs); runProject(fProject, runargs);
end; end;
procedure TCEMainForm.actProjRunExecute(Sender: TObject); procedure TCEMainForm.actProjRunExecute(Sender: TObject);
@ -892,8 +898,8 @@ var
runargs: string; runargs: string;
begin begin
runargs := ''; runargs := '';
if InputQuery('Execution arguments', 'enter switches and arguments', if InputQuery('Execution arguments', '', runargs) then
runargs) then runProject(fProject, runargs); runProject(fProject, runargs);
end; end;
{$ENDREGION} {$ENDREGION}

305
src/ce_search.lfm Normal file
View File

@ -0,0 +1,305 @@
inherited CESearchWidget: TCESearchWidget
Left = 1338
Height = 276
Top = 697
Width = 405
Caption = 'Search & replace'
ClientHeight = 276
ClientWidth = 405
inherited Back: TPanel
Height = 276
Width = 405
ClientHeight = 276
ClientWidth = 405
inherited Content: TPanel
Height = 276
Width = 405
ClientHeight = 276
ClientWidth = 405
object cbToFind: TComboBox[0]
Left = 4
Height = 23
Top = 4
Width = 397
Align = alTop
BorderSpacing.Around = 4
ItemHeight = 15
OnChange = cbToFindChange
TabOrder = 0
end
object cbReplaceWth: TComboBox[1]
Left = 4
Height = 23
Top = 31
Width = 397
Align = alTop
BorderSpacing.Around = 4
ItemHeight = 15
OnChange = cbReplaceWthChange
TabOrder = 1
end
object btnFind: TBitBtn[2]
Left = 4
Height = 24
Top = 192
Width = 397
Align = alBottom
BorderSpacing.Around = 4
Caption = 'btnFind'
Glyph.Data = {
36040000424D3604000000000000360000002800000010000000100000000100
2000000000000004000064000000640000000000000000000000FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF003E39
34FF393430FF332F2BFF2C2925FF272421FF201D1BFF1716141A110F0EDB0B0A
09FF070706FF040403FF000000FF000000FFFFFFFF00FFFFFF00FFFFFF004641
3BFF857A70FFC3B8AEFF7C7268FF7F756BFF36322DFF1E1C190F282522D49589
7DFFBAAEA2FF7C7268FF7F756BFF010101FFFFFFFF00FFFFFF00FFFFFF004D47
41FF83786FFFCCC3BAFF786F65FF7B7167FF2F2B28F9272421011D1B18EE9589
7DFFC2B8ADFF786F65FF7C7268FF060505FFFFFFFF00FFFFFF00FFFFFF00534C
46FC83786FFFCCC3BAFF797066FF71685FFF37332ED5FFFFFF00252220D5857A
70FFC2B8ADFF786F65FF7B7167FF0A0908FCFFFFFF00FFFFFF00FFFFFF005A52
4CC39F9286FFCCC3BAFFC0B4AAFFA6988BFF3E3934A8FFFFFF002C2925A89084
79FFC2B8ADFFC0B4AAFFA89B8EFF110F0EC3FFFFFF00FFFFFF00797066055C55
4EF9423D38FF58514AFF3D3833FF332F2BFF23201DE5171614301E1C19B51A18
16FF252220FF191715FF0F0E0DFF010101EE00000002FFFFFF009F9286059D91
85FFB1A396FF7F756BFF7C7268FF776D64FF6C635BFF2E2A26FF564F48FF8076
6CFF7C7268FF776D64FF70675EFF000000FE00000005FFFFFF00AB9D9004AFA1
94E1BAAEA2FF82776DFF82776DFFAA917BFFBAA794FFB7A48EFAB09781FF9F8D
7DFF836D5BFF716357FF95897DFF040403E000000003FFFFFF00B9ACA008877D
72489B8E82FF9D9185FF867B71FF564F48FF504A44FF80766CFF6E665DFF826C
58FFA6917DFF948474FF564F48FF0C0B0B7A07070601FFFFFF00FFFFFF00FFFF
FF00746B62FFA4978AFF95897DFF9F9286FF3E3934FFFFFFFF004C4640FF7E74
6AFF857A70FF3E3934FF453F3AA72522200C15131102FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF008E8378E2C3B8AEFF655D55FFFFFFFF007C7268FFA89B
8EFF9C8F83E4FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF009C8F83E2BCB0A4FF9D9185FFFFFFFF00AEA093FF9D91
85FF655D55DAFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00
}
TabOrder = 2
end
object btnReplace: TBitBtn[3]
Left = 4
Height = 24
Top = 220
Width = 397
Align = alBottom
BorderSpacing.Around = 4
Caption = 'btnReplace'
Glyph.Data = {
36040000424D3604000000000000360000002800000010000000100000000100
2000000000000004000064000000640000000000000000000000FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00DB772511DB742199D9701FFFD96E1CFFD86C
1BCCD8691A77D8671A77D6651AEED6621AEED4621999D4601911FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00DD7B2A66E18F4CFFEBB183FFE3914EFFDA73
23FFDA7428FFE08848FFE7A270FFE3935CFFDB7533FFD6621A44FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00DF823044E28D44FFECB588FFDC7A2CFFDB74
2311DB721F22D9701EDDE6A471FFDC7A34FFD8671A44FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00DF8231CCE69959FFE49755FFDB7B
2877FFFFFF00DB742177E18C4CFFE18B49FFD86C1B77FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00E1873711DF8435BBE59856FFE595
53FFDD7B2ACCDB7727AAE69D63FFE8A46DFFD9701ECCFFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00419149E539853FFF317A37FF7F7A32FF9579
2EFCDF8230BBDF7E2CFFE39250FFEBB386FFDC7728FFDB721F11FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00419149F9BCB272FFE8A05EFFBD82
37FEDF853511FFFFFF00DF7E2E99E69E61FFE1924EFFDB772566FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF0051A75A8A71B67AFFB6C590FFE69B55FFE8A4
65FFE2893988FFFFFF00DF843588E69F61FFE59858FFDD7B2A77DB721F99D96E
1CDDD86C1BDDD8691AFF919749F080C588FFB0DCB6FF75B87CFF8E9146FAE496
4AFFE8A361FFE28B3CFFE69E5CFFE9A96FFFE49956FFDF823066DB772755E087
42FFDB721F88FFFFFF0083AA59D988CB90FF83C68BFF51A75AA8499C52035991
48E5E2924377E29040BBE28D3CBBE28B3AAAE1873966FFFFFF00DF7E2E11DE7E
2FFFDB7727AAFFFFFF00DB721F1190A352FF85A251F958B16203FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00DF82
31BBDF7E2EFFFFFFFF00FFFFFF00DB7423CCDE833AFFD96E1C44FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00E189
3977E59B59FFDF8231BBDF7E2E88E39250FFDD7F32FFDB742322FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00E28E
4033E5944CFFE18939BBDF8535AADF8231BBDF7E2E55FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00E29041FFE28E40DDFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00E697
4766E69547FFE69A4EFFE2904122FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00
}
TabOrder = 3
end
object grpOpts: TGroupBox[4]
Left = 4
Height = 130
Top = 58
Width = 397
Align = alClient
BorderSpacing.Around = 4
Caption = 'Options'
ClientHeight = 112
ClientWidth = 393
TabOrder = 4
object chkWWord: TCheckBox
Left = 8
Height = 19
Top = 0
Width = 82
Caption = 'whole word'
TabOrder = 0
end
object chkBack: TCheckBox
Left = 8
Height = 19
Top = 24
Width = 71
Caption = 'backward'
TabOrder = 1
end
object chkFromCur: TCheckBox
Left = 8
Height = 19
Top = 48
Width = 82
Caption = 'from cursor'
Checked = True
State = cbChecked
TabOrder = 2
end
object chkCaseSens: TCheckBox
Left = 128
Height = 19
Top = 0
Width = 91
Caption = 'case sensitive'
TabOrder = 3
end
object chkPrompt: TCheckBox
Left = 128
Height = 19
Top = 24
Width = 60
Caption = 'Prompt'
TabOrder = 4
end
end
object btnReplaceAll: TBitBtn[5]
Left = 4
Height = 24
Top = 248
Width = 397
Align = alBottom
BorderSpacing.Around = 4
Caption = 'btnReplaceAll'
Glyph.Data = {
36040000424D3604000000000000360000002800000010000000100000000100
2000000000000004000064000000640000000000000000000000FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00DB772511DB742199D9701FFFD96E1CFFD86C
1BCCD8691A77D8671A77D6651AEED6621AEED4621999D4601911FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00DD7B2A66E18F4CFFEBB183FFE3914EFFDA73
23FFDA7428FFE08848FFE7A270FFE3935CFFDB7533FFD6621A44FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00DF823044E28D44FFECB588FFDC7A2CFFDB74
2311DB721F22D9701EDDE6A471FFDC7A34FFD8671A44FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00DF8231CCE69959FFE49755FFDB7B
2877FFFFFF00DB742177E18C4CFFE18B49FFD86C1B77FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00E1873711DF8435BBE59856FFE595
53FFDD7B2ACCDB7727AAE69D63FFE8A46DFFD9701ECCFFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00419149E539853FFF317A37FF7F7A32FF9579
2EFCDF8230BBDF7E2CFFE39250FFEBB386FFDC7728FFDB721F11FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00419149F9BCB272FFE8A05EFFBD82
37FEDF853511FFFFFF00DF7E2E99E69E61FFE1924EFFDB772566FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF0051A75A8A71B67AFFB6C590FFE69B55FFE8A4
65FFE2893988FFFFFF00DF843588E69F61FFE59858FFDD7B2A77DB721F99D96E
1CDDD86C1BDDD8691AFF919749F080C588FFB0DCB6FF75B87CFF8E9146FAE496
4AFFE8A361FFE28B3CFFE69E5CFFE9A96FFFE49956FFDF823066DB772755E087
42FFDB721F88FFFFFF0083AA59D988CB90FF83C68BFF51A75AA8499C52035991
48E5E2924377E29040BBE28D3CBBE28B3AAAE1873966FFFFFF00DF7E2E11DE7E
2FFFDB7727AAFFFFFF00DB721F1190A352FF85A251F958B16203FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00DF82
31BBDF7E2EFFFFFFFF00FFFFFF00DB7423CCDE833AFFD96E1C44FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00E189
3977E59B59FFDF8231BBDF7E2E88E39250FFDD7F32FFDB742322FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00E28E
4033E5944CFFE18939BBDF8535AADF8231BBDF7E2E55FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00E29041FFE28E40DDFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00E697
4766E69547FFE69A4EFFE2904122FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00
}
TabOrder = 5
end
end
end
object imgList: TImageList[2]
left = 32
Bitmap = {
4C690200000010000000100000007B7977007B7977007B7977FF73716FFF6D6B
69FF696665FF625F5EFF615E5D007E7C7A007B7977FF73716FFF6D6B69FF6966
65FF63605FFF64616000646160007B7977007B7977007A7976FF908D8CFF908E
8CFF656461FF615E5DFF615E5D007D7B7900797775FF8E8B8AFF918F8DFF6866
64FF63605FFF64616000646160007B7977007B79770000000033787574FFCBCA
C7FF9B9A99FF625E5DFF625F5E007D7A7900787574FFCAC8C6FF989796FF605D
5CFF0000003364616000646160007B797700797875AE716E6DFF696665FF6460
5FFF625E5DFF545251AA7B7A7700656361006A6967AA6F6C6BFF696665FF6764
63FF656261FF63605FAE646160007C797800787574FFBDBBB9FFCECCCBFFA5A3
A2FF7E7C7BFF5E5B5AFF7B7977FF646260FF797675FFBCBBB8FFCECCCBFFA6A4
A3FF807E7DFF605D5CFF63605F007B787700777473FFB9B7B5FFC9C7C6FFA2A0
9FFF7D7B7AFF5C5858FF777472FF615F5DFF777473FFB9B8B5FFC9C7C6FFA2A0
9FFF7E7C7BFF605D5CFF63605F007B797700777473FFBCBAB8FFCDCBCAFFA5A3
A2FF7E7C7BFF595655FFD6D5D3FF8C8C89FF767372FFBCBAB7FFCCCAC9FFA4A2
A1FF7E7C7BFF5F5C5BFF625F5E007A7876FF6F6D6BFF666261FF605D5CFF5E5C
5AFF5E5A5AFF4946469BD3D2D0FF8A8987FF62615F9B6C6A68FF646160FF625F
5EFF615F5DFF615E5DFF615E5DA8777472FFDEDDDDFFEBEBE9FFDBDAD9FFCAC9
C8FFBBBAB9FF575453FFD6D5D3FF8C8B89FF757371FFDEDDDCFFEBEBE9FFDBDA
D9FFCAC9C8FFBCBCBBFF5E5B5AFF767472FFB3B0AEFFCAC9C7FFB0ADADFF9190
8EFF757472FF5B5857FF767472FF615F5DFF767472FFB3B1AFFFCAC9C7FFB0AD
ADFF91908EFF757573FF5F5C5BFF767472FFB3B1AFFFCAC9C7FFB1AEAEFF9392
90FF777674FF5E5A59FF7A7876FF646260FF777573FFB3B1AFFFCAC9C7FFB1AE
AEFF939290FF777674FF605D5CFF767472FFB3B1AFFFCAC9C7FFB0AEADFF9190
8EFF757472FF5E5A59FF0000003300000033777573FFB3B1AFFFCAC9C7FFB0AE
ADFF91908EFF757572FF5F5C5BFF777573FFCFCFCFFFD9D7D6FFD0CFCEFFC8C8
C7FFC3C1C1FF5E5A59FF5F5C5B007E7C7A00777573FFD0CFCFFFD9D7D6FFD0CF
CEFFC8C8C7FFC3C1C1FF5E5B5AFF7A7876FF817E7DFF9C9996FF898583FF716F
6CFF595756FF605D5CFF605D5C007F7D7B007A7876FF817E7DFF9C9996FF8985
83FF716F6CFF595756FF615E5DFF716F6DC0767472FF706D6CFF6D6A69FF6967
65FF666362FF5A5756C0605D5C007E7C7A00716F6DC0767472FF706D6CFF6D6A
69FF696765FF666362FF5A5756C0000000230000003300000033000000330000
0033000000330000002300000000000000000000002300000033000000330000
0033000000330000003300000023FFFFFF00E6974766E69547FFE69A4EFFE290
4122FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00E29041FFE28E40DDFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00E28E4033E5944CFFE18939BBDF85
35AADF8231BBDF7E2E55FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00E1893977E59B59FFDF8231BBDF7E
2E88E39250FFDD7F32FFDB742322FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00DF8231BBDF7E2EFFFFFFFF00FFFF
FF00DB7423CCDE833AFFD96E1C44FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00DF7E2E11DE7E2FFFDB7727AAFFFFFF00DB72
1F1190A352FF85A251F958B16203FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00DB772755E08742FFDB721F88FFFFFF0083AA
59D988CB90FF83C68BFF51A75AA8499C5203599148E5E2924377E29040BBE28D
3CBBE28B3AAAE1873966FFFFFF00DB721F99D96E1CDDD86C1BDDD8691AFF9197
49F080C588FFB0DCB6FF75B87CFF8E9146FAE4964AFFE8A361FFE28B3CFFE69E
5CFFE9A96FFFE49956FFDF823066FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF0051A75A8A71B67AFFB6C590FFE69B55FFE8A465FFE2893988FFFFFF00DF84
3588E69F61FFE59858FFDD7B2A77FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00419149F9BCB272FFE8A05EFFBD8237FEDF853511FFFFFF00DF7E
2E99E69E61FFE1924EFFDB772566FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00419149E539853FFF317A37FF7F7A32FF95792EFCDF8230BBDF7E2CFFE392
50FFEBB386FFDC7728FFDB721F11FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00E1873711DF8435BBE59856FFE59553FFDD7B2ACCDB7727AAE69D
63FFE8A46DFFD9701ECCFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00DF8231CCE69959FFE49755FFDB7B2877FFFFFF00DB742177E18C
4CFFE18B49FFD86C1B77FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00DF823044E28D44FFECB588FFDC7A2CFFDB742311DB721F22D9701EDDE6A4
71FFDC7A34FFD8671A44FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00DD7B2A66E18F4CFFEBB183FFE3914EFFDA7323FFDA7428FFE08848FFE7A2
70FFE3935CFFDB7533FFD6621A44FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00DB772511DB742199D9701FFFD96E1CFFD86C1BCCD8691A77D8671A77D665
1AEED6621AEED4621999D4601911
}
end
end

186
src/ce_search.pas Normal file
View File

@ -0,0 +1,186 @@
unit ce_search;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
Menus, StdCtrls, actnList, Buttons, SynEdit, SynEditSearch, SynEditTypes, ce_common,
ce_widget, ce_synmemo;
type
{ TCESearchWidget }
TCESearchWidget = class(TCEWidget)
btnFind: TBitBtn;
btnReplace: TBitBtn;
btnReplaceAll: TBitBtn;
cbToFind: TComboBox;
cbReplaceWth: TComboBox;
chkPrompt: TCheckBox;
chkWWord: TCheckBox;
chkBack: TCheckBox;
chkFromCur: TCheckBox;
chkCaseSens: TCheckBox;
grpOpts: TGroupBox;
imgList: TImageList;
procedure cbReplaceWthChange(Sender: TObject);
procedure cbToFindChange(Sender: TObject);
private
fEditor: TCESynMemo;
fToFind: string;
fReplaceWth: string;
fActFindNext, fActReplaceNext: TAction;
fActReplaceAll: TAction;
fSearchMru, fReplaceMru: TMruList;
function getOptions: TSynSearchOptions;
procedure actFindNextExecute(sender: TObject);
procedure actReplaceAllExecute(sender: TObject);
procedure actReplaceNextExecute(sender: TObject);
procedure replaceEvent(Sender: TObject; const ASearch, AReplace:
string; Line, Column: integer; var ReplaceAction: TSynReplaceAction);
protected
procedure UpdateByEvent; override;
public
constructor Create(aOwner: TComponent); override;
destructor Destroy; override;
//
procedure docFocused(const aDoc: TCESynMemo); override;
procedure docClose(const aDoc: TCESynMemo); override;
end;
implementation
{$R *.lfm}
constructor TCESearchWidget.Create(aOwner: TComponent);
begin
inherited;
fID := 'ID_FIND';
//
fSearchMru := TMruList.Create;
fReplaceMru:= TMruList.Create;
//
fActFindNext := TAction.Create(self);
fActFindNext.Caption := 'Find';
fActFindNext.OnExecute := @actFindNextExecute;
btnFind.Action := fActFindNext;
fActReplaceNext := TAction.Create(self);
fActReplaceNext.Caption := 'Replace';
fActReplaceNext.OnExecute := @actReplaceNextExecute;
btnReplace.Action := fActReplaceNext;
fActReplaceAll := TAction.Create(self);
fActReplaceAll.Caption := 'Replace all';
fActReplaceAll.OnExecute := @actReplaceAllExecute;
btnReplaceAll.Action := fActReplaceAll;
end;
destructor TCESearchWidget.Destroy;
begin
fSearchMru.Free;
fReplaceMru.Free;
inherited;
end;
procedure TCESearchWidget.docFocused(const aDoc: TCESynMemo);
begin
fEditor := aDoc;
UpdateByEvent;
end;
procedure TCESearchWidget.docClose(const aDoc: TCESynMemo);
begin
if fEditor = aDoc then fEditor := nil;
UpdateByEvent;
end;
procedure TCESearchWidget.cbToFindChange(Sender: TObject);
begin
if Updating then exit;
fToFind := cbToFind.Text;
end;
procedure TCESearchWidget.cbReplaceWthChange(Sender: TObject);
begin
if Updating then exit;
fReplaceWth := cbReplaceWth.Text;
end;
function TCESearchWidget.getOptions: TSynSearchOptions;
begin
result := [];
if chkWWord.Checked then result += [ssoWholeWord];
if chkBack.Checked then result += [ssoBackwards];
if chkCaseSens.Checked then result += [ssoMatchCase];
if chkPrompt.Checked then result += [ssoPrompt];
end;
procedure TCESearchWidget.actFindNextExecute(sender: TObject);
begin
if fEditor = nil then exit;
//
fSearchMru.Insert(0,fToFind);
if not chkFromCur.Checked then if chkBack.Checked then
fEditor.CaretXY := Point(high(Integer), high(Integer)) else
fEditor.CaretXY := Point(0,0);
fEditor.SearchReplace(fToFind, '', getOptions);
UpdateByEvent;
end;
procedure TCESearchWidget.actReplaceNextExecute(sender: TObject);
begin
if fEditor = nil then exit;
//
fSearchMru.Insert(0, fToFind);
fReplaceMru.Insert(0, fReplaceWth);
if chkPrompt.Checked then
fEditor.OnReplaceText := @replaceEvent;
if not chkFromCur.Checked then if chkBack.Checked then
fEditor.CaretXY := Point(high(Integer), high(Integer)) else
fEditor.CaretXY := Point(0,0);
fEditor.SearchReplace(fToFind, fReplaceWth, getOptions + [ssoReplace]);
fEditor.OnReplaceText := nil;
UpdateByEvent;
end;
procedure TCESearchWidget.actReplaceAllExecute(sender: TObject);
var
opts: TSynSearchOptions;
begin
if fEditor = nil then exit;
opts := getOptions + [ssoReplace];
opts -= [ssoBackwards];
//
fSearchMru.Insert(0, fToFind);
fReplaceMru.Insert(0, fReplaceWth);
if chkPrompt.Checked then fEditor.OnReplaceText := @replaceEvent;
fEditor.CaretXY := Point(0,0);
while(true) do
begin
if fEditor.SearchReplace(fToFind, fReplaceWth, opts) = 0
then break;
end;
fEditor.OnReplaceText := nil;
UpdateByEvent;
end;
procedure TCESearchWidget.replaceEvent(Sender: TObject; const ASearch, AReplace:
string; Line, Column: integer; var ReplaceAction: TSynReplaceAction);
begin
ReplaceAction := raSkip;
if dlgOkCancel('Replace this match ?') = mrOK then
ReplaceAction := raReplace;
end;
procedure TCESearchWidget.UpdateByEvent;
begin
fActFindNext.Enabled := fEditor <> nil;
fActReplaceNext.Enabled := fEditor <> nil;
//
cbToFind.Items.Assign(fSearchMru);
cbReplaceWth.Items.Assign(fReplaceMru);
end;
end.

View File

@ -34,6 +34,7 @@ inherited CEStaticExplorerWidget: TCEStaticExplorerWidget
SelectionColor = clActiveBorder SelectionColor = clActiveBorder
TabOrder = 0 TabOrder = 0
OnDeletion = TreeDeletion OnDeletion = TreeDeletion
OnKeyPress = TreeKeyPress
Options = [tvoAutoItemHeight, tvoKeepCollapsedNodes, tvoReadOnly, tvoRowSelect, tvoShowButtons, tvoShowLines, tvoShowRoot, tvoToolTips, tvoThemedDraw] Options = [tvoAutoItemHeight, tvoKeepCollapsedNodes, tvoReadOnly, tvoRowSelect, tvoShowButtons, tvoShowLines, tvoShowRoot, tvoToolTips, tvoThemedDraw]
Items.Data = { Items.Data = {
F9FFFFFF020009000000000000000000000000000000FFFFFFFF000000000000 F9FFFFFF020009000000000000000000000000000000FFFFFFFF000000000000

View File

@ -18,6 +18,7 @@ type
Tree: TTreeView; Tree: TTreeView;
TreeFilterEdit1: TTreeFilterEdit; TreeFilterEdit1: TTreeFilterEdit;
procedure TreeDeletion(Sender: TObject; Node: TTreeNode); procedure TreeDeletion(Sender: TObject; Node: TTreeNode);
procedure TreeKeyPress(Sender: TObject; var Key: char);
private private
fActRefresh: TAction; fActRefresh: TAction;
fActAutoRefresh: TAction; fActAutoRefresh: TAction;
@ -168,6 +169,11 @@ begin
FreeMem(node.Data) FreeMem(node.Data)
end; end;
procedure TCEStaticExplorerWidget.TreeKeyPress(Sender: TObject; var Key: char);
begin
if Key = #13 then TreeDblClick(nil);
end;
procedure TCEStaticExplorerWidget.TreeDblClick(Sender: TObject); procedure TCEStaticExplorerWidget.TreeDblClick(Sender: TObject);
var var
line: Int64; line: Int64;
@ -178,7 +184,7 @@ begin
// //
line := PInt64(Tree.Selected.Data)^; line := PInt64(Tree.Selected.Data)^;
fDoc.CaretY := line; fDoc.CaretY := line;
fDoc.SelectLine(); fDoc.SelectLine;
end; end;
procedure TCEStaticExplorerWidget.Rescan; procedure TCEStaticExplorerWidget.Rescan;