* 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
begin
// If MultiSelect is selected we will start a full row drag only in case a label was hit,
// otherwise a multi selection will start.
FullRowDrag := (toFullRowDrag in FOptions.FMiscOptions) and IsCellHit and FullRowDrag := (toFullRowDrag in FOptions.FMiscOptions) and IsCellHit and
not (hiNowhere in HitInfo.HitPositions) and not (hiNowhere in HitInfo.HitPositions) and
(NodeSelected or (hiOnItemLabel in HitInfo.HitPositions) or (hiOnNormalIcon in HitInfo.HitPositions)) (NodeSelected or (hiOnItemLabel in HitInfo.HitPositions) or (hiOnNormalIcon in HitInfo.HitPositions));
end IsHeightTracking := (Message.Msg = WM_LBUTTONDOWN) and
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);