IDE: Add hints for result tabs in search result view. Issue #40327, patch by BrunoK.

This commit is contained in:
Juha 2023-06-19 11:15:07 +03:00
parent 6c09197c78
commit f41ec673d7
4 changed files with 265 additions and 141 deletions

View File

@ -542,6 +542,8 @@ var
SearchForm: TSearchProgressForm; SearchForm: TSearchProgressForm;
Where: Integer; Where: Integer;
begin begin
{ Only then in manual dialog data entry }
if aResultsPage < 0 then
SaveHistory; SaveHistory;
SearchForm := TSearchProgressForm.Create(SearchResultsView); SearchForm := TSearchProgressForm.Create(SearchResultsView);

View File

@ -5437,14 +5437,14 @@ resourcestring
// View Search Results dialog // View Search Results dialog
rsFoundButNotListedHere = 'Found but not listed here: '; rsFoundButNotListedHere = 'Found but not listed here: ';
rsRefreshTheSearch = 'Refresh the search'; rsRefreshTheSearch = 'Refresh the search (F5)';
rsNewSearchWithSameCriteria = 'New search with same criteria'; rsNewSearchWithSameCriteria = 'New search with same criteria (Ctrl+N)';
rsShowPathMode = 'Path display mode'; rsShowPathMode = 'Path display mode (Ctrl+P)';
rsShowAbsPath = 'Absolute path'; rsShowAbsPath = 'Absolute path';
rsShowRelPath = 'Relative path'; rsShowRelPath = 'Relative path';
rsShowFileName = 'File name'; rsShowFileName = 'File name';
rsFilterTheListWithString = 'Filter the lines in list with a string'; rsFilterTheListWithString = 'Filter the lines in list with a string (Ctrl+F)';
rsCloseCurrentPage = 'Close current page'; rsCloseCurrentPage = 'Close current page (Ctrl+F4)∥(Ctrl+W)';
rsCloseLeft = 'Close page(s) on the left'; rsCloseLeft = 'Close page(s) on the left';
rsCloseRight = 'Close page(s) on the right'; rsCloseRight = 'Close page(s) on the right';
rsCloseOthers = 'Close other page(s)'; rsCloseOthers = 'Close other page(s)';

View File

@ -1015,11 +1015,12 @@ begin
[mbCancel]); [mbCancel]);
end; end;
finally finally
ListPage.Caption:= Format('%s (%d)',[SearchText, Cnt]); SearchResultsView.SetPageFoundCount(ListPage, Cnt);
// show, but bring to front only if Search Progress dialog was active // show, but bring to front only if Search Progress dialog was active
if fWasActive if fWasActive then
then State := iwgfShowOnTop State := iwgfShowOnTop
else State := iwgfShow; else
State := iwgfShow;
LazarusIDE.DoShowSearchResultsView(State); LazarusIDE.DoShowSearchResultsView(State);
SearchResultsView.EndUpdate(ListPage.PageIndex); SearchResultsView.EndUpdate(ListPage.PageIndex);
end; end;

View File

