diff --git a/components/virtualtreeview-new/trunk/VirtualTrees.pas b/components/virtualtreeview-new/trunk/VirtualTrees.pas index 226fb77be..c730b37eb 100644 --- a/components/virtualtreeview-new/trunk/VirtualTrees.pas +++ b/components/virtualtreeview-new/trunk/VirtualTrees.pas @@ -27,11 +27,32 @@ unit VirtualTrees; // (C) 1999-2001 digital publishing AG. All Rights Reserved. //---------------------------------------------------------------------------------------------------------------------- // +// August 2010 +// - Bug fix: TBaseVirtualTree.OnRemoveFromSelection is now triggered by TBaseVirtualTree.RemoveFromSelection +// as intended +// July 2010 +// - Bug fix: Toggling toShowFilteredNodes will now update the node counts in the tree even if its handle has not +// been allocated so far +// - Bug fix: TBaseVirtualTree.FindNodeInSelection should now work correctly with nodes above the 2gb boundary +// - Bug fix: Nodes that are about to be deleted are now removed from TBaseVirtualTree.FDragSelection +// - Bug fix: Changed TBaseVirtualTree.WMKeyDown to correctly handle special keys in Unicode based Delphi versions +// - Bug fix: Changed declaration of TBaseVirtualTree.EmptyListMessage to UnicodeString +// - Improvement: Added new property TBaseVirtualTree.EmptyListMessage. If this property is not empty, the assigned +// text will be displayed if there are no nodes to display, similar to the Windows XP file search. +// - Improvement: Added tstChecked to TVSTTextSourceType enumeration and support for the new flag to +// GetRenderStartValues(). So you can export only checked nodes. // June 2010 +// - Bug fix: range select with no nodes will no longer result in an access violation +// - Bug fix: TBaseVirtualTree.SetVisible now correctly decrements the visible node count +// - Bug fix: TStringEditLink.BeginEdit now calls AutoAdjustSize to ensure a consistent size of the edit field // - Improvement: TVTHeader.AutoFitColumns is now declared virtual // - Bug fix: header captions were badly positioned text if Extra Large fonts have been activated in the Windows // display options +// May 2010 +// - Improvement: TBaseVirtualTree.PaintTree is now declared virtual +// - Bug fix: corrected calculations regarding tree height and visible count when using filtered nodes // April 2010 +// - Bug fix: Changed TBaseVirtualTree.SetChildCount and TBaseVirtualTree.InitNode to correctly handle filtered nodes // - Bug fix: Ctrl+Click on a node often cause a delayed update of the displayed selection due to a missing (or // misplaced) call to Invalidate() in HandleClickSelection(). // - Bug fix: Shift+PgUp and Shift+PgDown now behave like a usual List(View) and select the node of the previous/ @@ -2237,6 +2258,7 @@ type FHeaderRect: TRect; // Space which the header currently uses in the control (window coords). FLastHintRect: TRect; // Area which the mouse must leave to reshow a hint. FUpdateRect: TRect; + FEmptyListMessage: String; // Optional message that will be displayed if no nodes exist in the control. // paint support and images FPlusBM, @@ -2650,6 +2672,8 @@ type {$endif} {$endif ThemeSupport} procedure WMVScroll(var Message: TLMVScroll); message LM_VSCROLL; + protected + procedure SetEmptyListMessage(const Value: String); procedure AddToSelection(Node: PVirtualNode); overload; virtual; procedure AddToSelection(const NewItems: TNodeArray; NewLength: Integer; ForceInsert: Boolean = False); overload; virtual; procedure AdjustPaintCellRect(var PaintInfo: TVTPaintInfo; out NextNonEmpty: TColumnIndex); virtual; @@ -3140,7 +3164,8 @@ type function GetMaxColumnWidth(Column: TColumnIndex; UseSmartColumnWidth: Boolean = False): Integer; function GetNext(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode; function GetNextChecked(Node: PVirtualNode; State: TCheckState = csCheckedNormal; - ConsiderChildrenAbove: Boolean = False): PVirtualNode; + ConsiderChildrenAbove: Boolean = False): PVirtualNode; overload; + function GetNextChecked(Node: PVirtualNode; ConsiderChildrenAbove: Boolean): PVirtualNode; overload; function GetNextCutCopy(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode; function GetNextInitialized(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode; function GetNextLeaf(Node: PVirtualNode): PVirtualNode; @@ -3194,7 +3219,7 @@ type procedure MoveTo(Node: PVirtualNode; Tree: TBaseVirtualTree; Mode: TVTNodeAttachMode; ChildrenOnly: Boolean); overload; procedure PaintTree(TargetCanvas: TCanvas; const Window: TRect; Target: TPoint; PaintOptions: TVTInternalPaintOptions; - PixelFormat: TPixelFormat = pfDevice); + PixelFormat: TPixelFormat = pfDevice); virtual; function PasteFromClipboard: Boolean; virtual; procedure PrepareDragImage(HotSpot: TPoint; const DataObject: IDataObject); {$ifdef EnablePrint} @@ -3217,8 +3242,11 @@ type procedure SortTree(Column: TColumnIndex; Direction: TSortDirection; DoInit: Boolean = True); virtual; procedure ToggleNode(Node: PVirtualNode); function UpdateAction(Action: TBasicAction): Boolean; override; + procedure UpdateHorizontalRange; procedure UpdateHorizontalScrollBar(DoRepaint: Boolean); + procedure UpdateRanges; procedure UpdateScrollBars(DoRepaint: Boolean); virtual; + procedure UpdateVerticalRange; procedure UpdateVerticalScrollBar(DoRepaint: Boolean); //lcl: reenable in case TControl implementation change to match Delphi // function UseRightToLeftReading: Boolean; @@ -3241,6 +3269,7 @@ type property VTVDragManager: IVTDragManager read GetDragManager; property DropTargetNode: PVirtualNode read FDropTargetNode; property EditLink: IVTEditLink read FEditLink; + property EmptyListMessage: String read FEmptyListMessage write SetEmptyListMessage; property Expanded[Node: PVirtualNode]: Boolean read GetExpanded write SetExpanded; property FocusedColumn: TColumnIndex read FFocusedColumn write SetFocusedColumn default InvalidColumn; property FocusedNode: PVirtualNode read FFocusedNode write SetFocusedNode; @@ -3389,7 +3418,8 @@ type tstInitialized, // Only initialized nodes are rendered. tstSelected, // Only selected nodes are rendered. tstCutCopySet, // Only nodes currently marked as being in the cut/copy clipboard set are rendered. - tstVisible // Only visible nodes are rendered. + tstVisible, // Only visible nodes are rendered. + tstChecked // Only checked nodes are rendered ); TVTPaintText = procedure(Sender: TBaseVirtualTree; const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; @@ -5565,6 +5595,7 @@ var ToBeSet, ToBeCleared: TVTPaintOptions; Run: PVirtualNode; + HandleWasAllocated: Boolean; begin if FPaintOptions <> Value then @@ -5573,6 +5604,34 @@ begin ToBeCleared := FPaintOptions - Value; FPaintOptions := Value; with FOwner do + begin + HandleWasAllocated := HandleAllocated; + + if not (csLoading in ComponentState) and (toShowFilteredNodes in ToBeSet + ToBeCleared) then + begin + if HandleWasAllocated then + BeginUpdate; + InterruptValidation; + Run := GetFirstNoInit; + while Assigned(Run) do + begin + if (vsFiltered in Run.States) and FullyVisible[Run] then + if toShowFilteredNodes in ToBeSet then + begin + Inc(FVisibleCount); + AdjustTotalHeight(Run, Run.NodeHeight, True); + end + else + begin + AdjustTotalHeight(Run, -Run.NodeHeight, True); + Dec(FVisibleCount); + end; + Run := GetNextNoInit(Run); + end; + if HandleWasAllocated then + EndUpdate; + end; + if HandleAllocated then begin {$ifdef ThemeSupport} @@ -5608,32 +5667,9 @@ begin PrepareBitmaps(True, False); RedrawWindow(Handle, nil, 0, RDW_INVALIDATE or RDW_VALIDATE or RDW_FRAME); - end - else + end; {$endif ThemeSupport} - if toShowFilteredNodes in ToBeSet + ToBeCleared then - begin - BeginUpdate; - InterruptValidation; - Run := GetFirst; - while Assigned(Run) do - begin - if (vsFiltered in Run.States) and FullyVisible[Run] then - if toShowFilteredNodes in ToBeSet then - begin - Inc(FVisibleCount); - AdjustTotalHeight(Run.Parent, Run.NodeHeight, True); - end - else - begin - AdjustTotalHeight(Run.Parent, -Run.NodeHeight, True); - Dec(FVisibleCount); - end; - Run := GetNext(Run); - end; - EndUpdate; - end - else + if toChildrenAbove in ToBeSet + ToBeCleared then begin InvalidateCache; @@ -5642,12 +5678,14 @@ begin ValidateCache; Invalidate; end; - end else + end; + Invalidate; end; end; end; end; +end; //---------------------------------------------------------------------------------------------------------------------- @@ -12803,7 +12841,7 @@ begin while Assigned(Child) do begin FixupTotalHeight(Child); - if IsEffectivelyVisible[Child] then + if vsVisible in Child.States then Inc(Node.TotalHeight, Child.TotalHeight); Child := Child.NextSibling; end; @@ -13118,7 +13156,7 @@ begin else AddToSelection(NewNode); end; - Invalidate; + Update;//Invalidate didn't update owner drawn selections end else // Shift key down @@ -14020,7 +14058,7 @@ begin if vsExpanded in Node.States then begin AdjustTotalHeight(Node, NewHeight, True); - if FullyVisible[Node] and not IsEffectivelyFiltered[Node] then + if FullyVisible[Node] then Inc(Integer(FVisibleCount), Count); end; @@ -14146,6 +14184,16 @@ end; //---------------------------------------------------------------------------------------------------------------------- +procedure TBaseVirtualTree.SetEmptyListMessage(const Value: String); + +begin + if Value <> EmptyListMessage then + begin + FEmptyListMessage := Value; + Invalidate; + end; +end; + procedure TBaseVirtualTree.SetExpanded(Node: PVirtualNode; Value: Boolean); begin @@ -14256,6 +14304,10 @@ var begin Assert(Assigned(Node) and (Node <> FRoot), 'Invalid parameter.'); + // Initialize the node if necessary as this might change the filtered state. + if not (vsInitialized in Node.States) then + InitNode(Node); + if Value <> (vsFiltered in Node.States) then begin InterruptValidation; @@ -14263,13 +14315,15 @@ begin if Value then begin Include(Node.States, vsFiltered); - if (vsExpanded in Node.Parent.States) and not (toShowFilteredNodes in FOptions.FPaintOptions) then - AdjustTotalHeight(Node.Parent, -Integer(NodeHeight[Node]), True); - if VisiblePath[Node] then + if not (toShowFilteredNodes in FOptions.FPaintOptions) then + begin + AdjustTotalHeight(Node, -Integer(NodeHeight[Node]), True); + if FullyVisible[Node] then begin Dec(FVisibleCount); NeedUpdate := True; end; + end; if FUpdateCount = 0 then DetermineHiddenChildrenFlag(Node.Parent) @@ -14279,13 +14333,14 @@ begin else begin Exclude(Node.States, vsFiltered); - if (vsExpanded in Node.Parent.States) and not (toShowFilteredNodes in FOptions.FPaintOptions) then - AdjustTotalHeight(Node.Parent, Integer(NodeHeight[Node]), True); - - if VisiblePath[Node] then + if not (toShowFilteredNodes in FOptions.FPaintOptions) then begin - Inc(FVisibleCount); - NeedUpdate := True; + AdjustTotalHeight(Node, Integer(NodeHeight[Node]), True); + if FullyVisible[Node] then + begin + Inc(FVisibleCount); + NeedUpdate := True; + end; end; if vsVisible in Node.States then @@ -14450,20 +14505,25 @@ begin begin Difference := Integer(Value) - Integer(Node.NodeHeight); Node.NodeHeight := Value; - AdjustTotalHeight(Node, Difference, True); - // If an edit operation is currently active then update the editors boundaries as well. - UpdateEditBounds; - - // Stay away from touching the node cache while it is being validated. - if not (tsValidating in FStates) and FullyVisible[Node] and not IsEffectivelyFiltered[Node] then + // If the node is effectively filtered out, nothing else has to be done, as it is not visible anyway. + if not IsEffectivelyFiltered[Node] then begin - InvalidateCache; - if FUpdateCount = 0 then + AdjustTotalHeight(Node, Difference, True); + + // If an edit operation is currently active then update the editors boundaries as well. + UpdateEditBounds; + + // Stay away from touching the node cache while it is being validated. + if not (tsValidating in FStates) and FullyVisible[Node] and not IsEffectivelyFiltered[Node] then begin - ValidateCache; - InvalidateToBottom(Node); - UpdateScrollBars(True); + InvalidateCache; + if FUpdateCount = 0 then + begin + ValidateCache; + InvalidateToBottom(Node); + UpdateScrollBars(True); + end; end; end; end; @@ -14721,24 +14781,25 @@ begin AdjustTotalHeight(Node.Parent, Node.TotalHeight, True); if VisiblePath[Node] then begin - Inc(FVisibleCount, 1 + CountVisibleChildren(Node)); + Inc(FVisibleCount, CountVisibleChildren(Node) + Cardinal(IfThen(IsEffectivelyVisible[Node], 1))); NeedUpdate := True; end; // Update the hidden children flag of the parent. // Since this node is now visible we simply have to remove the flag. + if not IsEffectivelyFiltered[Node] then Exclude(Node.Parent.States, vsAllChildrenHidden); end else begin - Exclude(Node.States, vsVisible); if vsExpanded in Node.Parent.States then AdjustTotalHeight(Node.Parent, -Integer(Node.TotalHeight), True); if VisiblePath[Node] then begin - Dec(FVisibleCount, 1 + CountVisibleChildren(Node)); + Dec(FVisibleCount, CountVisibleChildren(Node) + Cardinal(IfThen(IsEffectivelyVisible[Node], 1))); NeedUpdate := True; end; + Exclude(Node.States, vsVisible); if FUpdateCount = 0 then DetermineHiddenChildrenFlag(Node.Parent) @@ -15948,7 +16009,7 @@ var GetNextNode: TGetNextNodeProc; KeyState: TKeyboardState; - Buffer: array[0..1] of Char; + Buffer: array[0..1] of AnsiChar; begin {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMKeyDown');{$endif} @@ -16353,13 +16414,17 @@ begin FRangeAnchor := FFocusedNode; FLastSelectionLevel := GetNodeLevel(FFocusedNode); end; - // Finally change the selection for a specific range of nodes. - if DoRangeSelect then - ToggleSelection(LastFocused, FFocusedNode); - // Make sure the new focused node is also selected. - if Assigned(FFocusedNode) and ((LastFocused <> FFocusedNode) or ForceSelection) then - AddToSelection(FFocusedNode); + if Assigned(FFocusedNode) then + begin + // Finally change the selection for a specific range of nodes. + if DoRangeSelect then + ToggleSelection(LastFocused, FFocusedNode); + + // Make sure the new focused node is also selected. + if (LastFocused <> FFocusedNode) or ForceSelection then + AddToSelection(FFocusedNode); + end; // If a repaint is needed then paint the entire tree because of the ClearSelection call, if NeedInvalidate then @@ -17807,9 +17872,8 @@ begin Node := Node.FirstChild; while Assigned(Node) do begin - if (vsVisible in Node.States) and (not (vsFiltered in Node.States) or - (toShowFilteredNodes in FOptions.FPaintOptions)) then - Inc(Result, CountVisibleChildren(Node) + 1); + if vsVisible in Node.States then + Inc(Result, CountVisibleChildren(Node) + Cardinal(IfThen(IsEffectivelyVisible[Node], 1))); Node := Node.NextSibling; end; end; @@ -18752,7 +18816,6 @@ procedure TBaseVirtualTree.DoDragging(P: TPoint); var DragEffect, AllowedEffects: LongWord; - I: Integer; DragObject: TDragObject; DataObject: IDataObject; @@ -18811,15 +18874,7 @@ begin if (DragEffect = DROPEFFECT_MOVE) and (toAutoDeleteMovedNodes in TreeOptions.AutoOptions) then begin // The operation was a move so delete the previously selected nodes. - BeginUpdate; - try - // The list of selected nodes was retrieved in resolved state. That means there can never be a node - // in the list whose parent (or its parent etc.) is also selected. - for I := 0 to High(FDragSelection) do - DeleteNode(FDragSelection[I]); - finally - EndUpdate; - end; + DeleteSelectedNodes; end; DoStateChange([], [tsOLEDragging]); @@ -20542,7 +20597,7 @@ function TBaseVirtualTree.FindNodeInSelection(P: PVirtualNode; var Index: Intege var L, H, - I, C: PtrInt; + I: PtrInt; begin Result := False; @@ -20555,13 +20610,12 @@ begin while L <= H do begin I := (L + H) shr 1; - C := PtrInt(FSelection[I]) - PtrInt(P); - if C < 0 then + if PtrInt(FSelection[I]) < PtrInt(P) then L := I + 1 else begin H := I - 1; - if C = 0 then + if FSelection[I] = P then begin Result := True; L := I; @@ -21786,7 +21840,16 @@ begin if ivsMultiline in InitStates then Include(States, vsMultiline); if ivsFiltered in InitStates then + begin Include(States, vsFiltered); + if not (toShowFilteredNodes in FOptions.FPaintOptions) then + begin + AdjustTotalHeight(Node, -NodeHeight, True); + if FullyVisible[Node] then + Dec(FVisibleCount); + UpdateScrollBars(True); + end; + end; // Expanded may already be set (when called from ReinitNode) or be set in DoInitNode, allow both. if (vsExpanded in Node.States) xor (ivsExpanded in InitStates) then @@ -22086,13 +22149,10 @@ begin AdjustTotalCount(Destination.Parent, Node.TotalCount, True); // Add the new node's height only if its parent is expanded. - if (vsExpanded in Destination.Parent.States) and IsEffectivelyVisible[Node] then - AdjustTotalHeight(Destination.Parent, Node.TotalHeight, True); if FullyVisible[Node] then begin - Inc(FVisibleCount, CountVisibleChildren(Node)); - if not IsEffectivelyFiltered[Node] then - Inc(FVisibleCount); + AdjustTotalHeight(Destination.Parent, Node.TotalHeight, True); + Inc(FVisibleCount, CountVisibleChildren(Node) + Cardinal(IfThen(IsEffectivelyVisible[Node], 1))); end; end; amInsertAfter: @@ -22120,13 +22180,10 @@ begin AdjustTotalCount(Destination.Parent, Node.TotalCount, True); // Add the new node's height only if its parent is expanded. - if (vsExpanded in Destination.Parent.States) and IsEffectivelyVisible[Node] then - AdjustTotalHeight(Destination.Parent, Node.TotalHeight, True); if FullyVisible[Node] then begin - Inc(FVisibleCount, CountVisibleChildren(Node)); - if not IsEffectivelyFiltered[Node] then - Inc(FVisibleCount); + AdjustTotalHeight(Destination.Parent, Node.TotalHeight, True); + Inc(FVisibleCount, CountVisibleChildren(Node) + Cardinal(IfThen(IsEffectivelyVisible[Node], 1))); end; end; amAddChildFirst: @@ -22160,13 +22217,10 @@ begin Include(Destination.States, vsHasChildren); AdjustTotalCount(Destination, Node.TotalCount, True); // Add the new node's height only if its parent is expanded. - if (vsExpanded in Destination.States) and IsEffectivelyVisible[Node] then - AdjustTotalHeight(Destination, Node.TotalHeight, True); if FullyVisible[Node] then begin - Inc(FVisibleCount, CountVisibleChildren(Node)); - if not IsEffectivelyFiltered[Node] then - Inc(FVisibleCount); + AdjustTotalHeight(Destination, Node.TotalHeight, True); + Inc(FVisibleCount, CountVisibleChildren(Node) + Cardinal(IfThen(IsEffectivelyVisible[Node], 1))); end; end; amAddChildLast: @@ -22195,13 +22249,10 @@ begin Include(Destination.States, vsHasChildren); AdjustTotalCount(Destination, Node.TotalCount, True); // Add the new node's height only if its parent is expanded. - if (vsExpanded in Destination.States) and IsEffectivelyVisible[Node] then - AdjustTotalHeight(Destination, Node.TotalHeight, True); if FullyVisible[Node] then begin - Inc(FVisibleCount, CountVisibleChildren(Node)); - if not IsEffectivelyFiltered[Node] then - Inc(FVisibleCount); + AdjustTotalHeight(Destination, Node.TotalHeight, True); + Inc(FVisibleCount, CountVisibleChildren(Node) + Cardinal(IfThen(IsEffectivelyVisible[Node], 1))); end; end; else @@ -22276,7 +22327,7 @@ begin Node.States := Node.States - [vsChecking]; Parent := Node.Parent; Dec(Parent.ChildCount); - AdjustHeight := (vsExpanded in Parent.States) and IsEffectivelyVisible[Node]; + AdjustHeight := (vsExpanded in Parent.States) and (vsVisible in Node.States); if Parent.ChildCount = 0 then begin Parent.States := Parent.States - [vsAllChildrenHidden, vsHasChildren]; @@ -22287,11 +22338,7 @@ begin if AdjustHeight then AdjustTotalHeight(Parent, -Integer(Node.TotalHeight), True); if FullyVisible[Node] then - begin - Dec(FVisibleCount, CountVisibleChildren(Node)); - if not IsEffectivelyFiltered[Node] then - Dec(FVisibleCount); - end; + Dec(FVisibleCount, CountVisibleChildren(Node) + Cardinal(IfThen(IsEffectivelyVisible[Node], 1))); if Assigned(Node.PrevSibling) then Node.PrevSibling.NextSibling := Node.NextSibling @@ -22407,6 +22454,7 @@ begin Inc(PtrUInt(FSelection[Index])); if Assigned(FOnRemoveFromSelection) then FOnRemoveFromSelection(Self, Node); + AdviseChangeEvent(False, Node, crIgnore); end; end; @@ -23624,6 +23672,8 @@ begin if FSelectionCount = 0 then ResetRangeAnchor; + if Assigned(FOnRemoveFromSelection) then + FOnRemoveFromSelection(Self, Node); Change(Node); end; end; @@ -24741,6 +24791,7 @@ begin Self.Visible := Visible; Self.SelectionCurveRadius := SelectionCurveRadius; Self.SelectionBlendFactor := SelectionBlendFactor; + Self.EmptyListMessage := EmptyListMessage; end else inherited; @@ -25712,9 +25763,9 @@ begin Result := Rect(0, 0, 0, 0); // Check whether the node is visible (determine indentation level btw.). - Temp := Node; - if not IsEffectivelyVisible[Temp] then + if not IsEffectivelyVisible[Node] then Exit; + Temp := Node; Indent := 0; while Temp <> FRoot do begin @@ -26829,6 +26880,13 @@ end; //---------------------------------------------------------------------------------------------------------------------- +function TBaseVirtualTree.GetNextChecked(Node: PVirtualNode; ConsiderChildrenAbove: Boolean): PVirtualNode; +begin + Result := Self.GetNextChecked(Node, csCheckedNormal, ConsiderChildrenAbove); +end; + +//---------------------------------------------------------------------------------------------------------------------- + function TBaseVirtualTree.GetNextCutCopy(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode; // Returns the next node in the tree which is currently marked for a clipboard operation. Since only visible nodes can @@ -29372,6 +29430,13 @@ begin NodeBitmap.Canvas.Unlock; NodeBitmap.Free; end; + if (Self.ChildCount[nil]=0) and (FEmptyListMessage<>'') then begin + // output a message if no items are to display + Canvas.Font := Self.Font; + SetBkMode(TargetCanvas.Handle, TRANSPARENT); + TextOut(TargetCanvas.Handle, 2, 2, PAnsiChar(FEmptyListMessage), Length(FEmptyListMessage)); + end;//if + DoAfterPaint(TargetCanvas); finally DoStateChange([], [tsPainting]); @@ -30293,27 +30358,7 @@ var TotalFit: Boolean; ToggleData: TToggleAnimationData; - //--------------- local functions ------------------------------------------- - - procedure UpdateRanges; - - // This function is used to adjust FRangeX/FRangeY in order to correctly - // reflect the tree's state after a toggle, because it is essential that - // these values are correct if we need to scroll afterwards. To avoid a - // useless call to UpdateScrollbars we do it right here. - - begin - if FRoot.TotalHeight < FDefaultNodeHeight then - FRoot.TotalHeight := FDefaultNodeHeight; - FRangeY := FRoot.TotalHeight - FRoot.NodeHeight + FBottomSpace; - - if FHeader.UseColumns then - FRangeX := FHeader.FColumns.TotalWidth - else - FRangeX := GetMaxRightExtend; - end; - - //--------------------------------------------------------------------------- + //--------------- local function -------------------------------------------- procedure PrepareAnimation; @@ -30362,7 +30407,7 @@ var end; end; - //--------------- end local functions --------------------------------------- + //--------------- end local function ---------------------------------------- begin Assert(Assigned(Node), 'Node must not be nil.'); @@ -30468,7 +30513,7 @@ begin end; // collapse the node - AdjustTotalHeight(Node, NodeHeight[Node]); + AdjustTotalHeight(Node, IfThen(IsEffectivelyFiltered[Node], 0, NodeHeight[Node])); if FullyVisible[Node] then Dec(FVisibleCount, CountVisibleChildren(Node)); Exclude(Node.States, vsExpanded); @@ -30760,16 +30805,24 @@ end; //---------------------------------------------------------------------------------------------------------------------- -procedure TBaseVirtualTree.UpdateHorizontalScrollBar(DoRepaint: Boolean); - -var - ScrollInfo: TScrollInfo; +procedure TBaseVirtualTree.UpdateHorizontalRange; begin if FHeader.UseColumns then FRangeX := FHeader.FColumns.TotalWidth else FRangeX := GetMaxRightExtend; +end; + +//---------------------------------------------------------------------------------------------------------------------- + +procedure TBaseVirtualTree.UpdateHorizontalScrollBar(DoRepaint: Boolean); + +var + ScrollInfo: TScrollInfo; + +begin + UpdateHorizontalRange; if tsUpdating in FStates then exit; @@ -30847,6 +30900,15 @@ end; //---------------------------------------------------------------------------------------------------------------------- +procedure TBaseVirtualTree.UpdateRanges; + +begin + UpdateVerticalRange; + UpdateHorizontalRange; +end; + +//---------------------------------------------------------------------------------------------------------------------- + procedure TBaseVirtualTree.UpdateScrollBars(DoRepaint: Boolean); // adjusts scrollbars to reflect current size and paint offset of the tree @@ -30861,16 +30923,24 @@ end; //---------------------------------------------------------------------------------------------------------------------- -procedure TBaseVirtualTree.UpdateVerticalScrollBar(DoRepaint: Boolean); - -var - ScrollInfo: TScrollInfo; +procedure TBaseVirtualTree.UpdateVerticalRange; begin // Total node height includes the height of the invisible root node. if FRoot.TotalHeight < FDefaultNodeHeight then FRoot.TotalHeight := FDefaultNodeHeight; FRangeY := FRoot.TotalHeight - FRoot.NodeHeight + FBottomSpace; +end; + +//---------------------------------------------------------------------------------------------------------------------- + +procedure TBaseVirtualTree.UpdateVerticalScrollBar(DoRepaint: Boolean); + +var + ScrollInfo: TScrollInfo; + +begin + UpdateVerticalRange; if tsUpdating in FStates then exit; @@ -31316,6 +31386,7 @@ begin FEdit.Show; FEdit.SelectAll; FEdit.SetFocus; + FEdit.AutoAdjustSize; end; end; @@ -31503,6 +31574,11 @@ begin Node := GetFirstVisible(nil, True); NextNodeProc := GetNextVisible; end; + tstChecked: + begin + Node := GetFirstChecked; + NextNodeProc := GetNextChecked; + end; else // tstAll Node := GetFirst; NextNodeProc := GetNext; @@ -32387,7 +32463,7 @@ function TCustomVirtualStringTree.ContentToHTML(Source: TVSTTextSourceType; cons // Renders the current tree content (depending on Source) as HTML text encoded in UTF-8. // If Caption is not empty then it is used to create and fill the header for the table built here. -// Based on ideas and code from Frank van den Bergh and Andreas H?rstemeier. +// Based on ideas and code from Frank van den Bergh and Andreas Hörstemeier. type UCS2 = Word; @@ -32704,7 +32780,7 @@ begin begin Buffer.Add('  '); + Buffer.Add('px" class="normalborder"> '); end else Buffer.Add('  '); @@ -32810,7 +32886,7 @@ end; function TCustomVirtualStringTree.ContentToRTF(Source: TVSTTextSourceType): AnsiString; // Renders the current tree content (depending on Source) as RTF (rich text). -// Based on ideas and code from Frank van den Bergh and Andreas H?rstemeier. +// Based on ideas and code from Frank van den Bergh and Andreas Hörstemeier. var Fonts: TStringList;