From 9cf96b9dfab1dfb914266311f892a477ae72cd7f Mon Sep 17 00:00:00 2001 From: Juha Date: Sun, 25 Jun 2023 06:04:28 +0300 Subject: [PATCH] IDE: Make the PathStyle in search results persistent. Show renamed idents better. Improve GUI texts. Issue #40334, patch by n7800. --- ide/envguioptions.pas | 13 ++- ide/findrenameidentifier.pas | 26 +++-- ide/lazarusidestrconsts.pas | 14 +-- ide/searchresultview.pp | 202 ++++++++++++++++++++--------------- 4 files changed, 149 insertions(+), 106 deletions(-) diff --git a/ide/envguioptions.pas b/ide/envguioptions.pas index 7e0ac7667e..9f6559e1b6 100644 --- a/ide/envguioptions.pas +++ b/ide/envguioptions.pas @@ -32,7 +32,7 @@ type mwfsRelative, // = CreateRelativePath mwfsFull ); - TMsgWndFileNameStyles = set of TMsgWndFileNameStyle; + //TMsgWndFileNameStyles = set of TMsgWndFileNameStyle; const MsgWndFileNameStyleNames: array[TMsgWndFileNameStyle] of string = ( 'Short', // mwfsShort @@ -268,6 +268,8 @@ type // component list FComponentListKeepOpen: Boolean; FComponentListPageIndex: Integer; + // search result view + FSearchResultViewPathStyle: TMsgWndFileNameStyle; // object inspector FObjectInspectorOptions: TOIOptions; // messages @@ -361,6 +363,8 @@ type // component list property ComponentListKeepOpen: Boolean read FComponentListKeepOpen write FComponentListKeepOpen; property ComponentListPageIndex: Integer read FComponentListPageIndex write FComponentListPageIndex; + // search result view + property SearchResultViewPathStyle: TMsgWndFileNameStyle read FSearchResultViewPathStyle write FSearchResultViewPathStyle; // object inspector property ObjectInspectorOptions: TOIOptions read FObjectInspectorOptions; // messages view @@ -1034,6 +1038,9 @@ begin // component list FComponentListKeepOpen:=XMLCfg.GetValue(Path+'ComponentList/KeepOpen',false); FComponentListPageIndex:=XMLCfg.GetValue(Path+'ComponentList/PageIndex',0); + // search result view + FSearchResultViewPathStyle:=StrToMsgWndFilenameStyle(XMLCfg.GetValue( + Path+'SearchResultView/PathStyle',MsgWndFileNameStyleNames[mwfsRelative])); // object inspector FObjectInspectorOptions.Load; FObjectInspectorOptions.SaveBounds:=false; @@ -1154,6 +1161,10 @@ begin // component list XMLCfg.SetDeleteValue(Path+'ComponentList/KeepOpen',FComponentListKeepOpen,false); XMLCfg.SetDeleteValue(Path+'ComponentList/PageIndex',FComponentListPageIndex,0); + // search result view + XMLCfg.SetDeleteValue(Path+'SearchResultView/PathStyle', + MsgWndFileNameStyleNames[FSearchResultViewPathStyle], + MsgWndFileNameStyleNames[mwfsRelative]); // object inspector FObjectInspectorOptions.SaveBounds:=false; FObjectInspectorOptions.Save; diff --git a/ide/findrenameidentifier.pas b/ide/findrenameidentifier.pas index 46e16a32ee..0bf5ec5735 100644 --- a/ide/findrenameidentifier.pas +++ b/ide/findrenameidentifier.pas @@ -112,7 +112,9 @@ function GatherUnitReferences(Files: TStringList; var TreeOfPCodeXYPosition: TAVLTree): TModalResult; function ShowIdentifierReferences( DeclarationCode: TCodeBuffer; const DeclarationCaretXY: TPoint; - TreeOfPCodeXYPosition: TAVLTree): TModalResult; + TreeOfPCodeXYPosition: TAVLTree; + Identifier: string; + RenameTo: string = ''): TModalResult; procedure AddReferencesToResultView(DeclarationCode: TCodeBuffer; const DeclarationCaretXY: TPoint; TreeOfPCodeXYPosition: TAVLTree; ClearItems: boolean; SearchPageIndex: integer); @@ -416,14 +418,14 @@ begin end; if Options.RenameShowResult then Result:=ShowIdentifierReferences(DeclCode, - DeclarationCaretXY,PascalReferences); + DeclarationCaretXY,PascalReferences,Identifier,Options.RenameTo); end; // show result Result:=mrOk; if (not Options.Rename) or (not SetRenameActive) then begin Result:=ShowIdentifierReferences(DeclCode, - DeclarationCaretXY,PascalReferences); + DeclarationCaretXY,PascalReferences,Identifier); if Result<>mrOk then exit; end; @@ -566,27 +568,31 @@ end; function ShowIdentifierReferences( DeclarationCode: TCodeBuffer; const DeclarationCaretXY: TPoint; - TreeOfPCodeXYPosition: TAVLTree): TModalResult; -var + TreeOfPCodeXYPosition: TAVLTree; Identifier: string; + RenameTo: string): TModalResult; +var OldSearchPageIndex: TTabSheet; SearchPageIndex: TTabSheet; + lOptions: TLazFindInFileSearchOptions; begin Result:=mrCancel; LazarusIDE.DoShowSearchResultsView(iwgfShow); SearchPageIndex:=nil; try - // show result - CodeToolBoss.GetIdentifierAt(DeclarationCode, - DeclarationCaretXY.X,DeclarationCaretXY.Y,Identifier); // create a search result page //debugln(['ShowIdentifierReferences ',DbgSName(SearchResultsView)]); + if RenameTo = '' then + lOptions := [] + else + lOptions := [fifReplace]; + SearchPageIndex:=SearchResultsView.AddSearch( Identifier, - '', + RenameTo, ExtractFilePath(DeclarationCode.Filename), '*.pas;*.pp;*.p;*.inc', - [fifWholeWord,fifSearchDirectories]); + lOptions); if SearchPageIndex = nil then exit; // list results diff --git a/ide/lazarusidestrconsts.pas b/ide/lazarusidestrconsts.pas index f09748ef74..48cb94937e 100644 --- a/ide/lazarusidestrconsts.pas +++ b/ide/lazarusidestrconsts.pas @@ -2770,7 +2770,7 @@ resourcestring dlgIncludeSystemVariables = 'Include system variables'; lisRunParamsFileNotExecutable = 'File not executable'; lisRunParamsTheHostApplicationIsNotExecutable = 'The host application "%s" is not executable.'; - dlgTextToFind = '&Text to find'; + dlgTextToFind = 'Search s&tring'; dlgReplaceWith = 'Replace wit&h'; lisBFWhenThisFileIsActiveInSourceEditor = 'When this file is active in source editor'; lisBFOnBuildProjectExecuteTheBuildFileCommandInstead = 'On build project ' @@ -4259,12 +4259,12 @@ resourcestring // find in files dialog lisFindFileMultiLinePattern = '&Multiline pattern'; - lisFindFileWhere = 'Where'; - lisFindFilesearchAllFilesInProject = 'search all files in &project'; - lisFindFilesearchAllOpenFiles = 'search all &open files'; - lisFindFilesSearchInProjectGroup = 'search in project &group'; - lisFindFilesearchInActiveFile = 'search in &active file'; - lisFindFilesearchInDirectories = 'search in &directories'; + lisFindFileWhere = 'Search location'; + lisFindFilesearchAllFilesInProject = 'all files in &project'; + lisFindFilesearchAllOpenFiles = 'all &open files'; + lisFindFilesSearchInProjectGroup = 'project &group'; + lisFindFilesearchInActiveFile = '&active file'; + lisFindFilesearchInDirectories = '&directories'; lisFindFileDirectories = 'D&irectories'; lisMultipleDirectoriesAreSeparatedWithSemicolons = 'Multiple directories are' +' separated with semicolons'; diff --git a/ide/searchresultview.pp b/ide/searchresultview.pp index cee4d48de7..6d6eb48736 100644 --- a/ide/searchresultview.pp +++ b/ide/searchresultview.pp @@ -403,6 +403,15 @@ begin actCloseOthers .ImageIndex := IDEImages.LoadImage('tab_close_LR'); actCloseRight .ImageIndex := IDEImages.LoadImage('tab_close_R'); actCloseAll .ImageIndex := IDEImages.LoadImage('tab_close_All'); + + // load path style + mniPathRelative.Checked := true; // default + case EnvironmentGuiOpts.SearchResultViewPathStyle of + mwfsShort : mniPathAbsolute.Checked := true; + mwfsRelative: mniPathRelative.Checked := true; + mwfsFull : mniPathFileName.Checked := true; + end; + mniShowPathClick(Sender); end; procedure TSearchResultsView.FormKeyDown(Sender: TObject; var Key: Word; @@ -461,18 +470,27 @@ begin SearchInListEdit.SetFocus; end - // toggle path display mode + // toggle path display style else if (Key = VK_P) and (Shift = [ssCtrl]) then begin Key := 0; + // change path style and store in config if mniPathAbsolute.Checked then - mniPathRelative.Checked := true + begin + mniPathRelative.Checked := true; + EnvironmentGuiOpts.SearchResultViewPathStyle := mwfsRelative; + end else if mniPathRelative.Checked then - mniPathFileName.Checked := true + begin + mniPathFileName.Checked := true; + EnvironmentGuiOpts.SearchResultViewPathStyle := mwfsShort; + end else + begin mniPathAbsolute.Checked := true; - + EnvironmentGuiOpts.SearchResultViewPathStyle := mwfsFull; + end; mniShowPathClick(Sender); end @@ -587,6 +605,7 @@ var lOldScroll: TPoint; lDeltaScrollY: integer; begin + if not RefreshButton.Enabled then exit; lTree := GetCurrentTree; if lTree = nil then exit; // this also check ResultsNoteBook.PageIndex @@ -655,6 +674,7 @@ procedure TSearchResultsView.SearchAgainButtonClick(Sender: TObject); var lTree: TLazSearchResultTV; begin + if not SearchAgainButton.Enabled then exit; lTree := GetCurrentTree; if lTree = nil then MainIDEInterface.FindInFiles(Project1) @@ -1069,16 +1089,19 @@ end; procedure TSearchResultsView.UpdateToolbar; var - CurrentTV: TLazSearchResultTV; - state: Boolean; + lTree: TLazSearchResultTV; + lEnabled, lRenameIdResults: Boolean; begin - CurrentTV := GetCurrentTree; - state := Assigned(CurrentTV) and not CurrentTV.Updating; - RefreshButton.Enabled := state; - SearchAgainButton.Enabled := state; - ClosePageButton.Enabled := state; - SearchInListEdit.Enabled := state; - if state then + lTree := GetCurrentTree; + lEnabled := Assigned(lTree) and (not lTree.Updating); + lRenameIdResults := Assigned(lTree) and + (lTree.SearchObject.SearchOptions - [fifReplace, fifReplaceAll] = []); + + RefreshButton .Enabled := lEnabled and (not lRenameIdResults); + SearchAgainButton.Enabled := lEnabled and (not lRenameIdResults); + ClosePageButton .Enabled := lEnabled; + SearchInListEdit .Enabled := lEnabled; + if lEnabled then AsyncUpdateCloseButtons:=svcbEnable; end; @@ -1167,75 +1190,73 @@ begin end; procedure TSearchResultsView.NoteBookShowHint(Sender: TObject; HintInfo: PHintInfo); - - function GetHintString: string; - var - lThisTV: TLazSearchResultTV = nil; - function SearchOption: string; - const - cFifPlacesNoDir = - [fifSearchProject, fifSearchProjectGroup, fifSearchOpen, fifSearchActive]; - begin - Result := ''; - with lThisTV.SearchObject do begin - if fifSearchProject in SearchOptions then - Result := lisFindFilesearchAllFilesInProject - else if fifSearchProjectGroup in SearchOptions then - Result := lisFindFilesSearchInProjectGroup - else if fifSearchOpen in SearchOptions then - Result := lisFindFilesearchAllOpenFiles - else if fifSearchActive in SearchOptions then - Result := lisFindFilesearchInActiveFile - else if fifSearchDirectories in SearchOptions then - Result := ' ' + SearchDirectories + ' ' - else - Result := '!!! ERROR !!!'; - if (SearchOptions * cFifPlacesNoDir) <> [] then begin - Result := '* ' + Result + ' *'; - Result := StringReplace(Result,'&','',[rfReplaceAll, rfIgnoreCase]); - end; - end; - end; - - const - cFifReplaces = [fifReplace, fifReplaceAll]; - var - lReplaces: boolean; - begin - lThisTV := GetTreeView(FNoteBookTab); - with lThisTV.SearchObject do begin - Result := ''; - lReplaces := (SearchOptions * cFifReplaces) <> []; - if TabEllipsed or lReplaces then begin - Result := SearchString + EndOfLine; - if lReplaces then - Result := Result + '-> ' + EndOfLine + ReplaceText + EndOfLine; - Result := Result + EndOfLine; - end; - Result := Result + SearchOption; - end; - end; - +const + cFifPlaces = [fifSearchDirectories, fifSearchProject, fifSearchProjectGroup, fifSearchOpen, fifSearchActive]; var + lTree: TLazSearchResultTV; p: TPoint; r: TRect; h: integer; -begin - if Sender = ResultsNoteBook then - with ResultsNoteBook do begin - p := HintInfo^.CursorPos; - FNoteBookTab := IndexOfTabAt(p.X, p.Y); - if FNoteBookTab >= 0 then begin - r := ResultsNoteBook.TabRect(FNoteBookTab); - h := SearchInListEdit.Height; // Pick DPI independent value - if p.X > r.Right - 2 * h then - p.X := r.Right - 2 * h; - HintInfo^.HintStr := GetHintString; - HintInfo^.HintPos := ClientToScreen(Point(p.x, r.Bottom - (h div 10))); - end + // + function PlaceIs(aOption: TLazFindInFileSearchOption): boolean; + begin + result := lTree.SearchObject.SearchOptions * cFifPlaces = [aOption]; + end; + // + function GetHintString: string; + var + lReplace: boolean; + begin + result := ''; + lReplace := lTree.SearchObject.SearchOptions * [fifReplace, fifReplaceAll] <> []; + + { Line 1. Place } + if lTree.SearchObject.SearchOptions * cFifPlaces = [] then + begin + { find or rename identifier } + result := lisFRIFindOrRenameIdentifier; + end else begin + { find or replace string } + if PlaceIs(fifSearchProject) then result := RemoveAmpersands(lisFindFilesearchAllFilesInProject) + else if PlaceIs(fifSearchProjectGroup) then result := RemoveAmpersands(lisFindFilesSearchInProjectGroup) + else if PlaceIs(fifSearchOpen) then result := RemoveAmpersands(lisFindFilesearchAllOpenFiles) + else if PlaceIs(fifSearchActive) then result := RemoveAmpersands(lisFindFilesearchInActiveFile) + else if PlaceIs(fifSearchDirectories) then result := '"' + lTree.SearchObject.SearchDirectories + '"' else - Application.CancelHint; + debugln('TSearchResultsView.NoteBookShowHint: An invalid combination of TLazFindInFileSearchOptions flags'); + + result := lisFindFileWhere + ': ' + result; end; + + { Line 2. Search string } + if lTree.SearchObject.TabEllipsed or lReplace then + Result := Result + EndOfLine + RemoveAmpersands(dlgTextToFind) + ': "' + lTree.SearchObject.SearchString + '"'; + + { Line 3. Replace string } + if lReplace then + Result := Result + EndOfLine + RemoveAmpersands(dlgReplaceWith) + ': "' + lTree.SearchObject.ReplaceText + '"' + end; + // +begin + if Sender <> ResultsNoteBook then + exit; + + p := HintInfo^.CursorPos; + FNoteBookTab := ResultsNoteBook.IndexOfTabAt(p.X, p.Y); + if FNoteBookTab >= 0 then + begin + lTree := GetTreeView(FNoteBookTab); + if lTree = nil then exit; + if lTree.SearchObject = nil then exit; + + r := ResultsNoteBook.TabRect(FNoteBookTab); + h := SearchInListEdit.Height; // Pick DPI independent value + if p.X > r.Right - 2 * h then + p.X := r.Right - 2 * h; + HintInfo^.HintStr := GetHintString; + HintInfo^.HintPos := ResultsNoteBook.ClientToScreen(Point(p.x, r.Bottom - (h div 10))); + end else + Application.CancelHint; end; procedure TSearchResultsView.ResultsNoteBookCloseTabClick(Sender: TObject); @@ -1471,21 +1492,26 @@ begin Node.Text ); - if mniPathFileName.Checked then - // file name - DrawNextText(ExtractFileName(lRelPath), clNone, [fsBold]) - else if mniPathRelative.Checked then - // relative path - DrawNextText(lRelPath, clNone, [fsBold]) - else + if fifSearchDirectories in lTree.SearchObject.SearchOptions then + begin + if mniPathFileName.Checked then + // file name + DrawNextText(ExtractFileName(lRelPath), clNone, [fsBold]) + else if mniPathRelative.Checked then + // relative path + DrawNextText(lRelPath, clNone, [fsBold]) + else + // absolute path + DrawNextText(Node.Text, clNone, [fsBold]); + + // also show relative path if row selected + if mniPathFileName.Checked then + if [cdsSelected,cdsMarked] * State <> [] then + DrawNextText(' (' + lRelPath + ')', clHighlightText); + end else // absolute path DrawNextText(Node.Text, clNone, [fsBold]); - // also show relative path if row selected - if mniPathFileName.Checked then - if [cdsSelected,cdsMarked] * State <> [] then - DrawNextText(' (' + lRelPath + ')', clHighlightText); - // show a warning that this is a backup folder // strip path delimiter and filename, then check if last directory is 'backup' if IsBackup(Node.Text) then