LCL: TreeView selection handling improved.

git-svn-id: trunk@50168 -
This commit is contained in:
ondrej 2015-10-26 07:10:23 +00:00
parent cdd6191646
commit 5ccd3cef66
2 changed files with 71 additions and 4 deletions

View File

@ -3015,6 +3015,7 @@ type
private
FCount: integer;
FSelection: TFPList;
FStartMultiSelected: TTreeNode; // node where user started multiselection
FFirstMultiSelected: TTreeNode;
FLastMultiSelected: TTreeNode;
FKeepCollapsedNodes: boolean;
@ -3095,6 +3096,7 @@ type
procedure FreeAllNodeData;
procedure SelectionsChanged(ANode: TTreeNode; const AIsSelected: Boolean);
procedure SelectOnlyThis(Node: TTreeNode);
procedure MultiSelect(Node: TTreeNode; ClearWholeSelection: Boolean);
procedure SortTopLevelNodes(SortProc: TTreeNodeCompare);
procedure WriteDebugReport(const Prefix: string; AllNodes: boolean);
property Count: Integer read GetCount;

View File

@ -570,7 +570,10 @@ begin
// If there isn't any selected node, set self as first
if CurNode = nil then
TheTreeNodes.FFirstMultiSelected := Self
begin
TheTreeNodes.FFirstMultiSelected := Self;
TheTreeNodes.FStartMultiSelected := Self;
end
else
begin
@ -2691,6 +2694,67 @@ begin
end;
end;
procedure TTreeNodes.MultiSelect(Node: TTreeNode; ClearWholeSelection: Boolean);
var
I, FirstNode, LastNode: TTreeNode;
GetNext: Boolean;
begin
if Owner<>nil then Owner.LockSelectionChangeEvent;
try
if FStartMultiSelected=nil then
begin
FirstNode := Node;
FStartMultiSelected := Node;
end else
FirstNode := FStartMultiSelected;
if ClearWholeSelection then
begin
ClearMultiSelection(True);
end else
begin
//clear only last selection
if Assigned(FLastMultiSelected) then
begin
LastNode := FLastMultiSelected;
GetNext := (FirstNode.Index <= LastNode.Index);
I := FirstNode;
I.MultiSelected:=False;
while (I<>LastNode) do
begin
if GetNext then
I:=I.GetNextSibling
else
I:=I.GetPrevSibling;
if I=nil then Break;
I.MultiSelected:=False;
end;
end;
if Assigned(Owner) then
Owner.Selected := nil;
end;
//select again
GetNext := (FirstNode.Index <= Node.Index);
I := FirstNode;
I.Selected:=True;
while (I<>Node) do
begin
if GetNext then
I:=I.GetNextSibling
else
I:=I.GetPrevSibling;
if I=nil then Break;
I.Selected:=True;
end;
FStartMultiSelected := FirstNode;
FLastMultiSelected := Node;
finally
if Owner<>nil then Owner.UnlockSelectionChangeEvent;
end;
end;
procedure TTreeNodes.Assign(Source: TPersistent);
var
TreeNodes: TTreeNodes;
@ -5241,8 +5305,7 @@ begin
Exclude(FStates,tvsEditOnMouseUp);
LockSelectionChangeEvent;
try
Items.ClearMultiSelection;
CursorNode.MultiSelectGroup;
Items.MultiSelect(CursorNode, not(ssCtrl in Shift));
finally
UnlockSelectionChangeEvent;
end;
@ -5251,6 +5314,8 @@ begin
begin
Exclude(FStates,tvsEditOnMouseUp);
CursorNode.MultiSelected:=not CursorNode.MultiSelected;
if CursorNode.MultiSelected then
FTreeNodes.FStartMultiSelected := CursorNode;
end
else
begin
@ -5386,7 +5451,7 @@ begin
if tvoAllowMultiSelect in FOptions then
begin
if ASelect then
ANewNode.MultiSelectGroup
FTreeNodes.MultiSelect(ANewNode, False)
else begin
FTreeNodes.SelectOnlyThis(ANewNode);
end;