UPD: Operations viewer: Reordering operations within a queue.

This commit is contained in:
cobines 2012-03-21 05:45:05 +00:00
commit f9242e61df
2 changed files with 114 additions and 53 deletions

View file

@ -115,6 +115,7 @@ type
procedure tvOperationsMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
procedure tvOperationsSelectionChanged(Sender: TObject);
private
FDraggedOperation: TOperationHandle;
FMenuOperation: TOperationHandle;
function GetFocusedItem: TViewBaseItem;
procedure SetFocusItem(AOperationHandle: TOperationHandle);
@ -608,54 +609,53 @@ end;
procedure TfrmViewOperations.tvOperationsDragDrop(Sender, Source: TObject; X, Y: Integer);
var
SourceNode, TargetNode: TTreeNode;
TargetNode: TTreeNode;
NodeRect: TRect;
TargetItem: TViewBaseItem;
SourceItem: TViewOperationItem;
QueueItem: TViewQueueItem;
OperItem: TViewOperationItem;
SourceOpManItem, TargetOpManItem: TOperationsManagerItem;
TargetQueue: TOperationsManagerQueue;
TargetQueueId: TOperationsManagerQueueIdentifier;
HitTopPart: Boolean;
begin
SourceNode := tvOperations.Selected;
TargetNode := tvOperations.GetNodeAt(X, Y);
if not Assigned(TargetNode) then
TargetNode := tvOperations.Items.GetLastNode;
if (Source = tvOperations) and Assigned(SourceNode) and Assigned(TargetNode) then
if (Source = tvOperations) and Assigned(TargetNode) then
begin
SourceItem := TViewBaseItem(SourceNode.Data) as TViewOperationItem;
SourceOpManItem := OperationsManager.GetItemByHandle(SourceItem.FOperationHandle);
SourceOpManItem := OperationsManager.GetItemByHandle(FDraggedOperation);
if Assigned(SourceOpManItem) then
begin
NodeRect := TargetNode.DisplayRect(False);
TargetItem := TViewBaseItem(TargetNode.Data);
HitTopPart := Y - NodeRect.Top < (NodeRect.Bottom - NodeRect.Top) div 2;
HitTopPart := Y - NodeRect.Bottom < (NodeRect.Bottom - NodeRect.Top) div 2;
if HitTopPart and
(SourceNode = tvOperations.Items.GetFirstNode) and
(TargetItem is TViewQueueItem) and
(TViewQueueItem(TargetItem).FQueueIdentifier <> FreeOperationsQueueId) then
if TargetItem is TViewQueueItem then
begin
TargetQueue := OperationsManager.QueueByIdentifier[FreeOperationsQueueId];
SourceOpManItem.SetQueue(TargetQueue);
end
else if TargetItem is TViewQueueItem then
begin
TargetQueue := OperationsManager.QueueByIdentifier[TViewQueueItem(TargetItem).FQueueIdentifier];
SourceOpManItem.SetQueue(TargetQueue);
end
else if TargetItem is TViewOperationItem then
begin
TargetOpManItem := OperationsManager.GetItemByHandle(TViewOperationItem(TargetItem).FOperationHandle);
if Assigned(TargetOpManItem) then
QueueItem := TViewQueueItem(TargetItem);
if HitTopPart and
(TargetNode = tvOperations.Items.GetFirstNode) and
(QueueItem.FQueueIdentifier <> FreeOperationsQueueId) then
begin
TargetQueue := TargetOpManItem.Queue;
{if HitTopPart then
AttachMode := naInsert
else
AttachMode := naInsertBehind;}
SourceOpManItem.SetQueue(TargetQueue);
// There are no free operations and item was dropped at the top of the list
// on some queue. Create a free operations queue and move to it.
TargetQueueId := FreeOperationsQueueId;
end
else
begin
TargetQueueId := QueueItem.FQueueIdentifier;
end;
TargetQueue := OperationsManager.QueueByIdentifier[TargetQueueId];
SourceOpManItem.SetQueue(TargetQueue);
end
else if (TargetItem is TViewOperationItem) and
(FDraggedOperation <> TViewOperationItem(TargetItem).FOperationHandle) then
begin
OperItem := TViewOperationItem(TargetItem);
TargetOpManItem := OperationsManager.GetItemByHandle(OperItem.FOperationHandle);
if Assigned(TargetOpManItem) then
SourceOpManItem.Move(TargetOpManItem.Handle, HitTopPart);
end;
end;
end;
@ -671,11 +671,14 @@ var
Node: TTreeNode;
NodeRect: TRect;
begin
FDraggedOperation := InvalidOperationHandle;
Node := tvOperations.GetNodeAt(X, Y);
if Assigned(Node) then
begin
NodeRect := Node.DisplayRect(False);
TViewBaseItem(Node.Data).Click(Point(X - NodeRect.Left, Y - NodeRect.Top), Button, Shift);
if TViewBaseItem(Node.Data) is TViewOperationItem then
FDraggedOperation := TViewOperationItem(Node.Data).FOperationHandle;
end;
end;

View file

