diff --git a/icons/file/document_all.png b/icons/file/document_all.png new file mode 100644 index 00000000..44084add Binary files /dev/null and b/icons/file/document_all.png differ diff --git a/src/ce_icons.inc b/src/ce_icons.inc index 6022543c..f19b7e07 100644 --- a/src/ce_icons.inc +++ b/src/ce_icons.inc @@ -1067,6 +1067,20 @@ LazarusResources.Add('document_plus','PNG',[ +#159'8Ej'#12#255'/'#187#148#251#229#151#0#3#0'7'#190#22'@6n'#188'T'#0#0#0#0 +'IEND'#174'B`'#130 ]); +LazarusResources.Add('document_all','PNG',[ + #137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#16#0#0#0#16#8#4#0#0#0#181#250'7' + +#234#0#0#0#4'gAMA'#0#0#175#200'7'#5#138#233#0#0#0#25'tEXtSoftware'#0'Adobe I' + +'mageReadyq'#201'e<'#0#0#0#207'IDAT('#207'u'#145'M'#10#194'0'#16'FG='#135'R' + +#207'P'#218#30#195'3'#184#243':E'#23#30#193'#'#184'q'#163#208#222#192'C("' + +#180#218#159#180#240'9'#153#180'i'#10#149#15#134#132'y'#188'0'#25#162#21#5#20 + +#218'x4'#7#185'!'#10'T'#221'B'#167'A'#137'}LkZ'#140#129#176#229#198#29#23#156 + +#145#226#138#221#137'6'#174'G'#128#10'7(L{'#4'P'#12#252#243#8#208' '#193#216 + +#163'o'#135'X#'#29#144'b'#240#228'x'#227#193#167#2'G'#141#12'@'#239')'#144 + +#225#217'yxp'#23'0'#181#194#151#145#151'X,'#144'X'#192' '#133'<4i0H'#205#200 + +#167#3'<.'#17'm{'#143#137'b'#164'4'#0'O:'#227'a"'#215#160#207'JF'#22'@'#254 + +#203'zt'#179#143#3#12#30'7uN'#254'x'#181#158#179'x'#29#159#150'?,?X'#234#201 + +'.Yw'#0#0#0#0'IEND'#174'B`'#130 +]); LazarusResources.Add('folder','PNG',[ #137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#16#0#0#0#16#8#6#0#0#0#31#243#255'a' +#0#0#0#25'tEXtSoftware'#0'Adobe ImageReadyq'#201'e<'#0#0#2#26'IDATx'#218#164 diff --git a/src/ce_search.lfm b/src/ce_search.lfm index a92e70e8..14924b3d 100644 --- a/src/ce_search.lfm +++ b/src/ce_search.lfm @@ -1,26 +1,26 @@ inherited CESearchWidget: TCESearchWidget Left = 742 - Height = 282 + Height = 287 Top = 278 - Width = 394 + Width = 393 Caption = 'Search & replace' - ClientHeight = 282 - ClientWidth = 394 + ClientHeight = 287 + ClientWidth = 393 inherited Back: TPanel - Height = 282 - Width = 394 - ClientHeight = 282 - ClientWidth = 394 + Height = 287 + Width = 393 + ClientHeight = 287 + ClientWidth = 393 inherited Content: TPanel - Height = 282 - Width = 394 - ClientHeight = 282 - ClientWidth = 394 + Height = 287 + Width = 393 + ClientHeight = 287 + ClientWidth = 393 object cbToFind: TComboBox[0] Left = 4 Height = 23 Top = 4 - Width = 386 + Width = 385 Align = alTop AutoSize = False BorderSpacing.Around = 4 @@ -32,8 +32,8 @@ inherited CESearchWidget: TCESearchWidget object btnFind: TBitBtn[1] Left = 4 Height = 24 - Top = 170 - Width = 386 + Top = 167 + Width = 385 Align = alBottom BorderSpacing.Around = 4 Caption = 'btnFind' @@ -78,8 +78,8 @@ inherited CESearchWidget: TCESearchWidget object btnReplace: TBitBtn[2] Left = 4 Height = 24 - Top = 226 - Width = 386 + Top = 195 + Width = 385 Align = alBottom BorderSpacing.Around = 4 Caption = 'btnReplace' @@ -123,14 +123,14 @@ inherited CESearchWidget: TCESearchWidget end object grpOpts: TGroupBox[3] Left = 4 - Height = 108 + Height = 105 Top = 58 - Width = 386 + Width = 385 Align = alClient BorderSpacing.Around = 4 Caption = 'Options' - ClientHeight = 78 - ClientWidth = 382 + ClientHeight = 75 + ClientWidth = 381 TabOrder = 4 object chkWWord: TCheckBox Left = 8 @@ -190,8 +190,8 @@ inherited CESearchWidget: TCESearchWidget object btnReplaceAll: TBitBtn[4] Left = 4 Height = 24 - Top = 254 - Width = 386 + Top = 259 + Width = 385 Align = alBottom BorderSpacing.Around = 4 Caption = 'btnReplaceAll' @@ -237,18 +237,18 @@ inherited CESearchWidget: TCESearchWidget Left = 4 Height = 23 Top = 31 - Width = 386 + Width = 385 Align = alTop BorderSpacing.Around = 4 BevelOuter = bvNone ClientHeight = 23 - ClientWidth = 386 + ClientWidth = 385 TabOrder = 5 object cbReplaceWth: TComboBox Left = 108 Height = 23 Top = 0 - Width = 278 + Width = 277 Align = alClient Anchors = [akTop, akLeft, akBottom] ItemHeight = 0 @@ -267,51 +267,72 @@ inherited CESearchWidget: TCESearchWidget TabOrder = 0 end end - object btnFindAll: TBitBtn[6] - Left = 4 - Height = 24 - Top = 198 - Width = 386 + object Panel2: TPanel[6] + Left = 0 + Height = 32 + Top = 223 + Width = 393 Align = alBottom - BorderSpacing.Around = 4 - Caption = 'btnFindAll' - 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 - } + BevelOuter = bvNone + ClientHeight = 32 + ClientWidth = 393 TabOrder = 6 + object btnFindAll: TBitBtn + Left = 4 + Height = 24 + Top = 4 + Width = 352 + Align = alClient + BorderSpacing.Around = 4 + Caption = 'btnFindAll' + 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 = 0 + end + object btnAllScope: TBitBtn + Left = 360 + Height = 24 + Top = 4 + Width = 29 + Align = alRight + BorderSpacing.Around = 4 + OnClick = btnAllScopeClick + TabOrder = 1 + end end end end diff --git a/src/ce_search.pas b/src/ce_search.pas index 33a47e83..83b17a41 100644 --- a/src/ce_search.pas +++ b/src/ce_search.pas @@ -8,7 +8,7 @@ uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls, Menus, StdCtrls, actnList, Buttons, SynEdit, SynEditSearch, SynEditTypes, ce_common, ce_mru, ce_widget, ce_synmemo, ce_interfaces, ce_observer, - ce_writableComponent, ce_dialogs, strutils; + ce_writableComponent, ce_dialogs, ce_sharedres; type @@ -43,7 +43,8 @@ type end; { TCESearchWidget } - TCESearchWidget = class(TCEWidget, ICEMultiDocObserver) + TCESearchWidget = class(TCEWidget, ICEMultiDocObserver, ICEProjectObserver) + btnAllScope: TBitBtn; btnFind: TBitBtn; btnFindAll: TBitBtn; btnReplace: TBitBtn; @@ -60,6 +61,8 @@ type grpOpts: TGroupBox; imgList: TImageList; Panel1: TPanel; + Panel2: TPanel; + procedure btnAllScopeClick(Sender: TObject); procedure cbReplaceWthChange(Sender: TObject); procedure cbToFindChange(Sender: TObject); procedure chkEnableRepChange(Sender: TObject); @@ -75,21 +78,31 @@ type fCancelAll: boolean; fHasSearched: boolean; fHasRestarted: boolean; + fProj: ICECommonProject; + fAllInProj: boolean; function getOptions: TSynSearchOptions; procedure actReplaceAllExecute(sender: TObject); procedure replaceEvent(Sender: TObject; const ASearch, AReplace: string; Line, Column: integer; var ReplaceAction: TSynReplaceAction); - protected - procedure updateImperative; override; - public - constructor Create(aOwner: TComponent); override; - destructor Destroy; override; + // + procedure projNew(aProject: ICECommonProject); + procedure projChanged(aProject: ICECommonProject); + procedure projClosing(aProject: ICECommonProject); + procedure projFocused(aProject: ICECommonProject); + procedure projCompiling(aProject: ICECommonProject); // procedure docNew(aDoc: TCESynMemo); procedure docClosing(aDoc: TCESynMemo); procedure docFocused(aDoc: TCESynMemo); procedure docChanged(aDoc: TCESynMemo); // + procedure findAll(const filename: string; lines: TStrings); + protected + procedure updateImperative; override; + public + constructor Create(aOwner: TComponent); override; + destructor Destroy; override; + // procedure actFindNextExecute(sender: TObject); procedure actReplaceNextExecute(sender: TObject); procedure actFindAllExecute(sender: TObject); @@ -215,6 +228,7 @@ begin btnReplace.Action := fActReplaceNext; btnReplaceAll.Action := fActReplaceAll; btnFindAll.Action := fActFindAll; + AssignPng(btnAllScope, 'document'); updateImperative; // EntitiesConnector.addObserver(self); @@ -256,7 +270,7 @@ begin end; procedure TCESearchWidget.replaceEvent(Sender: TObject; const ASearch, AReplace: - string; Line, Column: integer; var ReplaceAction: TSynReplaceAction); + string; Line, Column: integer; var ReplaceAction: TSynReplaceAction); begin case dlgReplaceAll of mrYes: ReplaceAction := raReplace; @@ -271,6 +285,37 @@ begin end; procedure TCESearchWidget.actFindAllExecute(sender: TObject); +var + i: integer; + syn: TSynEdit; + fnm: string; +begin + if fDoc.isNil and not fAllInProj then + exit; + if (fProj = nil) and fAllInProj then + exit; + // + fSearchMru.Insert(0,fToFind); + cbToFind.Items.Assign(fSearchMru); + // + if fAllInProj then + begin + syn := TSynEdit.Create(nil); + try + for i := 0 to fProj.sourcesCount-1 do + begin + fnm := fProj.sourceAbsolute(i); + syn.Lines.LoadFromFile(fnm); + findAll(fnm, syn.Lines); + end; + finally + syn.Free; + end; + end + else findAll(fDoc.fileName, fDoc.Lines); +end; + +procedure TCESearchWidget.findAll(const filename: string; lines: TStrings); var search: TSynEditSearch; options: TSynSearchOptions; @@ -282,11 +327,6 @@ var i: integer; res: array of TPoint = nil; begin - if fDoc.isNil then exit; - // - fSearchMru.Insert(0,fToFind); - cbToFind.Items.Assign(fSearchMru); - // search := TSynEditSearch.Create; try options := getOptions; @@ -294,10 +334,12 @@ begin search.Whole := ssoWholeWord in options; search.RegularExpressions:= ssoRegExpr in options; search.Pattern:=fToFind; - search.IdentChars:=fDoc.IdentChars; + + // search.IdentChars:= []; + start := Point(1,1); - stop := Point(high(integer), fDoc.Lines.Count); - while search.FindNextOne(fDoc.Lines, start, stop, startf, stopf) do + stop := Point(high(integer), lines.Count); + while search.FindNextOne(lines, start, stop, startf, stopf) do begin setLength(res, length(res) + 1); res[high(res)].X := startf.X; @@ -307,10 +349,10 @@ begin msgs := getMessageDisplay; msg := format('%d result(s) for the pattern <%s>', [length(res), fToFind]); msgs.message(msg, nil, amcMisc, amkInf); - fmt := fDoc.fileName + '(%d,%d): "%s"'; + fmt := fileName + '(%d,%d): "%s"'; for i := 0 to high(res) do begin - msg := format(fmt, [res[i].Y, res[i].X, Trim(fDoc.Lines.Strings[res[i].Y-1])]); + msg := format(fmt, [res[i].Y, res[i].X, Trim(lines.Strings[res[i].Y-1])]); msgs.message(msg, nil, amcMisc, amkInf); end; finally @@ -413,6 +455,35 @@ begin end; {$ENDREGION} +{$REGION ICEProjectObserver ----------------------------------------------------} +procedure TCESearchWidget.projNew(aProject: ICECommonProject); +begin + fProj := aProject; + updateImperative; +end; + +procedure TCESearchWidget.projChanged(aProject: ICECommonProject); +begin +end; + +procedure TCESearchWidget.projClosing(aProject: ICECommonProject); +begin + if fProj = aProject then + fProj := nil; + updateImperative; +end; + +procedure TCESearchWidget.projFocused(aProject: ICECommonProject); +begin + fProj := aProject; + updateImperative; +end; + +procedure TCESearchWidget.projCompiling(aProject: ICECommonProject); +begin +end; +{$ENDREGION} + {$REGION ICEMultiDocObserver ---------------------------------------------------} procedure TCESearchWidget.docNew(aDoc: TCESynMemo); begin @@ -461,14 +532,33 @@ begin updateImperative; end; -procedure TCESearchWidget.updateImperative; +procedure TCESearchWidget.btnAllScopeClick(Sender: TObject); begin + fAllInProj := not fAllInProj; + if fAllInProj then + begin + AssignPng(btnAllScope, 'document_all'); + btnAllScope.Hint := 'all project sources'; + end + else + begin + AssignPng(btnAllScope, 'document'); + btnAllScope.Hint := 'selected source'; + end; + updateImperative; +end; + +procedure TCESearchWidget.updateImperative; +var + canAll: boolean; +begin + canAll := (fDoc.isNotNil and not fAllInProj) or (fAllInProj and (fProj <> nil)); btnFind.Enabled := fDoc.isNotNil and fToFind.isNotEmpty; - btnFindAll.Enabled := fDoc.isNotNil and fToFind.isNotEmpty; + btnFindAll.Enabled := canAll; btnReplace.Enabled := fDoc.isNotNil and chkEnableRep.Checked and fToFind.isNotEmpty; btnReplaceAll.Enabled := btnReplace.Enabled; cbReplaceWth.Enabled := fDoc.isNotNil and chkEnableRep.Checked; - cbToFind.Enabled := fDoc.isNotNil; + cbToFind.Enabled := canAll; end; {$ENDREGION}