Issue #1577: make apphelpers.SelectNode more intelligent, returning true/false to indicate whether it successful went through OnFocusChanging event

This commit is contained in:
Ansgar Becker
2022-05-05 19:13:42 +02:00
parent fe9bc11505
commit 56262e50a4
2 changed files with 26 additions and 21 deletions

View File

@ -332,8 +332,8 @@ type
function ComposeOrderClause(Cols: TOrderColArray): String; function ComposeOrderClause(Cols: TOrderColArray): String;
procedure DeInitializeVTNodes(Sender: TBaseVirtualTree); procedure DeInitializeVTNodes(Sender: TBaseVirtualTree);
function FindNode(VT: TVirtualStringTree; idx: Int64; ParentNode: PVirtualNode): PVirtualNode; function FindNode(VT: TVirtualStringTree; idx: Int64; ParentNode: PVirtualNode): PVirtualNode;
procedure SelectNode(VT: TVirtualStringTree; idx: Int64; ParentNode: PVirtualNode=nil); overload; function SelectNode(VT: TVirtualStringTree; idx: Int64; ParentNode: PVirtualNode=nil): Boolean; overload;
procedure SelectNode(VT: TVirtualStringTree; Node: PVirtualNode; ClearSelection: Boolean=True); overload; function SelectNode(VT: TVirtualStringTree; Node: PVirtualNode; ClearSelection: Boolean=True): Boolean; overload;
procedure GetVTSelection(VT: TVirtualStringTree; var SelectedCaptions: TStringList; var FocusedCaption: String); procedure GetVTSelection(VT: TVirtualStringTree; var SelectedCaptions: TStringList; var FocusedCaption: String);
procedure SetVTSelection(VT: TVirtualStringTree; SelectedCaptions: TStringList; FocusedCaption: String); procedure SetVTSelection(VT: TVirtualStringTree; SelectedCaptions: TStringList; FocusedCaption: String);
function GetNextNode(Tree: TVirtualStringTree; CurrentNode: PVirtualNode; Selected: Boolean=False): PVirtualNode; function GetNextNode(Tree: TVirtualStringTree; CurrentNode: PVirtualNode; Selected: Boolean=False): PVirtualNode;
@ -1455,31 +1455,39 @@ begin
end; end;
procedure SelectNode(VT: TVirtualStringTree; idx: Int64; ParentNode: PVirtualNode=nil); overload; function SelectNode(VT: TVirtualStringTree; idx: Int64; ParentNode: PVirtualNode=nil): Boolean; overload;
var var
Node: PVirtualNode; Node: PVirtualNode;
begin begin
// Helper to focus and highlight a node by its index // Helper to focus and highlight a node by its index
Node := FindNode(VT, idx, ParentNode); Node := FindNode(VT, idx, ParentNode);
if Assigned(Node) then if Assigned(Node) then
SelectNode(VT, Node); Result := SelectNode(VT, Node)
else
Result := False;
end; end;
procedure SelectNode(VT: TVirtualStringTree; Node: PVirtualNode; ClearSelection: Boolean=True); overload; function SelectNode(VT: TVirtualStringTree; Node: PVirtualNode; ClearSelection: Boolean=True): Boolean; overload;
var var
OldFocus: PVirtualNode; OldFocus: PVirtualNode;
begin begin
if Node = VT.RootNode then if Node = VT.RootNode then
Node := nil; Node := nil;
OldFocus := VT.FocusedNode; OldFocus := VT.FocusedNode;
if ClearSelection then Result := True;
VT.ClearSelection; if (Node <> OldFocus) and Assigned(VT.OnFocusChanging) then begin
VT.FocusedNode := Node; VT.OnFocusChanging(VT, OldFocus, Node, VT.FocusedColumn, VT.FocusedColumn, Result);
VT.Selected[Node] := True; end;
VT.ScrollIntoView(Node, False); if Result then begin
if (OldFocus = Node) and Assigned(VT.OnFocusChanged) then if ClearSelection then
VT.OnFocusChanged(VT, Node, VT.Header.MainColumn); VT.ClearSelection;
VT.FocusedNode := Node;
VT.Selected[Node] := True;
VT.ScrollIntoView(Node, False);
if (OldFocus = Node) and Assigned(VT.OnFocusChanged) then
VT.OnFocusChanged(VT, Node, VT.Header.MainColumn);
end;
end; end;

View File

@ -367,7 +367,7 @@ var
rx: TRegExpr; rx: TRegExpr;
Prompt: TModalResult; Prompt: TModalResult;
ReplaceFlags: TReplaceFlags; ReplaceFlags: TReplaceFlags;
FocusChangeAllowed: Boolean; NodeSelected: Boolean;
begin begin
// Data grid version of DoSearchReplaceText // Data grid version of DoSearchReplaceText
MainForm.ShowStatusMsg(_('Searching ...')); MainForm.ShowStatusMsg(_('Searching ...'));
@ -388,7 +388,7 @@ begin
ReplaceFlags := [rfReplaceAll]; ReplaceFlags := [rfReplaceAll];
if not (ssoMatchCase in Options) then if not (ssoMatchCase in Options) then
Include(ReplaceFlags, rfIgnoreCase); Include(ReplaceFlags, rfIgnoreCase);
FocusChangeAllowed := True; NodeSelected := True;
// Init regular expression // Init regular expression
rx := TRegExpr.Create; rx := TRegExpr.Create;
@ -451,12 +451,9 @@ begin
Inc(MatchCount); Inc(MatchCount);
// Set focus on node and column // Set focus on node and column
if (Node <> Grid.FocusedNode) and Assigned(Grid.OnFocusChanging) then begin NodeSelected := SelectNode(Grid, Node, False);
Grid.OnFocusChanging(Grid, Grid.FocusedNode, Node, Grid.FocusedColumn, Column, FocusChangeAllowed); if not NodeSelected then
if not FocusChangeAllowed then Break;
Break;
end;
SelectNode(Grid, Node, False);
Grid.FocusedColumn := Column; Grid.FocusedColumn := Column;
// Replace logic // Replace logic
@ -497,7 +494,7 @@ begin
if Match and (not (ssoReplaceAll in Options)) then if Match and (not (ssoReplaceAll in Options)) then
Break; Break;
if not FocusChangeAllowed then if not NodeSelected then
Break; Break;
if Backwards then if Backwards then