You've already forked lazarus-ccr
* Backported changes done in main svn tree up to svn rev 143 (version 4.5.4)
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@223 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@@ -2,7 +2,7 @@ unit VirtualTrees;
|
|||||||
|
|
||||||
{$mode delphi}{$H+}
|
{$mode delphi}{$H+}
|
||||||
|
|
||||||
// Version 4.5.1
|
// Version 4.5.4
|
||||||
//
|
//
|
||||||
// The contents of this file are subject to the Mozilla Public License
|
// The contents of this file are subject to the Mozilla Public License
|
||||||
// Version 1.1 (the "License"); you may not use this file except in compliance
|
// Version 1.1 (the "License"); you may not use this file except in compliance
|
||||||
@@ -26,9 +26,24 @@ unit VirtualTrees;
|
|||||||
// (C) 1999-2001 digital publishing AG. All Rights Reserved.
|
// (C) 1999-2001 digital publishing AG. All Rights Reserved.
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
|
// June 2007
|
||||||
|
// - Bug fix: Fixed a problem with potentially large amount of nodes (larger than 2 billion) in
|
||||||
|
// TBaseVirtualTree.SetChildCount.
|
||||||
|
// - Bug fix: remove hint if any in case the tree loses the focus.
|
||||||
|
// - Improvement: TVirtualTreeColumns.HandleClick is now virtual, introduced TVTHeader.DoSetSortColumn.
|
||||||
|
// - Bug fix: compiler error due to old variable reference when enabling flat scrollbars.
|
||||||
|
// May 2007
|
||||||
|
// - Improvement: new functions: GetPreviousSelected, GetPreviousChecked, GetCheckedCount,
|
||||||
|
// GetPreviousCutCopy, GetCutCopyCount, GetFirstLeaf, GetNextLeaf,
|
||||||
|
// GetPreviousLeaf, GetFirstLevel, GetNextLevel, GetPreviousLevel
|
||||||
|
// - Improvement: new properties: CheckedCount, CutCopyCount
|
||||||
|
// - Improvement: DoFocusChanging for finding a valid column (TBaseVirtualTree.WMKeyDown)
|
||||||
|
// March 2007
|
||||||
|
// - Improvement: adjusted accessibility implementation to compile with pre-BDS IDEs.
|
||||||
|
// - If a column is not visible, MultiColumnAccessibility now will not include it.
|
||||||
// January 2007
|
// January 2007
|
||||||
// - Improvement: added code donation from Marco Zehe (with help from Sebastian Modersohn) which implements the
|
// - Improvement: added code donation from Marco Zehe (with help from Sebastian Modersohn) which implements the
|
||||||
// MS accessability interface for Virtual Treeview.
|
// MS accessibility interface for Virtual Treeview.
|
||||||
// December 2006
|
// December 2006
|
||||||
// - Improvement: bidi mode implementation finished (toAutoBidiColumnOrdering introduced)
|
// - Improvement: bidi mode implementation finished (toAutoBidiColumnOrdering introduced)
|
||||||
// - Change: right-to-left flag removed from shorten string methods/events (not necessary)
|
// - Change: right-to-left flag removed from shorten string methods/events (not necessary)
|
||||||
@@ -135,7 +150,7 @@ uses
|
|||||||
const
|
const
|
||||||
{$I lclconstants.inc}
|
{$I lclconstants.inc}
|
||||||
|
|
||||||
VTVersion = '4.5.1';
|
VTVersion = '4.5.4';
|
||||||
VTTreeStreamVersion = 2;
|
VTTreeStreamVersion = 2;
|
||||||
VTHeaderStreamVersion = 3; // The header needs an own stream version to indicate changes only relevant to the header.
|
VTHeaderStreamVersion = 3; // The header needs an own stream version to indicate changes only relevant to the header.
|
||||||
|
|
||||||
@@ -1072,7 +1087,7 @@ type
|
|||||||
procedure FixPositions;
|
procedure FixPositions;
|
||||||
function GetColumnAndBounds(P: TPoint; var ColumnLeft, ColumnRight: Integer; Relative: Boolean = True): Integer;
|
function GetColumnAndBounds(P: TPoint; var ColumnLeft, ColumnRight: Integer; Relative: Boolean = True): Integer;
|
||||||
function GetOwner: TPersistent; override;
|
function GetOwner: TPersistent; override;
|
||||||
procedure HandleClick(P: TPoint; Button: TMouseButton; Force, DblClick: Boolean);
|
procedure HandleClick(P: TPoint; Button: TMouseButton; Force, DblClick: Boolean); virtual;
|
||||||
procedure IndexChanged(OldIndex, NewIndex: Integer);
|
procedure IndexChanged(OldIndex, NewIndex: Integer);
|
||||||
procedure InitializePositionArray;
|
procedure InitializePositionArray;
|
||||||
procedure ReorderColumns(RTL: Boolean);
|
procedure ReorderColumns(RTL: Boolean);
|
||||||
@@ -1208,6 +1223,7 @@ type
|
|||||||
function CanWriteColumns: Boolean; virtual;
|
function CanWriteColumns: Boolean; virtual;
|
||||||
procedure ChangeScale(M, D: Integer); virtual;
|
procedure ChangeScale(M, D: Integer); virtual;
|
||||||
function DetermineSplitterIndex(P: TPoint): Boolean; virtual;
|
function DetermineSplitterIndex(P: TPoint): Boolean; virtual;
|
||||||
|
procedure DoSetSortColumn(Value: TColumnIndex); virtual;
|
||||||
procedure DragTo(P: TPoint);
|
procedure DragTo(P: TPoint);
|
||||||
function GetColumnsClass: TVirtualTreeColumnsClass; virtual;
|
function GetColumnsClass: TVirtualTreeColumnsClass; virtual;
|
||||||
function GetOwner: TPersistent; override;
|
function GetOwner: TPersistent; override;
|
||||||
@@ -1986,10 +2002,12 @@ TBaseVirtualTree = class(TCustomControl)
|
|||||||
function FindInPositionCache(Position: Cardinal; var CurrentPos: Cardinal): PVirtualNode; overload;
|
function FindInPositionCache(Position: Cardinal; var CurrentPos: Cardinal): PVirtualNode; overload;
|
||||||
procedure FixupTotalCount(Node: PVirtualNode);
|
procedure FixupTotalCount(Node: PVirtualNode);
|
||||||
procedure FixupTotalHeight(Node: PVirtualNode);
|
procedure FixupTotalHeight(Node: PVirtualNode);
|
||||||
|
function GetCheckedCount: Integer;
|
||||||
function GetCheckState(Node: PVirtualNode): TCheckState;
|
function GetCheckState(Node: PVirtualNode): TCheckState;
|
||||||
function GetCheckType(Node: PVirtualNode): TCheckType;
|
function GetCheckType(Node: PVirtualNode): TCheckType;
|
||||||
function GetChildCount(Node: PVirtualNode): Cardinal;
|
function GetChildCount(Node: PVirtualNode): Cardinal;
|
||||||
function GetChildrenInitialized(Node: PVirtualNode): Boolean;
|
function GetChildrenInitialized(Node: PVirtualNode): Boolean;
|
||||||
|
function GetCutCopyCount: Integer;
|
||||||
function GetDisabled(Node: PVirtualNode): Boolean;
|
function GetDisabled(Node: PVirtualNode): Boolean;
|
||||||
function GetDragManager: IVTDragManager;
|
function GetDragManager: IVTDragManager;
|
||||||
function GetExpanded(Node: PVirtualNode): Boolean;
|
function GetExpanded(Node: PVirtualNode): Boolean;
|
||||||
@@ -2261,6 +2279,8 @@ TBaseVirtualTree = class(TCustomControl)
|
|||||||
procedure DoTimerScroll; virtual;
|
procedure DoTimerScroll; virtual;
|
||||||
procedure DoUpdating(State: TVTUpdateState); virtual;
|
procedure DoUpdating(State: TVTUpdateState); virtual;
|
||||||
function DoValidateCache: Boolean; virtual;
|
function DoValidateCache: Boolean; virtual;
|
||||||
|
procedure DragAndDrop(AllowedEffects: Integer; DataObject: IDataObject;
|
||||||
|
DragEffect: Integer); virtual;
|
||||||
procedure DragCanceled; override;
|
procedure DragCanceled; override;
|
||||||
function DragDrop(const DataObject: IDataObject; KeyState: Integer; Pt: TPoint;
|
function DragDrop(const DataObject: IDataObject; KeyState: Integer; Pt: TPoint;
|
||||||
var Effect: LongWord): HResult; reintroduce; virtual;
|
var Effect: LongWord): HResult; reintroduce; virtual;
|
||||||
@@ -2532,6 +2552,8 @@ TBaseVirtualTree = class(TCustomControl)
|
|||||||
function GetFirstChild(Node: PVirtualNode): PVirtualNode;
|
function GetFirstChild(Node: PVirtualNode): PVirtualNode;
|
||||||
function GetFirstCutCopy: PVirtualNode;
|
function GetFirstCutCopy: PVirtualNode;
|
||||||
function GetFirstInitialized: PVirtualNode;
|
function GetFirstInitialized: PVirtualNode;
|
||||||
|
function GetFirstLeaf: PVirtualNode;
|
||||||
|
function GetFirstLevel(NodeLevel: Cardinal): PVirtualNode;
|
||||||
function GetFirstNoInit: PVirtualNode;
|
function GetFirstNoInit: PVirtualNode;
|
||||||
function GetFirstSelected: PVirtualNode;
|
function GetFirstSelected: PVirtualNode;
|
||||||
function GetFirstVisible: PVirtualNode;
|
function GetFirstVisible: PVirtualNode;
|
||||||
@@ -2553,6 +2575,8 @@ TBaseVirtualTree = class(TCustomControl)
|
|||||||
function GetNextChecked(Node: PVirtualNode; State: TCheckState = csCheckedNormal): PVirtualNode;
|
function GetNextChecked(Node: PVirtualNode; State: TCheckState = csCheckedNormal): PVirtualNode;
|
||||||
function GetNextCutCopy(Node: PVirtualNode): PVirtualNode;
|
function GetNextCutCopy(Node: PVirtualNode): PVirtualNode;
|
||||||
function GetNextInitialized(Node: PVirtualNode): PVirtualNode;
|
function GetNextInitialized(Node: PVirtualNode): PVirtualNode;
|
||||||
|
function GetNextLeaf(Node: PVirtualNode): PVirtualNode;
|
||||||
|
function GetNextLevel(Node: PVirtualNode; NodeLevel: Cardinal): PVirtualNode;
|
||||||
function GetNextNoInit(Node: PVirtualNode): PVirtualNode;
|
function GetNextNoInit(Node: PVirtualNode): PVirtualNode;
|
||||||
function GetNextSelected(Node: PVirtualNode): PVirtualNode;
|
function GetNextSelected(Node: PVirtualNode): PVirtualNode;
|
||||||
function GetNextSibling(Node: PVirtualNode): PVirtualNode;
|
function GetNextSibling(Node: PVirtualNode): PVirtualNode;
|
||||||
@@ -2565,8 +2589,13 @@ TBaseVirtualTree = class(TCustomControl)
|
|||||||
function GetNodeData(Node: PVirtualNode): Pointer;
|
function GetNodeData(Node: PVirtualNode): Pointer;
|
||||||
function GetNodeLevel(Node: PVirtualNode): Cardinal;
|
function GetNodeLevel(Node: PVirtualNode): Cardinal;
|
||||||
function GetPrevious(Node: PVirtualNode): PVirtualNode;
|
function GetPrevious(Node: PVirtualNode): PVirtualNode;
|
||||||
|
function GetPreviousChecked(Node: PVirtualNode; State: TCheckState = csCheckedNormal): PVirtualNode;
|
||||||
|
function GetPreviousCutCopy(Node: PVirtualNode): PVirtualNode;
|
||||||
function GetPreviousInitialized(Node: PVirtualNode): PVirtualNode;
|
function GetPreviousInitialized(Node: PVirtualNode): PVirtualNode;
|
||||||
|
function GetPreviousLeaf(Node: PVirtualNode): PVirtualNode;
|
||||||
|
function GetPreviousLevel(Node: PVirtualNode; NodeLevel: Cardinal): PVirtualNode;
|
||||||
function GetPreviousNoInit(Node: PVirtualNode): PVirtualNode;
|
function GetPreviousNoInit(Node: PVirtualNode): PVirtualNode;
|
||||||
|
function GetPreviousSelected(Node: PVirtualNode): PVirtualNode;
|
||||||
function GetPreviousSibling(Node: PVirtualNode): PVirtualNode;
|
function GetPreviousSibling(Node: PVirtualNode): PVirtualNode;
|
||||||
function GetPreviousVisible(Node: PVirtualNode): PVirtualNode;
|
function GetPreviousVisible(Node: PVirtualNode): PVirtualNode;
|
||||||
function GetPreviousVisibleNoInit(Node: PVirtualNode): PVirtualNode;
|
function GetPreviousVisibleNoInit(Node: PVirtualNode): PVirtualNode;
|
||||||
@@ -2630,11 +2659,13 @@ TBaseVirtualTree = class(TCustomControl)
|
|||||||
property AccessibleItem: IAccessible read FAccessibleItem write FAccessibleItem;
|
property AccessibleItem: IAccessible read FAccessibleItem write FAccessibleItem;
|
||||||
property AccessibleName: string read FAccessibleName write FAccessibleName;
|
property AccessibleName: string read FAccessibleName write FAccessibleName;
|
||||||
{$endif}
|
{$endif}
|
||||||
|
property CheckedCount: Integer read GetCheckedCount;
|
||||||
property CheckImages: TBitmap read FCheckImages;
|
property CheckImages: TBitmap read FCheckImages;
|
||||||
property CheckState[Node: PVirtualNode]: TCheckState read GetCheckState write SetCheckState;
|
property CheckState[Node: PVirtualNode]: TCheckState read GetCheckState write SetCheckState;
|
||||||
property CheckType[Node: PVirtualNode]: TCheckType read GetCheckType write SetCheckType;
|
property CheckType[Node: PVirtualNode]: TCheckType read GetCheckType write SetCheckType;
|
||||||
property ChildCount[Node: PVirtualNode]: Cardinal read GetChildCount write SetChildCount;
|
property ChildCount[Node: PVirtualNode]: Cardinal read GetChildCount write SetChildCount;
|
||||||
property ChildrenInitialized[Node: PVirtualNode]: Boolean read GetChildrenInitialized;
|
property ChildrenInitialized[Node: PVirtualNode]: Boolean read GetChildrenInitialized;
|
||||||
|
property CutCopyCount: Integer read GetCutCopyCount;
|
||||||
property DragImage: TVTDragImage read FDragImage;
|
property DragImage: TVTDragImage read FDragImage;
|
||||||
property DragManager: IVTDragManager read GetDragManager;
|
property DragManager: IVTDragManager read GetDragManager;
|
||||||
property DropTargetNode: PVirtualNode read FDropTargetNode;
|
property DropTargetNode: PVirtualNode read FDropTargetNode;
|
||||||
@@ -2924,7 +2955,8 @@ type
|
|||||||
property Colors;
|
property Colors;
|
||||||
property Constraints;
|
property Constraints;
|
||||||
property Ctl3D;
|
property Ctl3D;
|
||||||
property CustomCheckImages;
|
//todo: see a way to set CustomCheckImages at design time
|
||||||
|
//property CustomCheckImages;
|
||||||
property DefaultNodeHeight;
|
property DefaultNodeHeight;
|
||||||
property DefaultPasteMode;
|
property DefaultPasteMode;
|
||||||
property DefaultText;
|
property DefaultText;
|
||||||
@@ -9936,22 +9968,7 @@ begin
|
|||||||
if csLoading in Treeview.ComponentState then
|
if csLoading in Treeview.ComponentState then
|
||||||
FSortColumn := Value
|
FSortColumn := Value
|
||||||
else
|
else
|
||||||
begin
|
DoSetSortColumn(Value);
|
||||||
if Value < NoColumn then
|
|
||||||
Value := NoColumn;
|
|
||||||
if Value > Columns.Count - 1 then
|
|
||||||
Value := Columns.Count - 1;
|
|
||||||
if FSortColumn <> Value then
|
|
||||||
begin
|
|
||||||
if FSortColumn > NoColumn then
|
|
||||||
Invalidate(Columns[FSortColumn]);
|
|
||||||
FSortColumn := Value;
|
|
||||||
if FSortColumn > NoColumn then
|
|
||||||
Invalidate(Columns[FSortColumn]);
|
|
||||||
if (toAutoSort in Treeview.FOptions.FAutoOptions) and (Treeview.FUpdateCount = 0) then
|
|
||||||
Treeview.SortTree(FSortColumn, FSortDirection, True);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
@@ -10074,6 +10091,27 @@ end;
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
procedure TVTHeader.DoSetSortColumn(Value: TColumnIndex);
|
||||||
|
|
||||||
|
begin
|
||||||
|
if Value < NoColumn then
|
||||||
|
Value := NoColumn;
|
||||||
|
if Value > Columns.Count - 1 then
|
||||||
|
Value := Columns.Count - 1;
|
||||||
|
if FSortColumn <> Value then
|
||||||
|
begin
|
||||||
|
if FSortColumn > NoColumn then
|
||||||
|
Invalidate(Columns[FSortColumn]);
|
||||||
|
FSortColumn := Value;
|
||||||
|
if FSortColumn > NoColumn then
|
||||||
|
Invalidate(Columns[FSortColumn]);
|
||||||
|
if (toAutoSort in Treeview.FOptions.FAutoOptions) and (Treeview.FUpdateCount = 0) then
|
||||||
|
Treeview.SortTree(FSortColumn, FSortDirection, True);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
procedure TVTHeader.DragTo(P: TPoint);
|
procedure TVTHeader.DragTo(P: TPoint);
|
||||||
|
|
||||||
// Moves the drag image to a new position, which is determined from the passed point P and the previous
|
// Moves the drag image to a new position, which is determined from the passed point P and the previous
|
||||||
@@ -12284,6 +12322,16 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TBaseVirtualTree.DragAndDrop(AllowedEffects: Integer;
|
||||||
|
DataObject: IDataObject; DragEffect: Integer);
|
||||||
|
begin
|
||||||
|
{$ifdef UseExternalDragManager}
|
||||||
|
VirtualDragManager.DoDragDrop(DataObject, DragManager as IDropSource, AllowedEffects, @DragEffect);
|
||||||
|
{$else}
|
||||||
|
ActiveX.DoDragDrop(DataObject, DragManager as IDropSource, AllowedEffects, @DragEffect);
|
||||||
|
{$endif}
|
||||||
|
end;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
procedure TBaseVirtualTree.DrawLineImage(const PaintInfo: TVTPaintInfo; X, Y, H, VAlign: Integer; Style: TVTLineType;
|
procedure TBaseVirtualTree.DrawLineImage(const PaintInfo: TVTPaintInfo; X, Y, H, VAlign: Integer; Style: TVTLineType;
|
||||||
@@ -12457,6 +12505,22 @@ end;
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function TBaseVirtualTree.GetCheckedCount: Integer;
|
||||||
|
|
||||||
|
var
|
||||||
|
Node: PVirtualNode;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Result := 0;
|
||||||
|
Node := GetFirstChecked;
|
||||||
|
while Assigned(Node) do begin
|
||||||
|
Inc(Result);
|
||||||
|
Node := GetNextChecked(Node);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
function TBaseVirtualTree.GetCheckState(Node: PVirtualNode): TCheckState;
|
function TBaseVirtualTree.GetCheckState(Node: PVirtualNode): TCheckState;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
@@ -12492,6 +12556,21 @@ end;
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function TBaseVirtualTree.GetCutCopyCount: Integer;
|
||||||
|
|
||||||
|
var
|
||||||
|
Node: PVirtualNode;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Result := 0;
|
||||||
|
Node := GetFirstCutCopy;
|
||||||
|
while Assigned(Node) do begin
|
||||||
|
Inc(Result);
|
||||||
|
Node := GetNextCutCopy(Node);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
function TBaseVirtualTree.GetDisabled(Node: PVirtualNode): Boolean;
|
function TBaseVirtualTree.GetDisabled(Node: PVirtualNode): Boolean;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
@@ -13025,7 +13104,10 @@ begin
|
|||||||
if PeekMessage(Msg, Handle, 0, 0, PM_REMOVE) then
|
if PeekMessage(Msg, Handle, 0, 0, PM_REMOVE) then
|
||||||
begin
|
begin
|
||||||
if Msg.message = WM_QUIT then
|
if Msg.message = WM_QUIT then
|
||||||
|
begin
|
||||||
|
PostQuitMessage(Msg.WParam);
|
||||||
Break;
|
Break;
|
||||||
|
end;
|
||||||
TranslateMessage(Msg);
|
TranslateMessage(Msg);
|
||||||
DispatchMessage(Msg);
|
DispatchMessage(Msg);
|
||||||
end;
|
end;
|
||||||
@@ -13766,10 +13848,10 @@ procedure TBaseVirtualTree.SetChildCount(Node: PVirtualNode; NewChildCount: Card
|
|||||||
// routine is used.
|
// routine is used.
|
||||||
|
|
||||||
var
|
var
|
||||||
Count: Integer;
|
Remaining: Cardinal;
|
||||||
Index: Cardinal;
|
Index: Cardinal;
|
||||||
Child: PVirtualNode;
|
Child: PVirtualNode;
|
||||||
C: Integer;
|
Count: Integer;
|
||||||
NewHeight: Integer;
|
NewHeight: Integer;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
@@ -13782,18 +13864,17 @@ begin
|
|||||||
DeleteChildren(Node)
|
DeleteChildren(Node)
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
Count := Integer(NewChildCount) - Integer(Node.ChildCount);
|
|
||||||
|
|
||||||
// If nothing changed then do nothing.
|
// If nothing changed then do nothing.
|
||||||
if Count <> 0 then
|
if NewChildCount <> Node.ChildCount then
|
||||||
begin
|
begin
|
||||||
InterruptValidation;
|
InterruptValidation;
|
||||||
|
|
||||||
C := Count;
|
|
||||||
NewHeight := 0;
|
NewHeight := 0;
|
||||||
|
|
||||||
if Count > 0 then
|
if NewChildCount > Node.ChildCount then
|
||||||
begin
|
begin
|
||||||
|
Remaining := NewChildCount - Node.ChildCount;
|
||||||
|
Count := Remaining;
|
||||||
|
|
||||||
// New nodes to add.
|
// New nodes to add.
|
||||||
if Assigned(Node.LastChild) then
|
if Assigned(Node.LastChild) then
|
||||||
Index := Node.LastChild.Index + 1
|
Index := Node.LastChild.Index + 1
|
||||||
@@ -13805,7 +13886,7 @@ begin
|
|||||||
Node.States := Node.States - [vsAllChildrenHidden, vsHeightMeasured];
|
Node.States := Node.States - [vsAllChildrenHidden, vsHeightMeasured];
|
||||||
|
|
||||||
// New nodes are by default always visible, so we don't need to check the visibility.
|
// New nodes are by default always visible, so we don't need to check the visibility.
|
||||||
while Count > 0 do
|
while Remaining > 0 do
|
||||||
begin
|
begin
|
||||||
Child := MakeNewNode;
|
Child := MakeNewNode;
|
||||||
Child.Index := Index;
|
Child.Index := Index;
|
||||||
@@ -13816,7 +13897,7 @@ begin
|
|||||||
Node.LastChild := Child;
|
Node.LastChild := Child;
|
||||||
if Node.FirstChild = nil then
|
if Node.FirstChild = nil then
|
||||||
Node.FirstChild := Child;
|
Node.FirstChild := Child;
|
||||||
Dec(Count);
|
Dec(Remaining);
|
||||||
Inc(Index);
|
Inc(Index);
|
||||||
|
|
||||||
// The actual node height will later be computed once it is clear
|
// The actual node height will later be computed once it is clear
|
||||||
@@ -13828,10 +13909,10 @@ begin
|
|||||||
begin
|
begin
|
||||||
AdjustTotalHeight(Node, NewHeight, True);
|
AdjustTotalHeight(Node, NewHeight, True);
|
||||||
if FullyVisible[Node] then
|
if FullyVisible[Node] then
|
||||||
Inc(Integer(FVisibleCount), C);
|
Inc(Integer(FVisibleCount), Count);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
AdjustTotalCount(Node, C, True);
|
AdjustTotalCount(Node, Count, True);
|
||||||
Node.ChildCount := NewChildCount;
|
Node.ChildCount := NewChildCount;
|
||||||
if (FUpdateCount = 0) and (toAutoSort in FOptions.FAutoOptions) and (FHeader.FSortColumn > InvalidColumn) then
|
if (FUpdateCount = 0) and (toAutoSort in FOptions.FAutoOptions) and (FHeader.FSortColumn > InvalidColumn) then
|
||||||
Sort(Node, FHeader.FSortColumn, FHeader.FSortDirection, True);
|
Sort(Node, FHeader.FSortColumn, FHeader.FSortDirection, True);
|
||||||
@@ -13841,10 +13922,11 @@ begin
|
|||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
// Nodes have to be deleted.
|
// Nodes have to be deleted.
|
||||||
while Count < 0 do
|
Remaining := Node.ChildCount - NewChildCount;
|
||||||
|
while Remaining > 0 do
|
||||||
begin
|
begin
|
||||||
DeleteNode(Node.LastChild);
|
DeleteNode(Node.LastChild);
|
||||||
Inc(Count);
|
Dec(Remaining);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@@ -15749,7 +15831,10 @@ begin
|
|||||||
else
|
else
|
||||||
NewColumn := NoColumn;
|
NewColumn := NoColumn;
|
||||||
// Find a column for the new/current node which can be focused.
|
// Find a column for the new/current node which can be focused.
|
||||||
while (NewColumn > NoColumn) and not DoFocusChanging(FFocusedNode, Node, FFocusedColumn, NewColumn) do
|
// Make the 'DoFocusChanging' for finding a valid column
|
||||||
|
// identifiable from the 'DoFocusChanging' raised later on by
|
||||||
|
// "FocusedNode := Node;"
|
||||||
|
while (NewColumn > NoColumn) and not DoFocusChanging(FFocusedNode, FFocusedNode, FFocusedColumn, NewColumn) do
|
||||||
NewColumn := GetNextColumn(NewColumn);
|
NewColumn := GetNextColumn(NewColumn);
|
||||||
if NewColumn > InvalidColumn then
|
if NewColumn > InvalidColumn then
|
||||||
begin
|
begin
|
||||||
@@ -16242,6 +16327,9 @@ var
|
|||||||
begin
|
begin
|
||||||
Logger.EnterMethod([lcMessages],'WMKillFocus');
|
Logger.EnterMethod([lcMessages],'WMKillFocus');
|
||||||
inherited WMKillFocus(Msg);
|
inherited WMKillFocus(Msg);
|
||||||
|
|
||||||
|
// Remove hint if shown currently.
|
||||||
|
Application.CancelHint;
|
||||||
|
|
||||||
// Stop wheel panning if active.
|
// Stop wheel panning if active.
|
||||||
StopWheelPanning;
|
StopWheelPanning;
|
||||||
@@ -18428,11 +18516,7 @@ begin
|
|||||||
DragEffect := DROPEFFECT_NONE;
|
DragEffect := DROPEFFECT_NONE;
|
||||||
AllowedEffects := GetDragOperations;
|
AllowedEffects := GetDragOperations;
|
||||||
try
|
try
|
||||||
{$ifdef UseExternalDragManager}
|
DragAndDrop(AllowedEffects, DataObject, DragEffect);
|
||||||
virtualdragmanager.DoDragDrop(DataObject, DragManager as IDropSource, AllowedEffects, @DragEffect);
|
|
||||||
{$else}
|
|
||||||
ActiveX.DoDragDrop(DataObject, DragManager as IDropSource, AllowedEffects, @DragEffect);
|
|
||||||
{$endif}
|
|
||||||
DragManager.ForceDragLeave;
|
DragManager.ForceDragLeave;
|
||||||
finally
|
finally
|
||||||
GetCursorPos(P);
|
GetCursorPos(P);
|
||||||
@@ -24931,6 +25015,36 @@ end;
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function TBaseVirtualTree.GetFirstLeaf: PVirtualNode;
|
||||||
|
|
||||||
|
// Returns the first node in the tree which has currently no children.
|
||||||
|
// The result is initialized if necessary.
|
||||||
|
|
||||||
|
begin
|
||||||
|
Result := GetNextLeaf(nil);
|
||||||
|
end;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function TBaseVirtualTree.GetFirstLevel(NodeLevel: Cardinal): PVirtualNode;
|
||||||
|
|
||||||
|
// Returns the first node in the tree on a specific level.
|
||||||
|
// The result is initialized if necessary.
|
||||||
|
|
||||||
|
begin
|
||||||
|
Result := GetFirstNoInit;
|
||||||
|
while Assigned(Result) and (GetNodeLevel(Result) <> NodeLevel) do
|
||||||
|
Result := GetNextNoInit(Result);
|
||||||
|
|
||||||
|
if Assigned(Result) and (GetNodeLevel(Result) <> NodeLevel) then // i.e. there is no node with the desired level in the tree
|
||||||
|
Result := nil;
|
||||||
|
|
||||||
|
if Assigned(Result) and not (vsInitialized in Result.States) then
|
||||||
|
InitNode(Result);
|
||||||
|
end;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
function TBaseVirtualTree.GetFirstNoInit: PVirtualNode;
|
function TBaseVirtualTree.GetFirstNoInit: PVirtualNode;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
@@ -25573,6 +25687,69 @@ end;
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function TBaseVirtualTree.GetNextLeaf(Node: PVirtualNode): PVirtualNode;
|
||||||
|
|
||||||
|
// Returns the next node in the tree which has currently no children.
|
||||||
|
// The result is initialized if necessary.
|
||||||
|
|
||||||
|
begin
|
||||||
|
if (Node = nil) or (Node = FRoot) then
|
||||||
|
Result := FRoot.FirstChild
|
||||||
|
else
|
||||||
|
Result := GetNext(Node);
|
||||||
|
while Assigned(Result) and (vsHasChildren in Result.States) do
|
||||||
|
Result := GetNext(Result);
|
||||||
|
if Assigned(Result) and not (vsInitialized in Result.States) then
|
||||||
|
InitNode(Result);
|
||||||
|
end;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function TBaseVirtualTree.GetNextLevel(Node: PVirtualNode; NodeLevel: Cardinal): PVirtualNode;
|
||||||
|
|
||||||
|
// Returns the next node in the tree on a specific level.
|
||||||
|
// The result is initialized if necessary.
|
||||||
|
|
||||||
|
var
|
||||||
|
StartNodeLevel: Cardinal;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Result := nil;
|
||||||
|
|
||||||
|
if Assigned(Node) and (Node <> FRoot) then
|
||||||
|
begin
|
||||||
|
StartNodeLevel := GetNodeLevel(Node);
|
||||||
|
|
||||||
|
if StartNodeLevel < NodeLevel then
|
||||||
|
begin
|
||||||
|
Result := GetNext(Node);
|
||||||
|
if Assigned(Result) and (GetNodeLevel(Result) <> NodeLevel) then
|
||||||
|
Result := GetNextLevel(Result, NodeLevel);
|
||||||
|
end else if StartNodeLevel = NodeLevel then
|
||||||
|
begin
|
||||||
|
Result := Node.NextSibling;
|
||||||
|
if not Assigned(Result) then // i.e. start node was a last sibling
|
||||||
|
begin
|
||||||
|
Result := Node.Parent;
|
||||||
|
if Assigned(Result) then
|
||||||
|
begin
|
||||||
|
// go to next anchestor of the start node which has a next sibling (if exists)
|
||||||
|
while Assigned(Result) and not Assigned(Result.NextSibling) do
|
||||||
|
Result := Result.Parent;
|
||||||
|
if Assigned(Result) then
|
||||||
|
Result := GetNextLevel(Result.NextSibling, NodeLevel);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end else // i.e. StartNodeLevel > NodeLevel
|
||||||
|
Result := GetNextLevel(Node.Parent, NodeLevel);
|
||||||
|
end;
|
||||||
|
|
||||||
|
if Assigned(Result) and not (vsInitialized in Result.States) then
|
||||||
|
InitNode(Result);
|
||||||
|
end;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
function TBaseVirtualTree.GetNextNoInit(Node: PVirtualNode): PVirtualNode;
|
function TBaseVirtualTree.GetNextNoInit(Node: PVirtualNode): PVirtualNode;
|
||||||
|
|
||||||
// Optimized variant of GetNext, no initialization of nodes is performed (if a node is not initialized
|
// Optimized variant of GetNext, no initialization of nodes is performed (if a node is not initialized
|
||||||
@@ -25998,6 +26175,49 @@ end;
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function TBaseVirtualTree.GetPreviousChecked(Node: PVirtualNode; State: TCheckState = csCheckedNormal): PVirtualNode;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
if (Node = nil) or (Node = FRoot) then
|
||||||
|
Result := FRoot.LastChild
|
||||||
|
else
|
||||||
|
Result := GetPreviousNoInit(Node);
|
||||||
|
|
||||||
|
while Assigned(Result) and (Result.CheckState <> State) do
|
||||||
|
Result := GetPreviousNoInit(Result);
|
||||||
|
|
||||||
|
if Assigned(Result) and not (vsInitialized in Result.States) then
|
||||||
|
InitNode(Result);
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function TBaseVirtualTree.GetPreviousCutCopy(Node: PVirtualNode): PVirtualNode;
|
||||||
|
|
||||||
|
// Returns the previous node in the tree which is currently marked for a clipboard operation. Since only visible nodes can
|
||||||
|
// be marked (or they are hidden after they have been marked) it is not necessary to initialize nodes to check for
|
||||||
|
// child nodes. The result, however, is initialized if necessary.
|
||||||
|
|
||||||
|
begin
|
||||||
|
if ClipboardStates * FStates <> [] then
|
||||||
|
begin
|
||||||
|
if (Node = nil) or (Node = FRoot) then
|
||||||
|
Result := FRoot.LastChild
|
||||||
|
else
|
||||||
|
Result := GetPreviousNoInit(Node);
|
||||||
|
while Assigned(Result) and not (vsCutOrCopy in Result.States) do
|
||||||
|
Result := GetPreviousNoInit(Result);
|
||||||
|
if Assigned(Result) and not (vsInitialized in Result.States) then
|
||||||
|
InitNode(Result);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Result := nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
function TBaseVirtualTree.GetPreviousInitialized(Node: PVirtualNode): PVirtualNode;
|
function TBaseVirtualTree.GetPreviousInitialized(Node: PVirtualNode): PVirtualNode;
|
||||||
|
|
||||||
// Returns the previous node in tree which is initialized.
|
// Returns the previous node in tree which is initialized.
|
||||||
@@ -26011,6 +26231,70 @@ end;
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function TBaseVirtualTree.GetPreviousLeaf(Node: PVirtualNode): PVirtualNode;
|
||||||
|
|
||||||
|
// Returns the previous node in the tree which has currently no children.
|
||||||
|
// The result is initialized if necessary.
|
||||||
|
|
||||||
|
begin
|
||||||
|
if (Node = nil) or (Node = FRoot) then
|
||||||
|
Result := FRoot.LastChild
|
||||||
|
else
|
||||||
|
Result := GetPrevious(Node);
|
||||||
|
while Assigned(Result) and (vsHasChildren in Result.States) do
|
||||||
|
Result := GetPrevious(Result);
|
||||||
|
if Assigned(Result) and not (vsInitialized in Result.States) then
|
||||||
|
InitNode(Result);
|
||||||
|
end;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function TBaseVirtualTree.GetPreviousLevel(Node: PVirtualNode; NodeLevel: Cardinal): PVirtualNode;
|
||||||
|
|
||||||
|
// Returns the previous node in the tree on a specific level.
|
||||||
|
// The result is initialized if necessary.
|
||||||
|
|
||||||
|
var
|
||||||
|
StartNodeLevel: Cardinal;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Result := nil;
|
||||||
|
|
||||||
|
if Assigned(Node) and (Node <> FRoot) then
|
||||||
|
begin
|
||||||
|
StartNodeLevel := GetNodeLevel(Node);
|
||||||
|
|
||||||
|
if StartNodeLevel < NodeLevel then
|
||||||
|
begin
|
||||||
|
Result := Node.PrevSibling;
|
||||||
|
if Assigned(Result) then
|
||||||
|
begin
|
||||||
|
// go to last descendant of previous sibling with desired node level (if exists)
|
||||||
|
while Assigned(Result) and (GetNodeLevel(Result) < NodeLevel) do
|
||||||
|
Result := GetLastChild(Result);
|
||||||
|
if not Assigned(Result) then
|
||||||
|
Result := GetPreviousLevel(Node.PrevSibling, NodeLevel);
|
||||||
|
end else
|
||||||
|
Result := GetPreviousLevel(Node.Parent, NodeLevel);
|
||||||
|
end else if StartNodeLevel = NodeLevel then
|
||||||
|
begin
|
||||||
|
Result := Node.PrevSibling;
|
||||||
|
if not Assigned(Result) then // i.e. start node was a first sibling
|
||||||
|
begin
|
||||||
|
Result := Node.Parent;
|
||||||
|
if Assigned(Result) then
|
||||||
|
Result := GetPreviousLevel(Result, NodeLevel);
|
||||||
|
end;
|
||||||
|
end else // i.e. StartNodeLevel > NodeLevel
|
||||||
|
Result := GetPreviousLevel(Node.Parent, NodeLevel);
|
||||||
|
end;
|
||||||
|
|
||||||
|
if Assigned(Result) and not (vsInitialized in Result.States) then
|
||||||
|
InitNode(Result);
|
||||||
|
end;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
function TBaseVirtualTree.GetPreviousNoInit(Node: PVirtualNode): PVirtualNode;
|
function TBaseVirtualTree.GetPreviousNoInit(Node: PVirtualNode): PVirtualNode;
|
||||||
|
|
||||||
// Returns the previous node in the tree with regard to Node. No initialization in done, hence this
|
// Returns the previous node in the tree with regard to Node. No initialization in done, hence this
|
||||||
@@ -26041,6 +26325,30 @@ end;
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function TBaseVirtualTree.GetPreviousSelected(Node: PVirtualNode): PVirtualNode;
|
||||||
|
|
||||||
|
// Returns the previous node in the tree which is currently selected. Since children of unitialized nodes cannot be
|
||||||
|
// in the current selection (because they simply do not exist yet) it is not necessary to initialize nodes here.
|
||||||
|
// The result however is initialized if necessary.
|
||||||
|
|
||||||
|
begin
|
||||||
|
if FSelectionCount > 0 then
|
||||||
|
begin
|
||||||
|
if (Node = nil) or (Node = FRoot) then
|
||||||
|
Result := FRoot.LastChild
|
||||||
|
else
|
||||||
|
Result := GetPreviousNoInit(Node);
|
||||||
|
while Assigned(Result) and not (vsSelected in Result.States) do
|
||||||
|
Result := GetPreviousNoInit(Result);
|
||||||
|
if Assigned(Result) and not (vsInitialized in Result.States) then
|
||||||
|
InitNode(Result);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Result := nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
function TBaseVirtualTree.GetPreviousSibling(Node: PVirtualNode): PVirtualNode;
|
function TBaseVirtualTree.GetPreviousSibling(Node: PVirtualNode): PVirtualNode;
|
||||||
|
|
||||||
// Get next sibling of Node, initialize it if necessary.
|
// Get next sibling of Node, initialize it if necessary.
|
||||||
@@ -28970,7 +29278,7 @@ begin
|
|||||||
// Since the position is automatically changed if it doesn't meet the range
|
// Since the position is automatically changed if it doesn't meet the range
|
||||||
// we better read the current position back to stay synchronized.
|
// we better read the current position back to stay synchronized.
|
||||||
{$ifdef UseFlatScrollbars}
|
{$ifdef UseFlatScrollbars}
|
||||||
FScrollOffsetX := FlatSB_GetScrollPos(Handle, SB_HORZ);
|
FEffectiveOffsetX := FlatSB_GetScrollPos(Handle, SB_HORZ);
|
||||||
{$else}
|
{$else}
|
||||||
//todo: Use get scrollinfo instead of GetScrollPos??
|
//todo: Use get scrollinfo instead of GetScrollPos??
|
||||||
FEffectiveOffsetX := GetScrollPos(Handle, SB_HORZ);
|
FEffectiveOffsetX := GetScrollPos(Handle, SB_HORZ);
|
||||||
|
Reference in New Issue
Block a user