@ -37,6 +37,18 @@ type
AThread: TOperationThread);
destructor Destroy; override;
{en
Moves the item and places it before or after another operation.
@param(TargetOperation
Handle to another operation where item should be moved.
If handle belongs to operation from a different queue then
the item is moved to that queue and placed before or after the operation.)
@param(PlaceBefore
If @true then places item before TargetOperation.
If @false then places item after TargetOperation.)
}
procedure Move(TargetOperation: TOperationHandle; PlaceBefore: Boolean);
procedure MoveToBottom;
procedure SetQueue(NewQueue: TOperationsManagerQueue; InsertAtFront: Boolean = False);
property Handle: TOperationHandle read FHandle;
@ -52,6 +64,7 @@ type
strict private
FList: TFPList;
FIdentifier: TOperationsManagerQueueIdentifier;
function GetIndexByHandle(Handle: TOperationHandle): Integer;
function GetItem(Index: Integer): TOperationsManagerItem;
function GetItemByHandle(Handle: TOperationHandle): TOperationsManagerItem;
function GetOperationsCount: Integer;
@ -73,6 +86,19 @@ type
if @false then inserts at the back.)
}
function Insert(Item: TOperationsManagerItem; InsertAtFront: Boolean): Integer;
{en
Moves item within the queue.
@param(SourceItem
Which item should be moved.)
@param(TargetItem
SourceItem is moved placed either before or after TargetItem.
If TargetItem is @nil then SourceItem is moved to the back
of the queue, regardless of PlaceBefore parameter.)
@param(PlaceBefore
If @true then SourceItem is placed before TargetItem.
If @false then SourceItem is placed after TargetItem.)
}
procedure Move(SourceItem, TargetItem: TOperationsManagerItem; PlaceBefore: Boolean);
function Remove(Item: TOperationsManagerItem): Boolean;
public
constructor Create(AIdentifier: TOperationsManagerQueueIdentifier);
@ -157,14 +183,6 @@ type
function GetItemByHandle(Handle: TOperationHandle): TOperationsManagerItem;
function GetOrCreateQueue(Identifier: TOperationsManagerQueueIdentifier): TOperationsManagerQueue;
{en
Changes the Item's (and thus operation's) position in the list.
It is used to change the order of execution of queued operations.
@param(FromIndex is an index in the operations list of the Item that should be moved.)
@param(ToIndex is an index in the operations list where the Item should be moved to.)
}
procedure MoveOperation(FromIndex: Integer; ToIndex: Integer);
procedure CancelAll;
procedure PauseRunning;
procedure StartRunning;
@ -214,6 +232,23 @@ begin
FOperation.Free;
end;
procedure TOperationsManagerItem.Move(TargetOperation: TOperationHandle; PlaceBefore: Boolean);
var
TargetItem: TOperationsManagerItem;
begin
TargetItem := OperationsManager.GetItemByHandle(TargetOperation);
if Assigned(TargetItem) then
begin
SetQueue(TargetItem.Queue);
TargetItem.Queue.Move(Self, TargetItem, PlaceBefore);
end;
end;
procedure TOperationsManagerItem.MoveToBottom;
begin
Queue.Move(Self, nil, False);
end;
procedure TOperationsManagerItem.SetQueue(NewQueue: TOperationsManagerQueue; InsertAtFront: Boolean);
begin
if (Queue <> NewQueue) and Assigned(NewQueue) then
@ -228,6 +263,16 @@ end;
{ TOperationsManagerQueue }
function TOperationsManagerQueue.GetIndexByHandle(Handle: TOperationHandle): Integer;
begin
for Result := 0 to Count - 1 do
begin
if TOperationsManagerItem(Items[Result]).Handle = Handle then
Exit;
end;
Result := -1;
end;
function TOperationsManagerQueue.GetItem(Index: Integer): TOperationsManagerItem;
begin
Result := TOperationsManagerItem(FList.Items[Index]);
@ -287,6 +332,36 @@ begin
FList.Free;
end;
procedure TOperationsManagerQueue.Move(SourceItem, TargetItem: TOperationsManagerItem; PlaceBefore: Boolean);
var
FromIndex, ToIndex: Integer;
begin
FromIndex := GetIndexByHandle(SourceItem.Handle);
if FromIndex >= 0 then
begin
if not Assigned(TargetItem) then
FList.Move(FromIndex, FList.Count - 1)
else
begin
ToIndex := GetIndexByHandle(TargetItem.Handle);
if ToIndex >= 0 then
begin
if PlaceBefore then
begin
if FromIndex < ToIndex then
Dec(ToIndex);
end
else
begin
if FromIndex > ToIndex then
Inc(ToIndex);
end;
FList.Move(FromIndex, ToIndex);
end;
end;
end;
end;
function TOperationsManagerQueue.Insert(Item: TOperationsManagerItem; InsertAt: Integer): Integer;
begin
if InsertAt = -1 then
@ -580,23 +655,6 @@ begin
NotifyEvents(Item.Operation, [omevOperationStarted]);
end;
procedure TOperationsManager.MoveOperation(FromIndex: Integer; ToIndex: Integer);
var
Item: TOperationsManagerItem = nil;
begin
{
if (FromIndex >= 0) and (FromIndex < FOperations.Count) and
(ToIndex >= 0) and (ToIndex < FOperations.Count) then
begin
Item := TOperationsManagerItem(FOperations.Items[FromIndex]);
// This has to be in exactly this order: first delete then insert.
FOperations.Delete(FromIndex);
FOperations.Insert(ToIndex, Item);
end;
}
end;
procedure TOperationsManager.CancelAll;
var
Item: TOperationsManagerItem;