@ -87,6 +87,7 @@ type
fSearchOptions: TLazFindInFileSearchOptions; fSearchOptions: TLazFindInFileSearchOptions;
fSearchDirectories: string; fSearchDirectories: string;
fSearchMask: string; fSearchMask: string;
ftabEllipsed: boolean;
public public
property SearchString: string read fSearchString write fSearchString; property SearchString: string read fSearchString write fSearchString;
property ReplaceText: string read FReplaceText write FReplaceText; property ReplaceText: string read FReplaceText write FReplaceText;
@ -95,6 +96,7 @@ type
property SearchDirectories: string read fSearchDirectories property SearchDirectories: string read fSearchDirectories
write fSearchDirectories; write fSearchDirectories;
property SearchMask: string read fSearchMask write fSearchMask; property SearchMask: string read fSearchMask write fSearchMask;
property TabEllipsed: boolean read ftabEllipsed write ftabEllipsed;
end; end;
{ TLazSearchResultTV } { TLazSearchResultTV }
@ -176,6 +178,8 @@ type
ToolButton3: TToolButton; ToolButton3: TToolButton;
tbbCloseAll: TToolButton; tbbCloseAll: TToolButton;
procedure RefreshButtonClick(Sender: TObject); procedure RefreshButtonClick(Sender: TObject);
procedure ResultsNoteBookMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure SearchAgainButtonClick(Sender: TObject); procedure SearchAgainButtonClick(Sender: TObject);
procedure ClosePageButtonClick(Sender: TObject); procedure ClosePageButtonClick(Sender: TObject);
procedure ResultsNoteBookResize(Sender: TObject); procedure ResultsNoteBookResize(Sender: TObject);
@ -219,8 +223,9 @@ type
FOnSelectionChanged: TNotifyEvent; FOnSelectionChanged: TNotifyEvent;
FMouseOverIndex: integer; FMouseOverIndex: integer;
FClosingTabs: boolean; FClosingTabs: boolean;
FNoteBookTab: integer;
function IsBackup(const aFullFilePath: string): boolean; function IsBackup(const aFullFilePath: string): boolean;
function BeautifyPageName(const APageName: string): string; function BeautifyPageName(const APageName: string; out aoTabEllipsed : boolean): string;
function GetPageIndex(const APageName: string): integer; function GetPageIndex(const APageName: string): integer;
function GetTreeView(APageIndex: integer): TLazSearchResultTV; function GetTreeView(APageIndex: integer): TLazSearchResultTV;
function GetCurrentTree: TLazSearchResultTV; function GetCurrentTree: TLazSearchResultTV;
@ -234,6 +239,7 @@ type
procedure ClosePageBegin; procedure ClosePageBegin;
procedure ClosePageEnd; procedure ClosePageEnd;
procedure DoAsyncUpdateCloseButtons(Data: PtrInt); procedure DoAsyncUpdateCloseButtons(Data: PtrInt);
procedure NoteBookShowHint(Sender: TObject; {%H-}HintInfo: PHintInfo);
protected protected
procedure Loaded; override; procedure Loaded; override;
procedure ActivateControl(aWinControl: TWinControl); procedure ActivateControl(aWinControl: TWinControl);
@ -265,6 +271,7 @@ type
write fOnSelectionChanged; write fOnSelectionChanged;
property Items[Index: integer]: TStrings read GetItems write SetItems; property Items[Index: integer]: TStrings read GetItems write SetItems;
function GetResultsPage(aIndex: integer): TTabSheet; function GetResultsPage(aIndex: integer): TTabSheet;
procedure SetPageFoundCount(aPage: TTabSheet; aCnt: integer);
end; end;
var var
@ -273,6 +280,9 @@ var
implementation implementation
uses
LCLIntf;
{$R *.lfm} {$R *.lfm}
function CompareTVNodeTextAsFilename(Node1, Node2: Pointer): integer; function CompareTVNodeTextAsFilename(Node1, Node2: Pointer): integer;
@ -357,6 +367,11 @@ begin
// hints // hints
ShowHint:= True; ShowHint:= True;
// Notebook
FNoteBookTab := -1;
ResultsNoteBook.OnMouseMove := @ResultsNoteBookMouseMove;
ResultsNoteBook.OnShowHint := @NoteBookShowHint;
RefreshButton .Hint := rsRefreshTheSearch; RefreshButton .Hint := rsRefreshTheSearch;
SearchAgainButton.Hint := rsNewSearchWithSameCriteria; SearchAgainButton.Hint := rsNewSearchWithSameCriteria;
ClosePageButton .Hint := rsCloseCurrentPage; ClosePageButton .Hint := rsCloseCurrentPage;
@ -394,104 +409,91 @@ begin
actCloseOthers .ImageIndex := IDEImages.LoadImage('tab_close_LR'); actCloseOthers .ImageIndex := IDEImages.LoadImage('tab_close_LR');
actCloseRight .ImageIndex := IDEImages.LoadImage('tab_close_R'); actCloseRight .ImageIndex := IDEImages.LoadImage('tab_close_R');
actCloseAll .ImageIndex := IDEImages.LoadImage('tab_close_All'); actCloseAll .ImageIndex := IDEImages.LoadImage('tab_close_All');
end; end;
procedure TSearchResultsView.FormKeyDown(Sender: TObject; var Key: Word; procedure TSearchResultsView.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState); Shift: TShiftState);
var var
lTree: TLazSearchResultTV; lTree: TLazSearchResultTV;
lChar: string;
begin begin
// select // WriteLn(Key:3, ' ', DbgsVKCode(Key), ' ', ShiftAsStr(Shift));
if (Key = VK_RETURN) and (Shift = []) then { Do not process the key down of key combination themselves }
begin if Key in [0, VK_CONTROL, VK_SHIFT, VK_LCL_ALT, VK_LCL_LALT, VK_LCL_RALT] then
Key := 0; Exit;
{ Process simple keys }
if Shift = [] then begin
repeat
case Key of
VK_RETURN: // select
if assigned(FOnSelectionChanged) then if assigned(FOnSelectionChanged) then
FOnSelectionChanged(self); FOnSelectionChanged(self);
end else VK_ESCAPE: // close
// close
if (Key = VK_ESCAPE) and (Shift = []) then
begin
Key := 0;
Close; Close;
end else VK_F5: // refresh
RefreshButtonClick(Sender);
// line scroll else // another key
if (Key = VK_DOWN) and (Shift = [ssCtrl]) then Break;
begin end;
Key := 0; Key := 0;
Exit;
until True;
end;
{ Process [ssCtrl] + Key }
if Shift = [ssCtrl] then begin
repeat
case Key of
VK_DOWN: begin // line scroll
lTree := GetCurrentTree; lTree := GetCurrentTree;
if lTree <> nil then if lTree <> nil then
lTree.ScrolledTop := lTree.ScrolledTop + lTree.DefaultItemHeight; lTree.ScrolledTop := lTree.ScrolledTop + lTree.DefaultItemHeight;
end else end;
if (Key = VK_UP) and (Shift = [ssCtrl]) then VK_UP: begin // line scroll
begin
Key := 0;
lTree := GetCurrentTree; lTree := GetCurrentTree;
if lTree <> nil then if lTree <> nil then
lTree.ScrolledTop := lTree.ScrolledTop - lTree.DefaultItemHeight; lTree.ScrolledTop := lTree.ScrolledTop - lTree.DefaultItemHeight;
end else end;
VK_LCL_MINUS: // full expand/collapse
// full expand/collapse
if (Key = VK_LCL_MINUS) and (Shift = [ssCtrl]) then
begin
Key := 0;
mniCollapseAllClick(Sender); mniCollapseAllClick(Sender);
end else VK_LCL_EQUAL:
if (Key = VK_LCL_EQUAL) and (Shift = [ssCtrl]) then
begin
Key := 0;
mniExpandAllClick(Sender); mniExpandAllClick(Sender);
end else VK_P: // toggle path display mode
// set focus in filter
if (Key = VK_F) and (Shift = [ssCtrl]) then
begin begin
Key := 0; if mniPathAbsolute.Checked then
mniPathRelative.Checked := True
else if mniPathRelative.Checked then
mniPathFileName.Checked := True
else
mniPathAbsolute.Checked := True;
mniShowPathClick(Sender);
end;
VK_F: // attempt focusing filter field
if SearchInListEdit.CanSetFocus then if SearchInListEdit.CanSetFocus then
SearchInListEdit.SetFocus; SearchInListEdit.SetFocus;
end else VK_N: // new search
// toggle path display mode
if (Key = VK_P) and (Shift = [ssCtrl]) then
begin
Key := 0;
if mniPathAbsolute.Checked then
mniPathRelative.Checked := true
else if mniPathRelative.Checked then
mniPathFileName.Checked := true
else
mniPathAbsolute.Checked := true;
mniShowPathClick(Sender);
end else
// new search
if (Key = VK_N) and (Shift = [ssCtrl]) then
begin
Key := 0;
SearchAgainButtonClick(Sender); SearchAgainButtonClick(Sender);
end else else // another key
break;
end;
Key := 0;
Exit;
until True;
end;
// refresh { process next tab }
if (Key = VK_F5) and (Shift = []) then if (Key = VK_TAB) then begin
begin repeat
if Shift = [ssCtrl] then
ResultsNoteBook.SelectNextPage(True)
else if Shift = [ssShift, ssCtrl] then
ResultsNoteBook.SelectNextPage(False)
else
break;
Key := 0; Key := 0;
RefreshButtonClick(Sender); Exit;
end else until True;
// next tab
if (Key = VK_TAB) and (Shift = [ssCtrl]) then
begin
Key := 0;
ResultsNoteBook.SelectNextPage(true);
end else
if (Key = VK_TAB) and (Shift = [ssShift, ssCtrl]) then
begin
Key := 0;
ResultsNoteBook.SelectNextPage(false);
end; end;
end; end;
@ -527,27 +529,35 @@ end;
procedure TSearchResultsView.mniExpandAllClick(Sender: TObject); procedure TSearchResultsView.mniExpandAllClick(Sender: TObject);
var var
lTree: TLazSearchResultTV; lTree: TLazSearchResultTV;
lOldCursor : TCursor;
begin begin
lTree := GetCurrentTree; lTree := GetCurrentTree;
if lTree = nil then exit; if lTree = nil then exit;
// expand // expand
lOldCursor := Screen.Cursor;
Screen.Cursor := crHourGlass;
lTree.FullExpand; lTree.FullExpand;
Screen.Cursor := lOldCursor;
end; end;
procedure TSearchResultsView.mniCollapseAllClick(Sender: TObject); procedure TSearchResultsView.mniCollapseAllClick(Sender: TObject);
var var
lTree: TLazSearchResultTV; lTree: TLazSearchResultTV;
lNode: TTreeNode; lNode: TTreeNode;
lOldCursor : TCursor;
begin begin
lTree := GetCurrentTree; lTree := GetCurrentTree;
if lTree = nil then exit; if lTree = nil then exit;
// collapse // collapse
lOldCursor := Screen.Cursor;
Screen.Cursor := crHourGlass;
lTree.FullCollapse; lTree.FullCollapse;
// selection // selection
lTree.ClearSelection; lTree.ClearSelection;
lNode := lTree.Items.GetFirstVisibleNode; lNode := lTree.Items.GetFirstVisibleNode;
if lNode <> nil then if lNode <> nil then
lNode.Selected := true; lNode.Selected := true;
Screen.Cursor := lOldCursor;
end; end;
procedure TSearchResultsView.ResultsNoteBookMouseDown( procedure TSearchResultsView.ResultsNoteBookMouseDown(
@ -615,6 +625,23 @@ begin
end; end;
end; end;
procedure TSearchResultsView.ResultsNoteBookMouseMove(Sender: TObject;
Shift: TShiftState; X, Y: Integer);
var
p: TPoint;
lPageIx: integer;
begin
if Sender = ResultsNoteBook then begin
with ResultsNoteBook do begin
lPageIx := IndexOfTabAt(Point(x, y));
if lPageIx <> FNoteBookTab then begin
FNoteBookTab := lPageIx;
Application.CancelHint;
end;
end;
end;
end;
procedure TSearchResultsView.SearchAgainButtonClick(Sender: TObject); procedure TSearchResultsView.SearchAgainButtonClick(Sender: TObject);
var var
lTree: TLazSearchResultTV; lTree: TLazSearchResultTV;
@ -635,9 +662,10 @@ end;
procedure TSearchResultsView.ResultsNoteBookResize(Sender: TObject); procedure TSearchResultsView.ResultsNoteBookResize(Sender: TObject);
begin begin
if ResultsNoteBook.PageCount > 0 if ResultsNoteBook.PageCount > 0 then
then AsyncUpdateCloseButtons := svcbEnable AsyncUpdateCloseButtons := svcbEnable
else AsyncUpdateCloseButtons := svcbDisable; else
AsyncUpdateCloseButtons := svcbDisable;
end; end;
procedure TSearchResultsView.mniShowPathClick(Sender: TObject); procedure TSearchResultsView.mniShowPathClick(Sender: TObject);
@ -724,7 +752,7 @@ begin
end; end;
end; end;
{Keeps track of the Index of the Item the mouse is over, Sets ShowHint to true {Keeps track of the Index of the Item the mouse is over, Sets Show to true
if the Item length is longer than the TreeView client width.} if the Item length is longer than the TreeView client width.}
procedure TSearchResultsView.LazTVMousemove(Sender: TObject; Shift: TShiftState; procedure TSearchResultsView.LazTVMousemove(Sender: TObject; Shift: TShiftState;
X, Y: Integer); X, Y: Integer);
@ -737,13 +765,10 @@ begin
Node := GetNodeAt(X, Y); Node := GetNodeAt(X, Y);
if Assigned(Node) then if Assigned(Node) then
fMouseOverIndex:=Node.Index fMouseOverIndex:=Node.Index
else else begin
fMouseOverIndex:=-1; fMouseOverIndex:=-1;
if (fMouseOverIndex > -1) and (fMouseOverIndex < Items.Count) Application.CancelHint;
and (Canvas.TextWidth(Items[fMouseOverIndex].Text) > Width) then end;
ShowHint:= True
else
ShowHint:= False;
end;//with end;//with
end; end;
@ -810,13 +835,17 @@ begin
result := 0 = CompareText('backup', ExtractFileName(ExtractFileDir(aFullFilePath))); result := 0 = CompareText('backup', ExtractFileName(ExtractFileDir(aFullFilePath)));
end; end;
function TSearchResultsView.BeautifyPageName(const APageName: string): string; function TSearchResultsView.BeautifyPageName(const APageName: string; out
aoTabEllipsed: boolean): string;
const const
MaxPageName = 25; MaxPageName = 25;
begin begin
aoTabEllipsed:= False;
Result:=Utf8EscapeControlChars(APageName, emHexPascal); Result:=Utf8EscapeControlChars(APageName, emHexPascal);
if UTF8Length(Result)>MaxPageName then if UTF8Length(Result)>MaxPageName then begin
Result:=UTF8Copy(Result,1,MaxPageName-5)+'...'; Result:=UTF8Copy(Result,1,MaxPageName-5)+'...';
aoTabEllipsed:= True;
end;
end; end;
procedure TSearchResultsView.AddMatch(const APageIndex: integer; procedure TSearchResultsView.AddMatch(const APageIndex: integer;
@ -970,9 +999,15 @@ end;
function TSearchResultsView.GetResultsPage(aIndex: integer): TTabSheet; function TSearchResultsView.GetResultsPage(aIndex: integer): TTabSheet;
begin begin
if InRange(aIndex, 0, ResultsNoteBook.PageCount - 1) if InRange(aIndex, 0, ResultsNoteBook.PageCount - 1) then
then result := ResultsNoteBook.Pages[aIndex] Result := ResultsNoteBook.Pages[aIndex]
else result := nil; else
Result := nil;
end;
procedure TSearchResultsView.SetPageFoundCount(aPage: TTabSheet; aCnt: integer);
begin
aPage.Caption := aPage.Caption + Format(' (%d)',[aCnt]);
end; end;
{Sets the Items from the treeview on the currently selected page in the TNoteBook} {Sets the Items from the treeview on the currently selected page in the TNoteBook}
@ -1114,6 +1149,78 @@ begin
lPageList.Free; lPageList.Free;
end; 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;
var
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
else
Application.CancelHint;
end;
end;
procedure TSearchResultsView.ResultsNoteBookCloseTabClick(Sender: TObject); procedure TSearchResultsView.ResultsNoteBookCloseTabClick(Sender: TObject);
begin begin
if Sender is TTabSheet then if Sender is TTabSheet then
@ -1132,15 +1239,15 @@ function TSearchResultsView.AddSearch(
): TTabSheet; ): TTabSheet;
var var
lNewTree: TLazSearchResultTV; lNewTree: TLazSearchResultTV;
lTabEllipsed: boolean;
begin begin
result := nil; result := nil;
if ResultsNoteBook = nil then if ResultsNoteBook = nil then
exit; exit;
with ResultsNoteBook do with ResultsNoteBook do
begin begin
FFocusTreeViewInEndUpdate := (ActivePage = nil) and SearchInListEdit.IsParentOf(ActivePage); FFocusTreeViewInEndUpdate := (ActivePage = nil) and SearchInListEdit.IsParentOf(ActivePage);
FWorkedSearchText := BeautifyPageName(aResultsName); FWorkedSearchText := BeautifyPageName(aResultsName, lTabEllipsed);
PageIndex := TCustomTabControl(ResultsNoteBook).Pages.Add(FWorkedSearchText); PageIndex := TCustomTabControl(ResultsNoteBook).Pages.Add(FWorkedSearchText);
lNewTree := TLazSearchResultTV.Create(Page[PageIndex]); lNewTree := TLazSearchResultTV.Create(Page[PageIndex]);
@ -1149,7 +1256,7 @@ begin
Parent := Page[PageIndex]; Parent := Page[PageIndex];
BorderSpacing.Around := 0; BorderSpacing.Around := 0;
Align := alClient; Align := alClient;
ShowHint := true; ShowHint := False; // true; ~bk apparently OnShowHint messes up with ShowHint True
RowSelect := true; RowSelect := true;
ShowLines := false; ShowLines := false;
Options := Options + [tvoAllowMultiselect] - [tvoThemedDraw]; Options := Options + [tvoAllowMultiselect] - [tvoThemedDraw];
@ -1170,6 +1277,7 @@ begin
lNewTree.SearchObject.SearchDirectories := aDirectories; lNewTree.SearchObject.SearchDirectories := aDirectories;
lNewTree.SearchObject.SearchMask := aFileMask; lNewTree.SearchObject.SearchMask := aFileMask;
lNewTree.SearchObject.SearchOptions := aOptions; lNewTree.SearchObject.SearchOptions := aOptions;
lNewTree.SearchObject.TabEllipsed := lTabEllipsed;
end; end;
lNewTree.Skipped := 0; lNewTree.Skipped := 0;
@ -1182,27 +1290,31 @@ end;
procedure TSearchResultsView.LazTVShowHint(Sender: TObject; HintInfo: PHintInfo); procedure TSearchResultsView.LazTVShowHint(Sender: TObject; HintInfo: PHintInfo);
var var
MatchPos: TLazSearchMatchPos; MatchPos: TLazSearchMatchPos;
HintStr: string; lThisTV: TLazSearchResultTV;
begin begin
if Sender is TLazSearchResultTV then if Sender is TLazSearchResultTV then
begin begin
With Sender as TLazSearchResultTV do lThisTV := Sender as TLazSearchResultTV;
begin With lThisTV do
if (fMouseOverIndex >= 0) and (fMouseOverIndex < Items.Count) then
begin begin
{ (Canvas.TextWidth(Items[fMouseOverIndex].Text) > Width) then}
if (fMouseOverIndex >= 0) and (fMouseOverIndex < Items.Count)
and (Canvas.TextWidth(Items[fMouseOverIndex].Text) > Width)
then begin
if Assigned(Items[fMouseOverIndex].Data) then if Assigned(Items[fMouseOverIndex].Data) then
MatchPos:= TLazSearchMatchPos(Items[fMouseOverIndex].Data) MatchPos:= TLazSearchMatchPos(Items[fMouseOverIndex].Data)
else else
MatchPos:= nil; MatchPos:= nil;
if MatchPos<>nil then if MatchPos<>nil then
HintStr:=MatchPos.Filename HintInfo^.HintStr := MatchPos.Filename
+' ('+IntToStr(MatchPos.FileStartPos.Y) +' ('+IntToStr(MatchPos.FileStartPos.Y)
+','+IntToStr(MatchPos.FileStartPos.X)+')' +','+IntToStr(MatchPos.FileStartPos.X)+')'
+' '+MatchPos.TheText +' '+MatchPos.TheText
else else
HintStr:=Items[fMouseOverIndex].Text; HintInfo^.HintStr := Items[fMouseOverIndex].Text;
Hint:= HintStr; end //if
end;//if else
Application.CancelHint;
end;//with end;//with
end;//if end;//if
end; end;
@ -1265,17 +1377,21 @@ var
lTree.Canvas.Font.Style := []; lTree.Canvas.Font.Style := [];
lTree.Canvas.Brush.Style := bsSolid; lTree.Canvas.Brush.Style := bsSolid;
end; end;
var
lOldBkMode : integer;
begin begin
if Stage <> cdPostPaint then exit; if Stage <> cdPostPaint then exit;
if Sender is TLazSearchResultTV // it also check nil if Sender is TLazSearchResultTV then // it also check nil
then lTree := TLazSearchResultTV(Sender) lTree := TLazSearchResultTV(Sender)
else exit; else
exit;
// clear // clear
lRect := Node.DisplayRect(true); lRect := Node.DisplayRect(true);
lTree.Canvas.FillRect(lRect); lTree.Canvas.FillRect(lRect);
// transparent paint for very near bold text
lOldBkMode := SetBkMode(lTree.Canvas.Handle, TRANSPARENT);
if TObject(Node.Data) is TLazSearchMatchPos then if TObject(Node.Data) is TLazSearchMatchPos then
begin { search results } begin { search results }
@ -1290,9 +1406,10 @@ begin
lPart := inttostr(lMatch.FileStartPos.Y) + ':'; lPart := inttostr(lMatch.FileStartPos.Y) + ':';
lTextX := lRect.Left + 6 * lDigitWidth - lTree.Canvas.GetTextWidth(lPart); lTextX := lRect.Left + 6 * lDigitWidth - lTree.Canvas.GetTextWidth(lPart);
// draw line number ("99999: ") // draw line number ("99999: ")
if [cdsSelected, cdsMarked] * State <> [] if [cdsSelected, cdsMarked] * State <> [] then
then DrawNextText(lPart) DrawNextText(lPart)
else DrawNextText(lPart, clGrayText); else
DrawNextText(lPart, clGrayText);
lTextX := lRect.Left + 7 * lDigitWidth; lTextX := lRect.Left + 7 * lDigitWidth;
lDrawnLength := 0; lDrawnLength := 0;
@ -1311,9 +1428,10 @@ begin
lDrawnLength := lDrawnLength + lMatch.MatchLen; lDrawnLength := lDrawnLength + lMatch.MatchLen;
// draw found text // draw found text
if [cdsSelected,cdsMarked] * State <> [] if [cdsSelected, cdsMarked] * State <> [] then
then DrawNextText(lPart, clHighlightText, [fsBold]) DrawNextText(lPart, clHighlightText, [fsBold])
else DrawNextText(lPart, clHighlight, [fsBold]); else
DrawNextText(lPart, clHighlight, [fsBold]);
// remaining normal text // remaining normal text
if lMatch.NextInThisLine = nil then if lMatch.NextInThisLine = nil then
@ -1357,6 +1475,7 @@ begin
DrawNextText(' [BACKUP]', clRed); DrawNextText(' [BACKUP]', clRed);
end; end;
SetBkMode(lTree.Canvas.Handle, lOldBkMode); // restore
end; end;
{Returns the Position within the source file from a properly formated search result} {Returns the Position within the source file from a properly formated search result}
@ -1457,9 +1576,10 @@ end;
function TSearchResultsView.GetCurrentTree: TLazSearchResultTV; function TSearchResultsView.GetCurrentTree: TLazSearchResultTV;
begin begin
if ResultsNoteBook.PageIndex < 0 if ResultsNoteBook.PageIndex < 0 then
then result := nil Result := nil
else result := GetTreeView(ResultsNoteBook.PageIndex); else
Result := GetTreeView(ResultsNoteBook.PageIndex);
end; end;
procedure TSearchResultsView.SetAsyncUpdateCloseButtons(const AValue: TSVCloseButtonsState); procedure TSearchResultsView.SetAsyncUpdateCloseButtons(const AValue: TSVCloseButtonsState);
@ -1613,9 +1733,10 @@ begin
if fUpdateCount > 0 then exit; if fUpdateCount > 0 then exit;
FreeSrcList := not fUpdating; FreeSrcList := not fUpdating;
if fUpdating if fUpdating then
then SrcList := fUpdateStrings SrcList := fUpdateStrings
else SrcList := ItemsAsStrings; else
SrcList := ItemsAsStrings;
try try
// find shared path (the path of all filenames, that is the same) // find shared path (the path of all filenames, that is the same)