You've already forked lazarus-ccr
* (4.8 branch) Synchronize with main svn up to version 206
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@1134 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -27,6 +27,10 @@ unit VirtualTrees;
|
|||||||
// (C) 1999-2001 digital publishing AG. All Rights Reserved.
|
// (C) 1999-2001 digital publishing AG. All Rights Reserved.
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
|
// July 2009
|
||||||
|
// - Bug fix: TWorkerThread will no longer reference the tree after it has been destroyed (Mantis issue #384)
|
||||||
|
// - Bug fix: TBaseVirtualTree.InternalConnectNode checked the expanded state of the wrong node if Mode was
|
||||||
|
// amAddChildFirst or amAddChildLast
|
||||||
// June 2009
|
// June 2009
|
||||||
// - Bug fix: fixed some issues concerning the vista theme handling
|
// - Bug fix: fixed some issues concerning the vista theme handling
|
||||||
// - Improvement: removed hidden node handling in this branch
|
// - Improvement: removed hidden node handling in this branch
|
||||||
@ -4008,6 +4012,7 @@ type
|
|||||||
FWaiterList: TThreadList;
|
FWaiterList: TThreadList;
|
||||||
FRefCount: Cardinal;
|
FRefCount: Cardinal;
|
||||||
protected
|
protected
|
||||||
|
procedure CancelValidation(Tree: TBaseVirtualTree);
|
||||||
procedure ChangeTreeStates(EnterStates, LeaveStates: TChangeStates);
|
procedure ChangeTreeStates(EnterStates, LeaveStates: TChangeStates);
|
||||||
procedure Execute; override;
|
procedure Execute; override;
|
||||||
public
|
public
|
||||||
@ -4987,6 +4992,10 @@ begin
|
|||||||
// Make sure there is no reference remaining to the releasing tree.
|
// Make sure there is no reference remaining to the releasing tree.
|
||||||
Tree.InterruptValidation;
|
Tree.InterruptValidation;
|
||||||
|
|
||||||
|
// Borland change (used to debug shutdown issue with dangling FCurrentTree reference)
|
||||||
|
Assert(WorkerThread.FCurrentTree <> Tree, 'WorkerThread.FCurrentTree dangling reference!');
|
||||||
|
|
||||||
|
|
||||||
if WorkerThread.FRefCount = 0 then
|
if WorkerThread.FRefCount = 0 then
|
||||||
begin
|
begin
|
||||||
with WorkerThread do
|
with WorkerThread do
|
||||||
@ -5036,6 +5045,26 @@ end;
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
procedure TWorkerThread.CancelValidation(Tree: TBaseVirtualTree);
|
||||||
|
|
||||||
|
var
|
||||||
|
Msg: TMsg;
|
||||||
|
|
||||||
|
begin
|
||||||
|
// Wait for any references to this tree to be released.
|
||||||
|
// Pump WM_CHANGESTATE messages so the thread doesn't block on SendMessage calls.
|
||||||
|
while FCurrentTree = Tree do
|
||||||
|
begin
|
||||||
|
if Tree.HandleAllocated and PeekMessage(Msg, Tree.Handle, WM_CHANGESTATE, WM_CHANGESTATE, PM_REMOVE) then
|
||||||
|
begin
|
||||||
|
TranslateMessage(Msg);
|
||||||
|
DispatchMessage(Msg);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
procedure TWorkerThread.ChangeTreeStates(EnterStates, LeaveStates: TChangeStates);
|
procedure TWorkerThread.ChangeTreeStates(EnterStates, LeaveStates: TChangeStates);
|
||||||
|
|
||||||
begin
|
begin
|
||||||
@ -5078,14 +5107,14 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
// Something to do?
|
// Something to do?
|
||||||
try
|
|
||||||
if Assigned(FCurrentTree) then
|
if Assigned(FCurrentTree) then
|
||||||
begin
|
begin
|
||||||
|
try
|
||||||
ChangeTreeStates([csValidating], [csUseCache]);
|
ChangeTreeStates([csValidating], [csUseCache]);
|
||||||
EnterStates := [];
|
EnterStates := [];
|
||||||
if not (tsStopValidation in FCurrentTree.FStates) and FCurrentTree.DoValidateCache then
|
if not (tsStopValidation in FCurrentTree.FStates) and FCurrentTree.DoValidateCache then
|
||||||
EnterStates := [csUseCache];
|
EnterStates := [csUseCache];
|
||||||
end;
|
|
||||||
finally
|
finally
|
||||||
LeaveStates := [csValidating, csStopValidation];
|
LeaveStates := [csValidating, csStopValidation];
|
||||||
if csUseCache in EnterStates then
|
if csUseCache in EnterStates then
|
||||||
@ -5096,6 +5125,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -5113,6 +5143,7 @@ begin
|
|||||||
finally
|
finally
|
||||||
FWaiterList.UnlockList;
|
FWaiterList.UnlockList;
|
||||||
end;
|
end;
|
||||||
|
CancelValidation(Tree);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
@ -12900,10 +12931,8 @@ end;
|
|||||||
|
|
||||||
procedure TBaseVirtualTree.InterruptValidation;
|
procedure TBaseVirtualTree.InterruptValidation;
|
||||||
|
|
||||||
// Waits until the worker thread has stopped validating the caches of this tree.
|
var
|
||||||
|
WasValidating: Boolean;
|
||||||
//var
|
|
||||||
// Msg: TMsg;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
DoStateChange([tsStopValidation], [tsUseCache]);
|
DoStateChange([tsStopValidation], [tsUseCache]);
|
||||||
@ -12911,35 +12940,13 @@ begin
|
|||||||
// Check the worker thread existance. It might already be gone (usually on destruction of the last tree).
|
// Check the worker thread existance. It might already be gone (usually on destruction of the last tree).
|
||||||
if Assigned(WorkerThread) then
|
if Assigned(WorkerThread) then
|
||||||
begin
|
begin
|
||||||
if tsValidating in FStates then
|
WasValidating := (tsValidating in FStates);
|
||||||
begin
|
|
||||||
// Do a hard break until the worker thread has stopped validation.
|
|
||||||
while (tsValidating in FStates) and (WorkerThread.CurrentTree = Self) and not Application.Terminated do
|
|
||||||
begin
|
|
||||||
// Pump our own messages to avoid a deadlock.
|
|
||||||
//todo_lcl_check
|
|
||||||
Application.ProcessMessages;
|
|
||||||
{
|
|
||||||
if PeekMessage(Msg, Handle, 0, 0, PM_REMOVE) then
|
|
||||||
begin
|
|
||||||
if Msg.message = WM_QUIT then
|
|
||||||
begin
|
|
||||||
PostQuitMessage(Msg.WParam);
|
|
||||||
Break;
|
|
||||||
end;
|
|
||||||
TranslateMessage(Msg);
|
|
||||||
DispatchMessage(Msg);
|
|
||||||
end;
|
|
||||||
}
|
|
||||||
end;
|
|
||||||
DoStateChange([tsValidationNeeded]);
|
|
||||||
end
|
|
||||||
else // Remove any pending validation.
|
|
||||||
WorkerThread.RemoveTree(Self);
|
WorkerThread.RemoveTree(Self);
|
||||||
|
if WasValidating then
|
||||||
|
DoStateChange([tsValidationNeeded]);
|
||||||
end;
|
end;
|
||||||
{$endif}
|
{$endif}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
function TBaseVirtualTree.IsFirstVisibleChild(Parent, Node: PVirtualNode): Boolean;
|
function TBaseVirtualTree.IsFirstVisibleChild(Parent, Node: PVirtualNode): Boolean;
|
||||||
@ -21505,7 +21512,7 @@ begin
|
|||||||
Include(Destination.States, vsHasChildren);
|
Include(Destination.States, vsHasChildren);
|
||||||
AdjustTotalCount(Destination, Node.TotalCount, True);
|
AdjustTotalCount(Destination, Node.TotalCount, True);
|
||||||
// Add the new node's height only if its parent is expanded.
|
// Add the new node's height only if its parent is expanded.
|
||||||
if Destination.Parent.States * [vsExpanded, vsVisible] = [vsExpanded, vsVisible] then
|
if Destination.States * [vsExpanded, vsVisible] = [vsExpanded, vsVisible] then
|
||||||
AdjustTotalHeight(Destination, Node.TotalHeight, True);
|
AdjustTotalHeight(Destination, Node.TotalHeight, True);
|
||||||
if FullyVisible[Node] then
|
if FullyVisible[Node] then
|
||||||
Inc(FVisibleCount, CountVisibleChildren(Node) + 1);
|
Inc(FVisibleCount, CountVisibleChildren(Node) + 1);
|
||||||
@ -21536,7 +21543,7 @@ begin
|
|||||||
Include(Destination.States, vsHasChildren);
|
Include(Destination.States, vsHasChildren);
|
||||||
AdjustTotalCount(Destination, Node.TotalCount, True);
|
AdjustTotalCount(Destination, Node.TotalCount, True);
|
||||||
// Add the new node's height only if its parent is expanded.
|
// Add the new node's height only if its parent is expanded.
|
||||||
if Destination.Parent.States * [vsExpanded, vsVisible] = [vsExpanded, vsVisible] then
|
if Destination.States * [vsExpanded, vsVisible] = [vsExpanded, vsVisible] then
|
||||||
AdjustTotalHeight(Destination, Node.TotalHeight, True);
|
AdjustTotalHeight(Destination, Node.TotalHeight, True);
|
||||||
if FullyVisible[Node] then
|
if FullyVisible[Node] then
|
||||||
Inc(FVisibleCount, CountVisibleChildren(Node) + 1);
|
Inc(FVisibleCount, CountVisibleChildren(Node) + 1);
|
||||||
|
Reference in New Issue
Block a user