mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
1210 lines
36 KiB
ObjectPascal
1210 lines
36 KiB
ObjectPascal
unit fViewOperations;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, Forms, Controls, Graphics, StdCtrls, ExtCtrls, LCLType,
|
|
ComCtrls, Buttons, LCLIntf, Menus, uFileSourceOperation, uOperationsManager,
|
|
Themes;
|
|
|
|
type
|
|
|
|
TViewBaseItem = class;
|
|
TViewBaseItemClick = procedure(Item: TViewBaseItem; Button: TMouseButton; Shift: TShiftState; const Pt: TPoint) of object;
|
|
TViewBaseItemContextMenu = procedure(Item: TViewBaseItem; const Point: TPoint) of object;
|
|
TViewBaseItemSelected = procedure(Item: TViewBaseItem) of object;
|
|
|
|
TViewOperationsStatusIcon = (vosiPlay, vosiPause, vosiHourglass);
|
|
|
|
{ TViewBaseItem }
|
|
|
|
TViewBaseItem = class
|
|
private
|
|
FOnClick: TViewBaseItemClick;
|
|
FOnContextMenu: TViewBaseItemContextMenu;
|
|
FOnSelected: TViewBaseItemSelected;
|
|
FTreeNode: TTreeNode;
|
|
FText: String;
|
|
FTextRect: TRect;
|
|
procedure CalculateSizes(Canvas: TCanvas; NeedsStatusIcon, NeedsProgress: Boolean);
|
|
procedure DrawProgress(Canvas: TCanvas; NodeRect: TRect; Progress: Double);
|
|
procedure DrawStatusIcon(Canvas: TCanvas; NodeRect: TRect; Icon: TViewOperationsStatusIcon);
|
|
procedure DrawThemedBackground(Canvas: TCanvas; Element: TThemedTreeview; ARect: TRect);
|
|
procedure DrawThemedText(Canvas: TCanvas; Element: TThemedTreeview; NodeRect: TRect; Center: Boolean; AText: String);
|
|
function GetStatusIconRect(NodeRect: TRect): TRect;
|
|
function GetTextIndent: Integer; virtual; abstract;
|
|
procedure UpdateView(Canvas: TCanvas); virtual; abstract;
|
|
public
|
|
constructor Create(ANode: TTreeNode); virtual;
|
|
procedure Click(const Pt: TPoint; Button: TMouseButton; Shift: TShiftState); virtual;
|
|
procedure Draw(Canvas: TCanvas; NodeRect: TRect); virtual; abstract;
|
|
function GetBackgroundColor: TColor; virtual; abstract;
|
|
procedure KeyDown(var Key: Word; Shift: TShiftState); virtual;
|
|
procedure Selected; virtual;
|
|
procedure StartPause; virtual; abstract;
|
|
procedure Stop; virtual; abstract;
|
|
property OnClick: TViewBaseItemClick read FOnClick write FOnClick;
|
|
property OnContextMenu: TViewBaseItemContextMenu read FOnContextMenu write FOnContextMenu;
|
|
property OnSelected: TViewBaseItemSelected read FOnSelected write FOnSelected;
|
|
end;
|
|
|
|
{ TViewQueueItem }
|
|
|
|
TViewQueueItem = class(TViewBaseItem)
|
|
private
|
|
FQueueIdentifier: TOperationsManagerQueueIdentifier;
|
|
function GetTextIndent: Integer; override;
|
|
procedure UpdateView(Canvas: TCanvas); override;
|
|
public
|
|
constructor Create(ANode: TTreeNode; AQueueId: TOperationsManagerQueueIdentifier); reintroduce;
|
|
procedure Click(const Pt: TPoint; Button: TMouseButton; Shift: TShiftState); override;
|
|
procedure Draw(Canvas: TCanvas; NodeRect: TRect); override;
|
|
function GetBackgroundColor: TColor; override;
|
|
procedure StartPause; override;
|
|
procedure Stop; override;
|
|
end;
|
|
|
|
TViewOperationItem = class;
|
|
|
|
{ TViewOperationItem }
|
|
|
|
TViewOperationItem = class(TViewBaseItem)
|
|
private
|
|
FOperationHandle: TOperationHandle;
|
|
FProgress: Double;
|
|
function GetTextIndent: Integer; override;
|
|
procedure UpdateView(Canvas: TCanvas); override;
|
|
public
|
|
constructor Create(ANode: TTreeNode; AOperationHandle: TOperationHandle); reintroduce;
|
|
procedure Click(const Pt: TPoint; Button: TMouseButton; Shift: TShiftState); override;
|
|
procedure Draw(Canvas: TCanvas; NodeRect: TRect); override;
|
|
function GetBackgroundColor: TColor; override;
|
|
procedure StartPause; override;
|
|
procedure Stop; override;
|
|
end;
|
|
|
|
{ TfrmViewOperations }
|
|
|
|
TfrmViewOperations = class(TForm)
|
|
btnStop: TBitBtn;
|
|
btnStartPause: TBitBtn;
|
|
cbAlwaysOnTop: TCheckBox;
|
|
lblUseDragDrop: TLabel;
|
|
mnuCancelQueue: TMenuItem;
|
|
mnuNewQueue: TMenuItem;
|
|
mnuCancelOperation: TMenuItem;
|
|
mnuPutFirstInQueue: TMenuItem;
|
|
mnuPutLastInQueue: TMenuItem;
|
|
mnuOperationShowDetached: TMenuItem;
|
|
mnuQueue2: TMenuItem;
|
|
mnuQueue3: TMenuItem;
|
|
mnuQueue5: TMenuItem;
|
|
mnuQueue4: TMenuItem;
|
|
mnuQueue1: TMenuItem;
|
|
mnuQueue0: TMenuItem;
|
|
mnuQueue: TMenuItem;
|
|
mnuQueueShowDetached: TMenuItem;
|
|
pnlHeader: TPanel;
|
|
pmQueuePopup: TPopupMenu;
|
|
pnlTopHeader: TPanel;
|
|
pmOperationPopup: TPopupMenu;
|
|
tbPauseAll: TToggleBox;
|
|
tvOperations: TTreeView;
|
|
UpdateTimer: TTimer;
|
|
|
|
procedure btnStopClick(Sender: TObject);
|
|
procedure cbAlwaysOnTopChange(Sender: TObject);
|
|
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
|
|
procedure FormCreate(Sender: TObject);
|
|
procedure FormDestroy(Sender: TObject);
|
|
procedure mnuCancelOperationClick(Sender: TObject);
|
|
procedure mnuCancelQueueClick(Sender: TObject);
|
|
procedure mnuNewQueueClick(Sender: TObject);
|
|
procedure mnuPutFirstInQueueClick(Sender: TObject);
|
|
procedure mnuPutLastInQueueClick(Sender: TObject);
|
|
procedure mnuOperationShowDetachedClick(Sender: TObject);
|
|
procedure mnuQueueShowDetachedClick(Sender: TObject);
|
|
procedure OnOperationItemContextMenu(Item: TViewBaseItem; const Point: TPoint);
|
|
procedure OnOperationItemSelected(Item: TViewBaseItem);
|
|
procedure OnQueueContextMenu(Item: TViewBaseItem; const Point: TPoint);
|
|
procedure OnQueueItemSelected(Item: TViewBaseItem);
|
|
procedure OnUpdateTimer(Sender: TObject);
|
|
procedure btnStartPauseClick(Sender: TObject);
|
|
procedure mnuQueueNumberClick(Sender: TObject);
|
|
procedure tbPauseAllChange(Sender: TObject);
|
|
procedure tvOperationsCustomDrawItem(Sender: TCustomTreeView; Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
|
|
procedure tvOperationsDeletion(Sender: TObject; Node: TTreeNode);
|
|
procedure tvOperationsDragDrop(Sender, Source: TObject; X, Y: Integer);
|
|
procedure tvOperationsDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
|
|
procedure tvOperationsKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
|
|
procedure tvOperationsMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
|
procedure tvOperationsResize(Sender: TObject);
|
|
procedure tvOperationsSelectionChanged(Sender: TObject);
|
|
private
|
|
FDraggedOperation: TOperationHandle;
|
|
FMenuOperation: TOperationHandle;
|
|
FMenuQueueIdentifier: TOperationsManagerQueueIdentifier;
|
|
procedure CreateNodes;
|
|
function GetFocusedItem: TViewBaseItem;
|
|
procedure MoveWithinQueue(MoveToTop: Boolean);
|
|
procedure SetFocusItem(AOperationHandle: TOperationHandle);
|
|
procedure SetFocusItem(AQueueIdentifier: TOperationsManagerQueueIdentifier);
|
|
procedure SetNewQueue(Item: TViewOperationItem; NewQueue: TOperationsManagerQueueIdentifier);
|
|
procedure SetStartPauseCaption(SetPause: Boolean);
|
|
procedure UpdateView(Item: TOperationsManagerItem; Event: TOperationManagerEvent);
|
|
procedure UpdateSizes;
|
|
end;
|
|
|
|
procedure ShowOperationsViewer;
|
|
procedure ShowOperationsViewer(AOperationHandle: TOperationHandle);
|
|
procedure ShowOperationsViewer(AQueueIdentifier: TOperationsManagerQueueIdentifier);
|
|
|
|
implementation
|
|
|
|
{$R *.lfm}
|
|
|
|
uses
|
|
GraphMath, GraphType, Math,
|
|
fFileOpDlg, uLng, uGlobs, uFileSourceOperationMisc;
|
|
|
|
const
|
|
ExpandSignSize = 9;
|
|
StatusIconPlay: array[0..2] of TPoint =
|
|
((x: 5; y: 1), (x: 13; y: 9), (x: 5; y: 17));
|
|
StatusIconPause1: array[0..3] of TPoint =
|
|
((x: 3; y: 2), (x: 3; y: 16), (x: 7; y: 16), (x: 7; y: 2));
|
|
StatusIconPause2: array[0..3] of TPoint =
|
|
((x: 10; y: 2), (x: 10; y: 16), (x: 14; y: 16), (x: 14; y: 2));
|
|
StatusIconHourglass1: array[0..2] of TPoint =
|
|
((x: 3; y: 4), (x: 13; y: 4), (x: 8; y: 10));
|
|
StatusIconHourglass2: array[0..2] of TPoint =
|
|
((x: 8; y: 10), (x: 13; y: 15), (x: 3; y: 15));
|
|
StatusIconFrame: TRect = (Left: 0; Top: 0; Right: 18; Bottom: 19);
|
|
StatusIconRightMargin = 5;
|
|
ProgressHeight = 16;
|
|
ProgressWidth = 150;
|
|
ProgressHorizontalMargin = 5;
|
|
FreeOperationTextIndent = 3;
|
|
MarginTopBottom = 2;
|
|
|
|
var
|
|
frmViewOperations: TfrmViewOperations = nil;
|
|
ProgressRight: Integer;
|
|
|
|
procedure ShowOperationsViewer;
|
|
begin
|
|
if not Assigned(frmViewOperations) then
|
|
frmViewOperations := TfrmViewOperations.Create(Application);
|
|
frmViewOperations.ShowOnTop;
|
|
end;
|
|
|
|
procedure ShowOperationsViewer(AOperationHandle: TOperationHandle);
|
|
begin
|
|
ShowOperationsViewer;
|
|
if AOperationHandle <> InvalidOperationHandle then
|
|
frmViewOperations.SetFocusItem(AOperationHandle);
|
|
end;
|
|
|
|
procedure ShowOperationsViewer(AQueueIdentifier: TOperationsManagerQueueIdentifier);
|
|
begin
|
|
ShowOperationsViewer;
|
|
frmViewOperations.SetFocusItem(AQueueIdentifier);
|
|
end;
|
|
|
|
procedure ApplyProgress(var ARect: TRect; Progress: Double);
|
|
begin
|
|
ARect.Right := ARect.Left + Round((ARect.Right - ARect.Left) * Progress);
|
|
end;
|
|
|
|
function MoveRect(aRect: TRect; DeltaX, DeltaY: Integer): TRect;
|
|
begin
|
|
Result.Left := aRect.Left + DeltaX;
|
|
Result.Right := aRect.Right + DeltaX;
|
|
Result.Top := aRect.Top + DeltaY;
|
|
Result.Bottom := aRect.Bottom + DeltaY;
|
|
end;
|
|
|
|
procedure DrawMovePolygon(Canvas: TCanvas; const Points: array of TPoint; DeltaX, DeltaY: Integer);
|
|
var
|
|
CopyPoints: PPoint;
|
|
i: Integer;
|
|
begin
|
|
CopyPoints := GetMem(SizeOf(TPoint) * Length(Points));
|
|
for i := 0 to Length(Points) - 1 do
|
|
begin
|
|
CopyPoints[i].x := Points[i].x + DeltaX;
|
|
CopyPoints[i].y := Points[i].y + DeltaY;
|
|
end;
|
|
Canvas.Polygon(CopyPoints, Length(Points), True);
|
|
FreeMem(CopyPoints);
|
|
end;
|
|
|
|
{ TViewBaseItem }
|
|
|
|
procedure TViewBaseItem.DrawThemedBackground(Canvas: TCanvas; Element: TThemedTreeview; ARect: TRect);
|
|
var
|
|
Details: TThemedElementDetails;
|
|
begin
|
|
Details := ThemeServices.GetElementDetails(Element);
|
|
if ThemeServices.HasTransparentParts(Details) then
|
|
begin
|
|
Canvas.Brush.Color := GetBackgroundColor;
|
|
Canvas.FillRect(ARect);
|
|
end;
|
|
ThemeServices.DrawElement(Canvas.Handle, Details, ARect, nil);
|
|
end;
|
|
|
|
procedure TViewBaseItem.DrawProgress(Canvas: TCanvas; NodeRect: TRect; Progress: Double);
|
|
var
|
|
Details: TThemedElementDetails;
|
|
begin
|
|
if Progress > 0 then
|
|
begin
|
|
NodeRect.Right := NodeRect.Right - ProgressRight;
|
|
NodeRect.Left := NodeRect.Right - ProgressWidth;
|
|
NodeRect.Top := NodeRect.Top + (NodeRect.Bottom - NodeRect.Top - ProgressHeight) div 2;
|
|
NodeRect.Bottom := NodeRect.Top + ProgressHeight;
|
|
|
|
if ThemeServices.ThemesEnabled then
|
|
begin
|
|
Details := ThemeServices.GetElementDetails(tpBar);
|
|
ThemeServices.DrawElement(Canvas.Handle, Details, NodeRect, nil);
|
|
Details := ThemeServices.GetElementDetails(tpChunk);
|
|
InflateRect(NodeRect, -2, -2);
|
|
ApplyProgress(NodeRect, Progress);
|
|
ThemeServices.DrawElement(Canvas.Handle, Details, NodeRect, nil);
|
|
end
|
|
else
|
|
begin
|
|
Canvas.Pen.Color := clWindowText;
|
|
Canvas.Brush.Color := clForm;
|
|
Canvas.RoundRect(NodeRect, 3, 3);
|
|
Canvas.Brush.Color := clHighlight;
|
|
ApplyProgress(NodeRect, Progress);
|
|
Canvas.RoundRect(NodeRect, 3, 3);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TViewBaseItem.DrawStatusIcon(Canvas: TCanvas; NodeRect: TRect; Icon: TViewOperationsStatusIcon);
|
|
var
|
|
IconRect: TRect;
|
|
begin
|
|
Canvas.Brush.Color := GetBackgroundColor;
|
|
Canvas.Pen.Color := clWindowText;
|
|
|
|
IconRect := MoveRect(GetStatusIconRect(NodeRect), NodeRect.Left, NodeRect.Top);
|
|
Canvas.Rectangle(IconRect);
|
|
|
|
case Icon of
|
|
vosiPlay: // Paint "Play" triangle
|
|
begin
|
|
Canvas.Brush.Color := RGBToColor(0, 200, 0);
|
|
DrawMovePolygon(Canvas, StatusIconPlay, IconRect.Left, IconRect.Top);
|
|
end;
|
|
vosiPause: // Paint "Pause" double line
|
|
begin
|
|
Canvas.Brush.Color := RGBToColor(0, 0, 200);
|
|
DrawMovePolygon(Canvas, StatusIconPause1, IconRect.Left, IconRect.Top);
|
|
DrawMovePolygon(Canvas, StatusIconPause2, IconRect.Left, IconRect.Top);
|
|
end;
|
|
else // Paint "Hourglass"
|
|
begin
|
|
Canvas.Brush.Color := RGBToColor(255, 255, 255);
|
|
DrawMovePolygon(Canvas, StatusIconHourglass1, IconRect.Left, IconRect.Top);
|
|
DrawMovePolygon(Canvas, StatusIconHourglass2, IconRect.Left, IconRect.Top);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TViewBaseItem.DrawThemedText(Canvas: TCanvas; Element: TThemedTreeview; NodeRect: TRect; Center: Boolean; AText: String);
|
|
var
|
|
Details: TThemedElementDetails;
|
|
Flags: Cardinal = DT_WORDBREAK or DT_NOPREFIX;
|
|
begin
|
|
Details := ThemeServices.GetElementDetails(Element);
|
|
if Center then
|
|
Flags := Flags + DT_VCENTER;
|
|
ThemeServices.DrawText(Canvas, Details, AText, NodeRect, Flags, 0);
|
|
end;
|
|
|
|
function TViewBaseItem.GetStatusIconRect(NodeRect: TRect): TRect;
|
|
begin
|
|
Result := MoveRect(StatusIconFrame,
|
|
(NodeRect.Right - NodeRect.Left) - (StatusIconFrame.Right - StatusIconFrame.Left) - StatusIconRightMargin,
|
|
((NodeRect.Bottom - NodeRect.Top) - (StatusIconFrame.Bottom - StatusIconFrame.Top)) div 2);
|
|
end;
|
|
|
|
constructor TViewBaseItem.Create(ANode: TTreeNode);
|
|
begin
|
|
FTreeNode := ANode;
|
|
end;
|
|
|
|
procedure TViewBaseItem.CalculateSizes(Canvas: TCanvas; NeedsStatusIcon, NeedsProgress: Boolean);
|
|
var
|
|
NodeRect: TRect;
|
|
NeededHeight: Integer;
|
|
begin
|
|
// Calculate available width for text.
|
|
NodeRect := FTreeNode.DisplayRect(False);
|
|
FTextRect := Rect(0, 0, 0, 0);
|
|
FTextRect.Right := (NodeRect.Right - NodeRect.Left) - GetTextIndent -
|
|
(ProgressRight + ProgressWidth + ProgressHorizontalMargin);
|
|
|
|
// Calculate text height.
|
|
DrawText(Canvas.Handle, PChar(FText), Length(FText), FTextRect, DT_NOPREFIX + DT_CALCRECT + DT_WORDBREAK);
|
|
|
|
// Take max of text, progress and status icon.
|
|
NeededHeight := FTextRect.Bottom - FTextRect.Top;
|
|
if NeedsProgress then
|
|
NeededHeight := Max(NeededHeight, ProgressHeight);
|
|
if NeedsStatusIcon then
|
|
NeededHeight := Max(NeededHeight, StatusIconFrame.Bottom - StatusIconFrame.Top);
|
|
Inc(NeededHeight, 2 * MarginTopBottom);
|
|
|
|
FTextRect := MoveRect(FTextRect, NodeRect.Left + GetTextIndent, NodeRect.Top);
|
|
FTreeNode.Height := NeededHeight;
|
|
end;
|
|
|
|
procedure TViewBaseItem.Click(const Pt: TPoint; Button: TMouseButton; Shift: TShiftState);
|
|
var
|
|
Handled: Boolean = False;
|
|
begin
|
|
case Button of
|
|
mbRight:
|
|
if Assigned(FOnContextMenu) then
|
|
begin
|
|
OnContextMenu(Self, Pt);
|
|
Handled := True;
|
|
end;
|
|
end;
|
|
if not Handled and Assigned(FOnClick) then
|
|
FOnClick(Self, Button, Shift, Pt);
|
|
end;
|
|
|
|
procedure TViewBaseItem.KeyDown(var Key: Word; Shift: TShiftState);
|
|
var
|
|
Rect: TRect;
|
|
Point: TPoint;
|
|
begin
|
|
case Key of
|
|
VK_APPS:
|
|
if Assigned(FOnContextMenu) then
|
|
begin
|
|
Rect := FTreeNode.DisplayRect(False);
|
|
Point.x := Rect.Left + (Rect.Right - Rect.Left) div 2;
|
|
Point.y := Rect.Top + (Rect.Bottom - Rect.Top) div 2;
|
|
OnContextMenu(Self, Point);
|
|
Key := 0;
|
|
end;
|
|
VK_SPACE:
|
|
begin
|
|
StartPause;
|
|
Key := 0;
|
|
end;
|
|
VK_DELETE, VK_BACK:
|
|
begin
|
|
Stop;
|
|
Key := 0;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TViewBaseItem.Selected;
|
|
begin
|
|
if Assigned(FOnSelected) then
|
|
FOnSelected(Self);
|
|
end;
|
|
|
|
{ TViewOperationItem }
|
|
|
|
constructor TViewOperationItem.Create(ANode: TTreeNode; AOperationHandle: TOperationHandle);
|
|
begin
|
|
FOperationHandle := AOperationHandle;
|
|
inherited Create(ANode);
|
|
end;
|
|
|
|
procedure TViewOperationItem.Click(const Pt: TPoint; Button: TMouseButton; Shift: TShiftState);
|
|
var
|
|
Handled: Boolean = False;
|
|
OpManItem: TOperationsManagerItem;
|
|
NodeRect: TRect;
|
|
begin
|
|
OpManItem := OperationsManager.GetItemByHandle(FOperationHandle);
|
|
if Assigned(OpManItem) then
|
|
begin
|
|
case Button of
|
|
mbLeft:
|
|
if OpManItem.Queue.IsFree then
|
|
begin
|
|
NodeRect := FTreeNode.DisplayRect(False);
|
|
if ((ssDouble in Shift) or PtInRect(GetStatusIconRect(NodeRect), Pt)) then
|
|
begin
|
|
StartPause;
|
|
Handled := True;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
if not Handled then
|
|
inherited Click(Pt, Button, Shift);
|
|
end;
|
|
|
|
procedure TViewOperationItem.Draw(Canvas: TCanvas; NodeRect: TRect);
|
|
var
|
|
OpManItem: TOperationsManagerItem;
|
|
Element: TThemedTreeview;
|
|
Icon: TViewOperationsStatusIcon;
|
|
begin
|
|
if FTreeNode.Selected then
|
|
Element := ttItemSelected
|
|
else
|
|
Element := ttItemNormal;
|
|
|
|
DrawThemedBackground(Canvas, Element, NodeRect);
|
|
|
|
OpManItem := OperationsManager.GetItemByHandle(FOperationHandle);
|
|
if Assigned(OpManItem) then
|
|
begin
|
|
DrawThemedText(Canvas, Element, FTextRect, True, FText);
|
|
|
|
if OpManItem.Queue.IsFree then
|
|
begin
|
|
case OpManItem.Operation.State of
|
|
fsosRunning:
|
|
Icon := vosiPlay;
|
|
fsosPaused:
|
|
Icon := vosiPause;
|
|
else
|
|
Icon := vosiHourglass;
|
|
end;
|
|
DrawStatusIcon(Canvas, NodeRect, Icon);
|
|
end;
|
|
|
|
DrawProgress(Canvas, NodeRect, FProgress);
|
|
end;
|
|
end;
|
|
|
|
function TViewOperationItem.GetBackgroundColor: TColor;
|
|
begin
|
|
Result := FTreeNode.TreeView.BackgroundColor;
|
|
end;
|
|
|
|
procedure TViewOperationItem.StartPause;
|
|
var
|
|
OpManItem: TOperationsManagerItem;
|
|
begin
|
|
OpManItem := OperationsManager.GetItemByHandle(FOperationHandle);
|
|
if Assigned(OpManItem) and OpManItem.Queue.IsFree then
|
|
OpManItem.Operation.TogglePause;
|
|
end;
|
|
|
|
procedure TViewOperationItem.Stop;
|
|
var
|
|
OpManItem: TOperationsManagerItem;
|
|
begin
|
|
OpManItem := OperationsManager.GetItemByHandle(FOperationHandle);
|
|
if Assigned(OpManItem) then
|
|
OpManItem.Operation.Stop;
|
|
end;
|
|
|
|
procedure TViewOperationItem.UpdateView(Canvas: TCanvas);
|
|
var
|
|
OpManItem: TOperationsManagerItem;
|
|
begin
|
|
OpManItem := OperationsManager.GetItemByHandle(FOperationHandle);
|
|
if Assigned(OpManItem) then
|
|
begin
|
|
FText := IntToStr(OpManItem.Handle) + ': ' +
|
|
OpManItem.Operation.GetDescription(fsoddJobAndTarget);
|
|
FProgress := OpManItem.Operation.Progress;
|
|
if FProgress > 0 then
|
|
FText := FText + ' - ' + GetProgressString(FProgress);
|
|
FText := FText + GetOperationStateString(OpManItem.Operation.State);
|
|
|
|
CalculateSizes(Canvas, OpManItem.Queue.IsFree, FProgress > 0);
|
|
end
|
|
else
|
|
begin
|
|
FText := '';
|
|
FProgress := 0;
|
|
FTreeNode.Height := 10;
|
|
end;
|
|
end;
|
|
|
|
function TViewOperationItem.GetTextIndent: Integer;
|
|
begin
|
|
Result := FTreeNode.DisplayExpandSignLeft;
|
|
if FTreeNode.Level = 0 then
|
|
Inc(Result, FreeOperationTextIndent)
|
|
else
|
|
Dec(Result, TTreeView(FTreeNode.TreeView).Indent * (FTreeNode.Level - 1));
|
|
end;
|
|
|
|
{ TViewQueueItem }
|
|
|
|
procedure TViewQueueItem.Click(const Pt: TPoint; Button: TMouseButton; Shift: TShiftState);
|
|
var
|
|
Handled: Boolean = False;
|
|
NodeRect: TRect;
|
|
begin
|
|
case Button of
|
|
mbLeft:
|
|
begin
|
|
NodeRect := FTreeNode.DisplayRect(False);
|
|
if (ssDouble in Shift) or PtInRect(GetStatusIconRect(NodeRect), Pt) then
|
|
begin
|
|
StartPause;
|
|
Handled := True;
|
|
end;
|
|
end;
|
|
end;
|
|
if not Handled then
|
|
inherited Click(Pt, Button, Shift);
|
|
end;
|
|
|
|
constructor TViewQueueItem.Create(ANode: TTreeNode; AQueueId: TOperationsManagerQueueIdentifier);
|
|
begin
|
|
FQueueIdentifier := AQueueId;
|
|
inherited Create(ANode);
|
|
end;
|
|
|
|
procedure TViewQueueItem.Draw(Canvas: TCanvas; NodeRect: TRect);
|
|
var
|
|
Element: TThemedTreeview;
|
|
Queue: TOperationsManagerQueue;
|
|
Icon: TViewOperationsStatusIcon;
|
|
begin
|
|
if FTreeNode.Selected then
|
|
Element := ttItemSelected
|
|
else
|
|
Element := ttItemSelectedNotFocus;
|
|
DrawThemedBackground(Canvas, Element, NodeRect);
|
|
|
|
Queue := OperationsManager.QueueByIdentifier[FQueueIdentifier];
|
|
if Assigned(Queue) then
|
|
begin
|
|
DrawThemedText(Canvas, Element, FTextRect, True, FText);
|
|
|
|
if Queue.Paused then
|
|
Icon := vosiPause
|
|
else
|
|
Icon := vosiPlay;
|
|
DrawStatusIcon(Canvas, NodeRect, Icon);
|
|
end;
|
|
end;
|
|
|
|
function TViewQueueItem.GetBackgroundColor: TColor;
|
|
begin
|
|
Result := FTreeNode.TreeView.BackgroundColor;
|
|
end;
|
|
|
|
function TViewQueueItem.GetTextIndent: Integer;
|
|
var
|
|
ATreeView: TCustomTreeView;
|
|
begin
|
|
Result := FTreeNode.DisplayExpandSignLeft;
|
|
ATreeView := FTreeNode.TreeView;
|
|
if ATreeView is TTreeView then
|
|
Inc(Result, TTreeView(ATreeView).Indent);
|
|
end;
|
|
|
|
procedure TViewQueueItem.StartPause;
|
|
var
|
|
Queue: TOperationsManagerQueue;
|
|
begin
|
|
Queue := OperationsManager.QueueByIdentifier[FQueueIdentifier];
|
|
if Assigned(Queue) then
|
|
Queue.TogglePause;
|
|
end;
|
|
|
|
procedure TViewQueueItem.Stop;
|
|
var
|
|
Queue: TOperationsManagerQueue;
|
|
begin
|
|
Queue := OperationsManager.QueueByIdentifier[FQueueIdentifier];
|
|
if Assigned(Queue) then
|
|
begin
|
|
Queue.Stop;
|
|
end;
|
|
end;
|
|
|
|
procedure TViewQueueItem.UpdateView(Canvas: TCanvas);
|
|
var
|
|
Queue: TOperationsManagerQueue;
|
|
begin
|
|
Queue := OperationsManager.QueueByIdentifier[FQueueIdentifier];
|
|
if Assigned(Queue) then
|
|
begin
|
|
FText := Queue.GetDescription(False);
|
|
if Queue.Paused then
|
|
FText := FText + GetOperationStateString(fsosPaused);
|
|
|
|
CalculateSizes(Canvas, True, False);
|
|
end
|
|
else
|
|
begin
|
|
FText := '';
|
|
FTreeNode.Height := 10;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmViewOperations }
|
|
|
|
procedure TfrmViewOperations.FormCreate(Sender: TObject);
|
|
begin
|
|
InitPropStorage(Self);
|
|
cbAlwaysOnTopChange(nil);
|
|
|
|
FMenuOperation := InvalidOperationHandle;
|
|
tvOperations.DoubleBuffered := True;
|
|
DoubleBuffered := True;
|
|
|
|
CreateNodes;
|
|
|
|
OperationsManager.AddEventsListener(
|
|
[omevOperationAdded, omevOperationRemoved, omevOperationMoved],
|
|
@UpdateView);
|
|
|
|
tvOperations.OnResize := @tvOperationsResize;
|
|
end;
|
|
|
|
procedure TfrmViewOperations.btnStopClick(Sender: TObject);
|
|
var
|
|
Item: TViewBaseItem;
|
|
begin
|
|
Item := GetFocusedItem;
|
|
if Assigned(Item) then
|
|
Item.Stop;
|
|
end;
|
|
|
|
procedure TfrmViewOperations.cbAlwaysOnTopChange(Sender: TObject);
|
|
begin
|
|
if cbAlwaysOnTop.Checked then
|
|
begin
|
|
FormStyle := fsStayOnTop;
|
|
ShowInTaskBar := stDefault;
|
|
end
|
|
else
|
|
begin
|
|
FormStyle := fsNormal;
|
|
ShowInTaskBar := stAlways;
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmViewOperations.FormClose(Sender: TObject; var CloseAction: TCloseAction);
|
|
begin
|
|
CloseAction := caFree;
|
|
frmViewOperations := nil;
|
|
end;
|
|
|
|
procedure TfrmViewOperations.FormDestroy(Sender: TObject);
|
|
begin
|
|
OperationsManager.RemoveEventsListener(
|
|
[omevOperationAdded, omevOperationRemoved, omevOperationMoved],
|
|
@UpdateView);
|
|
end;
|
|
|
|
procedure TfrmViewOperations.mnuNewQueueClick(Sender: TObject);
|
|
var
|
|
Item: TViewBaseItem;
|
|
OpManItem: TOperationsManagerItem;
|
|
begin
|
|
Item := GetFocusedItem;
|
|
if Assigned(Item) and (Item is TViewOperationItem) then
|
|
begin
|
|
OpManItem := OperationsManager.GetItemByHandle(TViewOperationItem(Item).FOperationHandle);
|
|
if Assigned(OpManItem) then
|
|
OpManItem.MoveToNewQueue;
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmViewOperations.mnuPutFirstInQueueClick(Sender: TObject);
|
|
begin
|
|
MoveWithinQueue(True);
|
|
end;
|
|
|
|
procedure TfrmViewOperations.mnuPutLastInQueueClick(Sender: TObject);
|
|
begin
|
|
MoveWithinQueue(False);
|
|
end;
|
|
|
|
procedure TfrmViewOperations.mnuOperationShowDetachedClick(Sender: TObject);
|
|
var
|
|
OpManItem: TOperationsManagerItem;
|
|
begin
|
|
OpManItem := OperationsManager.GetItemByHandle(FMenuOperation);
|
|
if Assigned(OpManItem) and OpManItem.Queue.IsFree then
|
|
TfrmFileOp.ShowFor(OpManItem.Handle, [opwoIfExistsBringToFront]);
|
|
end;
|
|
|
|
procedure TfrmViewOperations.OnOperationItemContextMenu(Item: TViewBaseItem; const Point: TPoint);
|
|
var
|
|
i: Integer;
|
|
PopupPoint: TPoint;
|
|
OpManItem: TOperationsManagerItem;
|
|
begin
|
|
FMenuOperation := (Item as TViewOperationItem).FOperationHandle;
|
|
OpManItem := OperationsManager.GetItemByHandle(FMenuOperation);
|
|
if Assigned(OpManItem) then
|
|
begin
|
|
for i := 0 to mnuQueue.Count - 1 do
|
|
if i = OpManItem.Queue.Identifier then
|
|
mnuQueue.Items[i].Checked := True
|
|
else
|
|
mnuQueue.Items[i].Checked := False;
|
|
|
|
mnuOperationShowDetached.Enabled := OpManItem.Queue.IsFree;
|
|
PopupPoint := tvOperations.ClientToScreen(Point);
|
|
pmOperationPopup.PopUp(PopupPoint.x, PopupPoint.y);
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmViewOperations.OnOperationItemSelected(Item: TViewBaseItem);
|
|
var
|
|
OpManItem: TOperationsManagerItem;
|
|
begin
|
|
OpManItem := OperationsManager.GetItemByHandle(TViewOperationItem(Item).FOperationHandle);
|
|
if Assigned(OpManItem) then
|
|
begin
|
|
SetStartPauseCaption(OpManItem.Operation.State in [fsosStarting, fsosRunning, fsosWaitingForConnection]);
|
|
btnStartPause.Enabled := OpManItem.Queue.IsFree;
|
|
btnStop.Enabled := True;
|
|
end
|
|
else
|
|
begin
|
|
btnStartPause.Enabled := False;
|
|
btnStop.Enabled := False;
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmViewOperations.OnQueueContextMenu(Item: TViewBaseItem; const Point: TPoint);
|
|
var
|
|
PopupPoint: TPoint;
|
|
begin
|
|
FMenuQueueIdentifier := (Item as TViewQueueItem).FQueueIdentifier;
|
|
PopupPoint := tvOperations.ClientToScreen(Point);
|
|
pmQueuePopup.PopUp(PopupPoint.x, PopupPoint.y);
|
|
end;
|
|
|
|
procedure TfrmViewOperations.OnQueueItemSelected(Item: TViewBaseItem);
|
|
var
|
|
Queue: TOperationsManagerQueue;
|
|
begin
|
|
Queue := OperationsManager.QueueByIdentifier[TViewQueueItem(Item).FQueueIdentifier];
|
|
if Assigned(Queue) then
|
|
begin
|
|
SetStartPauseCaption(not Queue.Paused);
|
|
btnStartPause.Enabled := True;
|
|
end
|
|
else
|
|
begin
|
|
btnStartPause.Enabled := False;
|
|
end;
|
|
btnStop.Enabled := btnStartPause.Enabled;
|
|
end;
|
|
|
|
procedure TfrmViewOperations.OnUpdateTimer(Sender: TObject);
|
|
begin
|
|
UpdateSizes;
|
|
tvOperationsSelectionChanged(tvOperations);
|
|
tvOperations.Invalidate;
|
|
end;
|
|
|
|
procedure TfrmViewOperations.mnuQueueNumberClick(Sender: TObject);
|
|
var
|
|
NewQueueNumber: integer;
|
|
Item: TViewBaseItem;
|
|
begin
|
|
if TryStrToInt(Copy((Sender as TMenuItem).Name, 9, 1), NewQueueNumber) then
|
|
begin
|
|
Item := GetFocusedItem;
|
|
if Assigned(Item) and (Item is TViewOperationItem) then
|
|
SetNewQueue(TViewOperationItem(Item), NewQueueNumber);
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmViewOperations.mnuQueueShowDetachedClick(Sender: TObject);
|
|
var
|
|
Queue: TOperationsManagerQueue;
|
|
begin
|
|
Queue := OperationsManager.QueueByIdentifier[FMenuQueueIdentifier];
|
|
if Assigned(Queue) then
|
|
TfrmFileOp.ShowFor(Queue.Identifier, [opwoIfExistsBringToFront]);
|
|
end;
|
|
|
|
procedure TfrmViewOperations.tbPauseAllChange(Sender: TObject);
|
|
begin
|
|
if tbPauseAll.State = cbChecked then
|
|
OperationsManager.PauseAll
|
|
else
|
|
OperationsManager.UnPauseAll;
|
|
end;
|
|
|
|
procedure TfrmViewOperations.tvOperationsCustomDrawItem(Sender: TCustomTreeView; Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
|
|
var
|
|
Item: TViewBaseItem;
|
|
NodeRect: TRect;
|
|
|
|
procedure DrawExpandSign(MidX, MidY: integer; CollapseSign: boolean);
|
|
const
|
|
ExpandSignColor = clWindowText;
|
|
var
|
|
HalfSize, ALeft, ATop, ARight, ABottom: integer;
|
|
Points: array [0..2] of TPoint;
|
|
R: TRect;
|
|
begin
|
|
with Sender.Canvas do
|
|
begin
|
|
Brush.Color := clWindow;
|
|
Pen.Color := ExpandSignColor;
|
|
Pen.Style := psSolid;
|
|
|
|
HalfSize := ExpandSignSize shr 1;
|
|
if not Odd(ExpandSignSize) then
|
|
dec(HalfSize);
|
|
ALeft := MidX - HalfSize;
|
|
ATop := MidY - HalfSize;
|
|
ARight := ALeft + ExpandSignSize;
|
|
ABottom := ATop + ExpandSignSize;
|
|
|
|
// draw an arrow. down for collapse and right for expand
|
|
R := Rect(ALeft, ATop, ARight, ABottom);
|
|
if CollapseSign then
|
|
begin
|
|
// draw an arrow down
|
|
Points[0] := Point(R.Left, MidY);
|
|
Points[1] := Point(R.Right - 1, MidY);
|
|
Points[2] := Point(MidX, R.Bottom - 1);
|
|
end else
|
|
begin
|
|
// draw an arrow right
|
|
Points[0] := Point(MidX - 1, ATop);
|
|
Points[1] := Point(R.Right - 2, MidY);
|
|
Points[2] := Point(MidX - 1, R.Bottom - 1);
|
|
end;
|
|
Polygon(Points, False);
|
|
end;
|
|
end;
|
|
var
|
|
VertMid: Integer;
|
|
begin
|
|
if not Assigned(Node.Data) then
|
|
Exit;
|
|
|
|
Item := TViewBaseItem(Node.Data);
|
|
NodeRect := Node.DisplayRect(False);
|
|
|
|
Item.Draw(Sender.Canvas, NodeRect);
|
|
|
|
if tvOperations.ShowButtons and Node.HasChildren and ((tvoShowRoot in tvOperations.Options) or (Node.Parent <> nil)) then
|
|
begin
|
|
VertMid := (NodeRect.Top + NodeRect.Bottom) div 2;
|
|
DrawExpandSign(Node.DisplayExpandSignLeft + tvOperations.Indent shr 1, VertMid, Node.Expanded);
|
|
end;
|
|
|
|
// draw separator
|
|
if (tvoShowSeparators in tvOperations.Options) then
|
|
begin
|
|
Sender.Canvas.Pen.Color:=tvOperations.SeparatorColor;
|
|
Sender.Canvas.MoveTo(NodeRect.Left,NodeRect.Bottom-1);
|
|
Sender.Canvas.LineTo(NodeRect.Right,NodeRect.Bottom-1);
|
|
end;
|
|
|
|
DefaultDraw := False;
|
|
end;
|
|
|
|
procedure TfrmViewOperations.tvOperationsDeletion(Sender: TObject; Node: TTreeNode);
|
|
var
|
|
Item: TViewBaseItem;
|
|
begin
|
|
Item := TViewBaseItem(Node.Data);
|
|
Node.Data := nil;
|
|
Item.Free;
|
|
end;
|
|
|
|
procedure TfrmViewOperations.tvOperationsDragDrop(Sender, Source: TObject; X, Y: Integer);
|
|
var
|
|
TargetNode: TTreeNode;
|
|
NodeRect: TRect;
|
|
TargetItem: TViewBaseItem;
|
|
QueueItem: TViewQueueItem;
|
|
OperItem: TViewOperationItem;
|
|
SourceOpManItem, TargetOpManItem: TOperationsManagerItem;
|
|
TargetQueue: TOperationsManagerQueue;
|
|
TargetQueueId: TOperationsManagerQueueIdentifier;
|
|
HitTopPart: Boolean;
|
|
begin
|
|
if Source = tvOperations then
|
|
begin
|
|
SourceOpManItem := OperationsManager.GetItemByHandle(FDraggedOperation);
|
|
if Assigned(SourceOpManItem) then
|
|
begin
|
|
TargetNode := tvOperations.GetNodeAt(X, Y);
|
|
if not Assigned(TargetNode) then
|
|
begin
|
|
SourceOpManItem.MoveToNewQueue;
|
|
end
|
|
else
|
|
begin
|
|
NodeRect := TargetNode.DisplayRect(False);
|
|
TargetItem := TViewBaseItem(TargetNode.Data);
|
|
HitTopPart := Y - NodeRect.Top < (NodeRect.Bottom - NodeRect.Top) div 2;
|
|
|
|
if TargetItem is TViewQueueItem then
|
|
begin
|
|
QueueItem := TViewQueueItem(TargetItem);
|
|
if HitTopPart and
|
|
(TargetNode = tvOperations.Items.GetFirstNode) and
|
|
(QueueItem.FQueueIdentifier <> FreeOperationsQueueId) then
|
|
begin
|
|
// 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;
|
|
TargetQueue := OperationsManager.GetOrCreateQueue(TargetQueueId);
|
|
end
|
|
else
|
|
begin
|
|
TargetQueueId := QueueItem.FQueueIdentifier;
|
|
TargetQueue := OperationsManager.QueueByIdentifier[TargetQueueId];
|
|
end;
|
|
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;
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmViewOperations.tvOperationsDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
|
|
begin
|
|
Accept := True;
|
|
end;
|
|
|
|
procedure TfrmViewOperations.tvOperationsKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
|
|
var
|
|
Item: TViewBaseItem;
|
|
begin
|
|
Item := GetFocusedItem;
|
|
if Assigned(Item) then
|
|
Item.KeyDown(Key, Shift);
|
|
end;
|
|
|
|
procedure TfrmViewOperations.tvOperationsMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
|
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;
|
|
|
|
procedure TfrmViewOperations.tvOperationsResize(Sender: TObject);
|
|
begin
|
|
UpdateSizes;
|
|
end;
|
|
|
|
procedure TfrmViewOperations.tvOperationsSelectionChanged(Sender: TObject);
|
|
var
|
|
Node: TTreeNode;
|
|
begin
|
|
Node := tvOperations.Selected;
|
|
if Assigned(Node) then
|
|
TViewBaseItem(Node.Data).Selected;
|
|
end;
|
|
|
|
function TfrmViewOperations.GetFocusedItem: TViewBaseItem;
|
|
var
|
|
Node: TTreeNode;
|
|
begin
|
|
Node := tvOperations.Selected;
|
|
if Assigned(Node) then
|
|
Result := TViewBaseItem(Node.Data)
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure TfrmViewOperations.mnuCancelOperationClick(Sender: TObject);
|
|
var
|
|
OpManItem: TOperationsManagerItem;
|
|
begin
|
|
OpManItem := OperationsManager.GetItemByHandle(FMenuOperation);
|
|
if Assigned(OpManItem) then
|
|
OpManItem.Operation.Stop;
|
|
end;
|
|
|
|
procedure TfrmViewOperations.mnuCancelQueueClick(Sender: TObject);
|
|
var
|
|
Queue: TOperationsManagerQueue;
|
|
begin
|
|
Queue := OperationsManager.QueueByIdentifier[FMenuQueueIdentifier];
|
|
if Assigned(Queue) then
|
|
Queue.Stop;
|
|
end;
|
|
|
|
procedure TfrmViewOperations.MoveWithinQueue(MoveToTop: Boolean);
|
|
var
|
|
Item: TViewBaseItem;
|
|
OpManItem: TOperationsManagerItem;
|
|
begin
|
|
Item := GetFocusedItem;
|
|
if Assigned(Item) and (Item is TViewOperationItem) then
|
|
begin
|
|
OpManItem := OperationsManager.GetItemByHandle(TViewOperationItem(Item).FOperationHandle);
|
|
if Assigned(OpManItem) then
|
|
begin
|
|
if OpManItem.Queue.Identifier <> FreeOperationsQueueId then
|
|
begin
|
|
if MoveToTop then
|
|
OpManItem.MoveToTop
|
|
else
|
|
OpManItem.MoveToBottom;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmViewOperations.SetFocusItem(AOperationHandle: TOperationHandle);
|
|
var
|
|
Node: TTreeNode;
|
|
begin
|
|
for Node in tvOperations.Items do
|
|
begin
|
|
if (TViewBaseItem(Node.Data) is TViewOperationItem) and
|
|
(TViewOperationItem(Node.Data).FOperationHandle = AOperationHandle) then
|
|
begin
|
|
Node.Selected := True;
|
|
Exit;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmViewOperations.SetFocusItem(AQueueIdentifier: TOperationsManagerQueueIdentifier);
|
|
var
|
|
Node: TTreeNode;
|
|
begin
|
|
for Node in tvOperations.Items do
|
|
begin
|
|
if (TViewBaseItem(Node.Data) is TViewQueueItem) and
|
|
(TViewQueueItem(Node.Data).FQueueIdentifier = AQueueIdentifier) then
|
|
begin
|
|
Node.Selected := True;
|
|
Exit;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmViewOperations.SetNewQueue(Item: TViewOperationItem; NewQueue: TOperationsManagerQueueIdentifier);
|
|
var
|
|
OpManItem: TOperationsManagerItem;
|
|
begin
|
|
OpManItem := OperationsManager.GetItemByHandle(Item.FOperationHandle);
|
|
if Assigned(OpManItem) then
|
|
OpManItem.SetQueue(OperationsManager.GetOrCreateQueue(NewQueue));
|
|
end;
|
|
|
|
procedure TfrmViewOperations.SetStartPauseCaption(SetPause: Boolean);
|
|
begin
|
|
if SetPause then
|
|
btnStartPause.Caption := rsDlgOpPause
|
|
else
|
|
btnStartPause.Caption := rsDlgOpStart;
|
|
end;
|
|
|
|
procedure TfrmViewOperations.btnStartPauseClick(Sender: TObject);
|
|
var
|
|
Item: TViewBaseItem;
|
|
begin
|
|
Item := GetFocusedItem;
|
|
if Assigned(Item) then
|
|
Item.StartPause;
|
|
end;
|
|
|
|
procedure TfrmViewOperations.CreateNodes;
|
|
procedure AddOperations(Queue: TOperationsManagerQueue; QueueNode: TTreeNode);
|
|
var
|
|
OperIndex: Integer;
|
|
OpManItem: TOperationsManagerItem;
|
|
OperNode: TTreeNode;
|
|
Item: TViewBaseItem;
|
|
begin
|
|
for OperIndex := 0 to Queue.Count - 1 do
|
|
begin
|
|
OpManItem := Queue.Items[OperIndex];
|
|
OperNode := tvOperations.Items.AddChild(QueueNode, '');
|
|
Item := TViewOperationItem.Create(OperNode, OpManItem.Handle);
|
|
OperNode.Data := Item;
|
|
Item.UpdateView(tvOperations.Canvas);
|
|
Item.OnContextMenu := @OnOperationItemContextMenu;
|
|
Item.OnSelected := @OnOperationItemSelected;
|
|
end;
|
|
end;
|
|
var
|
|
QueueIndex: Integer;
|
|
Queue: TOperationsManagerQueue;
|
|
QueueNode: TTreeNode;
|
|
Item: TViewBaseItem;
|
|
begin
|
|
tvOperations.Items.Clear;
|
|
|
|
// First add all free operations.
|
|
Queue := OperationsManager.QueueByIdentifier[FreeOperationsQueueId];
|
|
if Assigned(Queue) then
|
|
AddOperations(Queue, nil);
|
|
|
|
for QueueIndex := 0 to OperationsManager.QueuesCount - 1 do
|
|
begin
|
|
Queue := OperationsManager.QueueByIndex[QueueIndex];
|
|
if Queue.Identifier <> FreeOperationsQueueId then
|
|
begin
|
|
QueueNode := tvOperations.Items.AddChild(nil, '');
|
|
Item := TViewQueueItem.Create(QueueNode, Queue.Identifier);
|
|
QueueNode.Data := Item;
|
|
Item.UpdateView(tvOperations.Canvas);
|
|
Item.OnContextMenu := @OnQueueContextMenu;
|
|
Item.OnSelected := @OnQueueItemSelected;
|
|
AddOperations(Queue, QueueNode);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmViewOperations.UpdateSizes;
|
|
var
|
|
Node: TTreeNode;
|
|
begin
|
|
Node := tvOperations.Items.GetFirstNode;
|
|
while Assigned(Node) do
|
|
begin
|
|
if Assigned(Node.Data) then
|
|
TViewBaseItem(Node.Data).UpdateView(tvOperations.Canvas);
|
|
Node := Node.GetNext;
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmViewOperations.UpdateView(Item: TOperationsManagerItem; Event: TOperationManagerEvent);
|
|
begin
|
|
CreateNodes;
|
|
tvOperations.Invalidate;
|
|
end;
|
|
|
|
initialization
|
|
ProgressRight := ProgressHorizontalMargin + StatusIconRightMargin + (StatusIconFrame.Right - StatusIconFrame.Left);
|
|
|
|
end.
|
|
|