* Synchronize with main VTV repository up to svn rev 512

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3406 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
blikblum
2014-08-02 00:29:27 +00:00
parent 697c55c0ac
commit ec589355d1

View File

@ -3,8 +3,6 @@ unit VirtualTrees;
{$mode delphi}{$H+} {$mode delphi}{$H+}
{$packset 1} {$packset 1}
// Version 5.1.2
//
// 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
// with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ // with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
@ -105,7 +103,7 @@ const
VTMajorVersion = 5; VTMajorVersion = 5;
VTMinorVersion = 1; VTMinorVersion = 1;
VTReleaseVersion = 2; VTReleaseVersion = 4;
VTTreeStreamVersion = 2; VTTreeStreamVersion = 2;
VTHeaderStreamVersion = 6; // The header needs an own stream version to indicate changes only relevant to the header. VTHeaderStreamVersion = 6; // The header needs an own stream version to indicate changes only relevant to the header.
@ -271,7 +269,7 @@ type
vsHasChildren, // Indicates the presence of child nodes without actually setting them. vsHasChildren, // Indicates the presence of child nodes without actually setting them.
vsVisible, // Indicate whether the node is visible or not (independant of the expand states of its parents). vsVisible, // Indicate whether the node is visible or not (independant of the expand states of its parents).
vsSelected, // Set if the node is in the current selection. vsSelected, // Set if the node is in the current selection.
vsInitialUserData, // Set if (via AddChild or InsertNode) initial user data has been set which requires OnFreeNode. vsOnFreeNodeCallRequired, // Set if user data has been set which requires OnFreeNode.
vsAllChildrenHidden, // Set if vsHasChildren is set and no child node has the vsVisible flag set. vsAllChildrenHidden, // Set if vsHasChildren is set and no child node has the vsVisible flag set.
vsClearing, // A node's children are being deleted. Don't register structure change event. vsClearing, // A node's children are being deleted. Don't register structure change event.
vsMultiline, // Node text is wrapped at the cell boundaries instead of being shorted. vsMultiline, // Node text is wrapped at the cell boundaries instead of being shorted.
@ -2328,6 +2326,7 @@ type
FSetOrRestoreBevelKindAndBevelWidth: Boolean; FSetOrRestoreBevelKindAndBevelWidth: Boolean;
procedure CMStyleChanged(var Message: TMessage); message CM_STYLECHANGED; procedure CMStyleChanged(var Message: TMessage); message CM_STYLECHANGED;
procedure CMBorderChanged(var Message: TMessage); message CM_BORDERCHANGED; procedure CMBorderChanged(var Message: TMessage); message CM_BORDERCHANGED;
procedure CMParentDoubleBufferedChange(var Message: TMessage); message CM_PARENTDOUBLEBUFFEREDCHANGED;
{$ifend} {$ifend}
procedure AdjustCoordinatesByIndent(var PaintInfo: TVTPaintInfo; Indent: Integer); procedure AdjustCoordinatesByIndent(var PaintInfo: TVTPaintInfo; Indent: Integer);
@ -2506,6 +2505,8 @@ type
{$endif ThemeSupport} {$endif ThemeSupport}
procedure WMVScroll(var Message: TLMVScroll); message LM_VSCROLL; procedure WMVScroll(var Message: TLMVScroll); message LM_VSCROLL;
function GetRangeX: Cardinal; function GetRangeX: Cardinal;
function GetDoubleBuffered: Boolean;
procedure SetDoubleBuffered(const Value: Boolean);
protected protected
procedure AddToSelection(Node: PVirtualNode); overload; virtual; procedure AddToSelection(Node: PVirtualNode); overload; virtual;
procedure AddToSelection(const NewItems: TNodeArray; NewLength: Integer; ForceInsert: Boolean = False); overload; virtual; procedure AddToSelection(const NewItems: TNodeArray; NewLength: Integer; ForceInsert: Boolean = False); overload; virtual;
@ -2954,6 +2955,10 @@ type
property OnUpdating: TVTUpdatingEvent read FOnUpdating write FOnUpdating; property OnUpdating: TVTUpdatingEvent read FOnUpdating write FOnUpdating;
public public
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
{$ifdef VCLStyleSupport}
class constructor Create;
class destructor Destroy;
{$ifend}
destructor Destroy; override; destructor Destroy; override;
function AbsoluteIndex(Node: PVirtualNode): Cardinal; function AbsoluteIndex(Node: PVirtualNode): Cardinal;
@ -3184,6 +3189,7 @@ type
property VisibleCount: Cardinal read FVisibleCount; property VisibleCount: Cardinal read FVisibleCount;
property VisiblePath[Node: PVirtualNode]: Boolean read GetVisiblePath write SetVisiblePath; property VisiblePath[Node: PVirtualNode]: Boolean read GetVisiblePath write SetVisiblePath;
property UpdateCount: Cardinal read FUpdateCount; property UpdateCount: Cardinal read FUpdateCount;
property DoubleBuffered: Boolean read GetDoubleBuffered write SetDoubleBuffered default True;
end; end;
@ -3507,6 +3513,7 @@ type
property DragWidth; property DragWidth;
property DrawSelectionMode; property DrawSelectionMode;
property EditDelay; property EditDelay;
property EmptyListMessage;
property Enabled; property Enabled;
property Font; property Font;
property Header; property Header;
@ -8002,7 +8009,7 @@ var
begin begin
Result := InvalidColumn; Result := InvalidColumn;
if Relative and (P.X > Header.Columns.GetVisibleFixedWidth) then if Relative and (P.X >= Header.Columns.GetVisibleFixedWidth) then
ColumnLeft := -FHeader.Treeview.FEffectiveOffsetX ColumnLeft := -FHeader.Treeview.FEffectiveOffsetX
else else
ColumnLeft := 0; ColumnLeft := 0;
@ -11779,7 +11786,7 @@ begin
FHeader := GetHeaderClass.Create(Self); FHeader := GetHeaderClass.Create(Self);
// we have an own double buffer handling // we have an own double buffer handling
DoubleBuffered := False; inherited DoubleBuffered := False;
FCheckImageKind := ckSystemDefault; FCheckImageKind := ckSystemDefault;
@ -12282,10 +12289,12 @@ begin
// Simple selection allows to draw the selection rectangle anywhere. No intersection with node captions is // Simple selection allows to draw the selection rectangle anywhere. No intersection with node captions is
// required. Only top and bottom bounds of the rectangle matter. // required. Only top and bottom bounds of the rectangle matter.
if SimpleSelection then if SimpleSelection or (toFullRowSelect in FOptions.FSelectionOptions) then
begin begin
IsInOldRect := (NextTop > OldRect.Top) and (CurrentTop < OldRect.Bottom); IsInOldRect := (NextTop > OldRect.Top) and (CurrentTop < OldRect.Bottom) and
IsInNewRect := (NextTop > NewRect.Top) and (CurrentTop < NewRect.Bottom); ((FHeader.Columns.Count = 0) or (FHeader.Columns.TotalWidth > OldRect.Left)) and (NodeLeft < OldRect.Right);
IsInNewRect := (NextTop > NewRect.Top) and (CurrentTop < NewRect.Bottom) and
((FHeader.Columns.Count = 0) or (FHeader.Columns.TotalWidth > NewRect.Left)) and (NodeLeft < NewRect.Right);
end end
else else
begin begin
@ -14219,6 +14228,20 @@ end;
//---------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------
procedure TBaseVirtualTree.SetDoubleBuffered(const Value: Boolean);
begin
// empty by intention, we do our own buffering
end;
//----------------------------------------------------------------------------------------------------------------------
function TBaseVirtualTree.GetDoubleBuffered: Boolean;
begin
Result := True; // we do our own buffering
end;
//----------------------------------------------------------------------------------------------------------------------
procedure TBaseVirtualTree.SetEmptyListMessage(const Value: String); procedure TBaseVirtualTree.SetEmptyListMessage(const Value: String);
begin begin
@ -15144,15 +15167,18 @@ begin
FSavedBorderWidth := BorderWidth; FSavedBorderWidth := BorderWidth;
end; end;
end; end;
{$IFEND}
// TODO: Compilerversion Ein/Ausschalten < Ist Eingeschaltet >
{$ifdef VCLStyleSupport}
procedure TBaseVirtualTree.CMStyleChanged(var Message: TMessage); procedure TBaseVirtualTree.CMStyleChanged(var Message: TMessage);
begin begin
VclStyleChanged; VclStyleChanged;
RecreateWnd; RecreateWnd;
end; end;
procedure TBaseVirtualTree.CMParentDoubleBufferedChange(var Message: TMessage);
begin
// empty by intention, we do our own buffering
end;
{$ifend} {$ifend}
//---------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------
@ -17808,7 +17834,7 @@ begin
DoScale := True; DoScale := True;
if DoScale then if DoScale then
begin begin
FDefaultNodeHeight := MulDiv(FDefaultNodeHeight, M, D); SetDefaultNodeHeight(MulDiv(FDefaultNodeHeight, M, D));
FHeader.ChangeScale(M, D); FHeader.ChangeScale(M, D);
end; end;
end; end;
@ -17996,6 +18022,11 @@ class constructor TBaseVirtualTree.Create;
begin begin
TCustomStyleEngine.RegisterStyleHook(TBaseVirtualTree, TVclStyleScrollBarsHook); TCustomStyleEngine.RegisterStyleHook(TBaseVirtualTree, TVclStyleScrollBarsHook);
end; end;
class destructor TBaseVirtualTree.Destroy;
begin
TCustomStyleEngine.UnRegisterStyleHook(TBaseVirtualTree, TVclStyleScrollBarsHook);
end;
{$ifend} {$ifend}
procedure TBaseVirtualTree.CreateParams(var Params: TCreateParams); procedure TBaseVirtualTree.CreateParams(var Params: TCreateParams);
@ -19398,7 +19429,7 @@ begin
FDropTargetNode := nil; FDropTargetNode := nil;
if Node = FLastStructureChangeNode then if Node = FLastStructureChangeNode then
FLastStructureChangeNode := nil; FLastStructureChangeNode := nil;
if Assigned(FOnFreeNode) and ([vsInitialized, vsInitialUserData] * Node.States <> []) then if Assigned(FOnFreeNode) and ([vsInitialized, vsOnFreeNodeCallRequired] * Node.States <> []) then
FOnFreeNode(Self, Node); FOnFreeNode(Self, Node);
FreeMem(Node); FreeMem(Node);
end; end;
@ -21297,7 +21328,8 @@ begin
if tsUseExplorerTheme in FStates then if tsUseExplorerTheme in FStates then
Include(CheckPositions, hiOnItemButtonExact); Include(CheckPositions, hiOnItemButtonExact);
if (CheckPositions * HitInfo.HitPositions = []) and not (toFullRowSelect in FOptions.FSelectionOptions) then if (CheckPositions * HitInfo.HitPositions = []) and
(not (toFullRowSelect in FOptions.FSelectionOptions) or (hiNowhere in HitInfo.HitPositions)) then
HitInfo.HitNode := nil; HitInfo.HitNode := nil;
if (HitInfo.HitNode <> FCurrentHotNode) or (HitInfo.HitColumn <> FCurrentHotColumn) then if (HitInfo.HitNode <> FCurrentHotNode) or (HitInfo.HitColumn <> FCurrentHotColumn) then
begin begin
@ -21794,18 +21826,10 @@ begin
MultiSelect := toMultiSelect in FOptions.FSelectionOptions; MultiSelect := toMultiSelect in FOptions.FSelectionOptions;
ShiftEmpty := ShiftState = []; ShiftEmpty := ShiftState = [];
NodeSelected := IsAnyHit and (vsSelected in HitInfo.HitNode.States); NodeSelected := IsAnyHit and (vsSelected in HitInfo.HitNode.States);
if MultiSelect then FullRowDrag := (toFullRowDrag in FOptions.FMiscOptions) and IsCellHit and
begin not (hiNowhere in HitInfo.HitPositions) and
// If MultiSelect is selected we will start a full row drag only in case a label was hit, (NodeSelected or (hiOnItemLabel in HitInfo.HitPositions) or (hiOnNormalIcon in HitInfo.HitPositions));
// otherwise a multi selection will start. IsHeightTracking := (Message.Msg = WM_LBUTTONDOWN) and
FullRowDrag := (toFullRowDrag in FOptions.FMiscOptions) and IsCellHit and
not (hiNowhere in HitInfo.HitPositions) and
(NodeSelected or (hiOnItemLabel in HitInfo.HitPositions) or (hiOnNormalIcon in HitInfo.HitPositions))
end
else // No MultiSelect, hence we can start a drag anywhere in the row.
FullRowDrag := toFullRowDrag in FOptions.FMiscOptions;
IsHeightTracking := (Message.Msg = LM_LBUTTONDOWN) and
(hiOnItem in HitInfo.HitPositions) and (hiOnItem in HitInfo.HitPositions) and
([hiUpperSplitter, hiLowerSplitter] * HitInfo.HitPositions <> []); ([hiUpperSplitter, hiLowerSplitter] * HitInfo.HitPositions <> []);
@ -21815,7 +21839,7 @@ begin
// Query the application to learn if dragging may start now (if set to dmManual). // Query the application to learn if dragging may start now (if set to dmManual).
if Assigned(HitInfo.HitNode) and not AutoDrag and (DragMode = dmManual) then if Assigned(HitInfo.HitNode) and not AutoDrag and (DragMode = dmManual) then
AutoDrag := DoBeforeDrag(HitInfo.HitNode, Column) and (not IsCellHit or FullRowDrag); AutoDrag := DoBeforeDrag(HitInfo.HitNode, Column) and (IsAnyHit or FullRowDrag);
// handle node height tracking // handle node height tracking
if IsHeightTracking then if IsHeightTracking then
@ -21907,7 +21931,7 @@ begin
// selection, but without a change event if it is the only selected node. // selection, but without a change event if it is the only selected node.
// The same applies if the Alt key is pressed, which allows to start drawing the selection rectangle also // The same applies if the Alt key is pressed, which allows to start drawing the selection rectangle also
// on node captions and images. Here the previous selection state does not matter, though. // on node captions and images. Here the previous selection state does not matter, though.
if NodeSelected or (AltPressed and Assigned(HitInfo.HitNode) and (HitInfo.HitColumn = FHeader.MainColumn)) then if NodeSelected or (AltPressed and Assigned(HitInfo.HitNode) and (HitInfo.HitColumn = FHeader.MainColumn)) and not (hiNowhere in HitInfo.HitPositions) then
begin begin
NeedChange := FSelectionCount > 1; NeedChange := FSelectionCount > 1;
InternalClearSelection; InternalClearSelection;
@ -21932,7 +21956,7 @@ begin
begin begin
// The original code here was moved up to fix issue #187. // The original code here was moved up to fix issue #187.
// In order not to break the semantics of this procedure, we are leaving these if statements here // In order not to break the semantics of this procedure, we are leaving these if statements here
if not IsCellHit then if not IsCellHit or (hiNowhere in HitInfo.HitPositions) then
Exit; Exit;
end; end;
@ -23115,7 +23139,7 @@ begin
IntersectClipRect(DC, RC.Left, RC.Top, RC.Right, RC.Bottom); IntersectClipRect(DC, RC.Left, RC.Top, RC.Right, RC.Bottom);
// Determine inner rectangle to exclude (RC corresponds then to the client area). // Determine inner rectangle to exclude (RC corresponds then to the client area).
InflateRect(RC, -BorderWidth, -BorderWidth); InflateRect(RC, -Integer(BorderWidth), -Integer(BorderWidth));
// Remove the inner rectangle. // Remove the inner rectangle.
ExcludeClipRect(DC, RC.Left, RC.Top, RC.Right, RC.Bottom); ExcludeClipRect(DC, RC.Left, RC.Top, RC.Right, RC.Bottom);
@ -24846,7 +24870,7 @@ begin
Body.ChildCount := ChildCount; Body.ChildCount := ChildCount;
Body.NodeHeight := NodeHeight; Body.NodeHeight := NodeHeight;
// Some states are only temporary so take them out as they make no sense at the new location. // Some states are only temporary so take them out as they make no sense at the new location.
Body.States := States - [vsChecking, vsCutOrCopy, vsDeleting, vsInitialUserData, vsHeightMeasured]; Body.States := States - [vsChecking, vsCutOrCopy, vsDeleting, vsOnFreeNodeCallRequired, vsHeightMeasured];
Body.Align := Align; Body.Align := Align;
Body.CheckState := CheckState; Body.CheckState := CheckState;
Body.CheckType := CheckType; Body.CheckType := CheckType;
@ -24989,7 +25013,7 @@ begin
begin begin
NodeData := Pointer(PByte(@Result.Data) + FTotalInternalDataSize); NodeData := Pointer(PByte(@Result.Data) + FTotalInternalDataSize);
NodeData^ := UserData; NodeData^ := UserData;
Include(Result.States, vsInitialUserData); Include(Result.States, vsOnFreeNodeCallRequired);
end end
else else
ShowError(SCannotSetUserData, hcTFCannotSetUserData); ShowError(SCannotSetUserData, hcTFCannotSetUserData);
@ -26716,6 +26740,14 @@ begin
if Y > Max(FRangeY, inherited GetClientRect.Bottom) then if Y > Max(FRangeY, inherited GetClientRect.Bottom) then
Include(HitInfo.HitPositions, hiBelow); Include(HitInfo.HitPositions, hiBelow);
// Convert position into absolute coordinate if necessary.
if Relative then
begin
if X >= Header.Columns.GetVisibleFixedWidth then
Inc(X, FEffectiveOffsetX);
Inc(Y, -FOffsetY);
end;
// If the point is in the tree area then check the nodes. // If the point is in the tree area then check the nodes.
if HitInfo.HitPositions = [] then if HitInfo.HitPositions = [] then
begin begin
@ -27754,9 +27786,8 @@ begin
if (FNodeDataSize <= 0) or (Node = nil) or (Node = FRoot) then if (FNodeDataSize <= 0) or (Node = nil) or (Node = FRoot) then
Result := nil Result := nil
else begin else begin
if ([vsInitialized, vsInitialUserData] * Node.States = []) then
InitNode(Node);
Result := PByte(@Node.Data) + FTotalInternalDataSize; Result := PByte(@Node.Data) + FTotalInternalDataSize;
Include(Node.States, vsOnFreeNodeCallRequired); // We now need to call OnFreeNode, see bug #323
end; end;
end; end;
@ -28767,7 +28798,7 @@ begin
begin begin
NodeData := Pointer(PByte(@Result.Data) + FTotalInternalDataSize); NodeData := Pointer(PByte(@Result.Data) + FTotalInternalDataSize);
NodeData^ := UserData; NodeData^ := UserData;
Include(Result.States, vsInitialUserData); Include(Result.States, vsOnFreeNodeCallRequired);
end end
else else
ShowError(SCannotSetUserData, hcTFCannotSetUserData); ShowError(SCannotSetUserData, hcTFCannotSetUserData);