UPD: Display queues in operations panel.

This commit is contained in:
cobines 2012-03-20 21:02:28 +00:00
commit dea91f7918
8 changed files with 507 additions and 285 deletions

View file

@ -272,7 +272,7 @@
<PackageName Value="viewerpackage"/>
</Item10>
</RequiredPackages>
<Units Count="159">
<Units Count="160">
<Unit0>
<Filename Value="doublecmd.lpr"/>
<IsPartOfProject Value="True"/>
@ -1263,6 +1263,11 @@
<ResourceBaseClass Value="Frame"/>
<UnitName Value="fWcxArchiveCopyOperationOptions"/>
</Unit158>
<Unit159>
<Filename Value="uoperationspanel.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="uOperationsPanel"/>
</Unit159>
</Units>
</ProjectOptions>
<CompilerOptions>

View file

@ -344,7 +344,7 @@ begin
btnOptions.Visible := False;
ShowOptions(False);
btnOK.Caption := rsOperStartStateAutoStart;
btnOK.Caption := rsDlgOpStart;
FQueueIdentifier := FreeOperationsQueueId;
HMForm := HotMan.Register(Self, HotkeysCategory);

View file

@ -122,23 +122,23 @@ object frmMain: TfrmMain
end
object pnlNotebooks: TPanel
Left = 0
Height = 154
Height = 157
Top = 46
Width = 760
Align = alClient
ClientHeight = 154
ClientHeight = 157
ClientWidth = 760
FullRepaint = False
TabOrder = 1
OnResize = pnlNotebooksResize
object pnlLeft: TPanel
Left = 1
Height = 152
Height = 155
Top = 1
Width = 511
Align = alLeft
BevelOuter = bvNone
ClientHeight = 152
ClientHeight = 155
ClientWidth = 511
TabOrder = 0
OnDblClick = pnlLeftRightDblClick
@ -155,18 +155,18 @@ object frmMain: TfrmMain
end
object pnlLeftTools: TPanel
Left = 0
Height = 24
Height = 25
Top = 10
Width = 511
Align = alTop
AutoSize = True
BevelOuter = bvNone
ClientHeight = 24
ClientHeight = 25
ClientWidth = 511
TabOrder = 0
object btnLeftDrive: TSpeedButton
Left = 0
Height = 24
Height = 25
Top = 0
Width = 48
Action = actLeftOpenDrives
@ -177,7 +177,7 @@ object frmMain: TfrmMain
end
object btnLeftHome: TSpeedButton
Left = 465
Height = 24
Height = 25
Hint = 'Go to home directory'
Top = 0
Width = 23
@ -188,7 +188,7 @@ object frmMain: TfrmMain
end
object btnLeftUp: TSpeedButton
Left = 442
Height = 24
Height = 25
Hint = 'Go to parent directory'
Top = 0
Width = 23
@ -199,7 +199,7 @@ object frmMain: TfrmMain
end
object btnLeftRoot: TSpeedButton
Left = 419
Height = 24
Height = 25
Hint = 'Go to root directory'
Top = 0
Width = 23
@ -210,7 +210,7 @@ object frmMain: TfrmMain
end
object btnLeftDirectoryHotlist: TSpeedButton
Left = 396
Height = 24
Height = 25
Hint = 'Directory hotlist'
Top = 0
Width = 23
@ -221,7 +221,7 @@ object frmMain: TfrmMain
end
object btnLeftEqualRight: TSpeedButton
Left = 488
Height = 24
Height = 25
Hint = 'Show current directory of the right panel in the left panel'
Top = 0
Width = 23
@ -265,12 +265,12 @@ object frmMain: TfrmMain
end
object pnlRight: TPanel
Left = 512
Height = 152
Height = 155
Top = 1
Width = 247
Align = alClient
BevelOuter = bvNone
ClientHeight = 152
ClientHeight = 155
ClientWidth = 247
TabOrder = 1
OnDblClick = pnlLeftRightDblClick
@ -287,18 +287,18 @@ object frmMain: TfrmMain
end
object pnlRightTools: TPanel
Left = 0
Height = 24
Height = 25
Top = 10
Width = 247
Align = alTop
AutoSize = True
BevelOuter = bvNone
ClientHeight = 24
ClientHeight = 25
ClientWidth = 247
TabOrder = 0
object btnRightDrive: TSpeedButton
Left = 0
Height = 24
Height = 25
Top = 0
Width = 48
Action = actRightOpenDrives
@ -309,7 +309,7 @@ object frmMain: TfrmMain
end
object btnRightHome: TSpeedButton
Left = 201
Height = 24
Height = 25
Top = 0
Width = 23
Align = alRight
@ -319,7 +319,7 @@ object frmMain: TfrmMain
end
object btnRightUp: TSpeedButton
Left = 178
Height = 24
Height = 25
Top = 0
Width = 23
Align = alRight
@ -329,7 +329,7 @@ object frmMain: TfrmMain
end
object btnRightRoot: TSpeedButton
Left = 155
Height = 24
Height = 25
Top = 0
Width = 23
Align = alRight
@ -339,7 +339,7 @@ object frmMain: TfrmMain
end
object btnRightDirectoryHotlist: TSpeedButton
Left = 132
Height = 24
Height = 25
Top = 0
Width = 23
Align = alRight
@ -349,7 +349,7 @@ object frmMain: TfrmMain
end
object btnRightEqualLeft: TSpeedButton
Left = 224
Height = 24
Height = 25
Hint = 'Show current directory of the left panel in the right panel'
Top = 0
Width = 23
@ -408,37 +408,14 @@ object frmMain: TfrmMain
end
end
object PanelAllProgress: TPanel
Left = 3
Left = 0
Height = 0
Top = 200
Width = 754
Top = 203
Width = 760
Align = alBottom
BorderSpacing.Left = 3
BorderSpacing.Right = 3
BorderSpacing.Bottom = 3
BorderSpacing.CellAlignHorizontal = ccaRightBottom
BorderSpacing.CellAlignVertical = ccaCenter
ClientHeight = 0
ClientWidth = 754
AutoSize = True
BevelOuter = bvNone
TabOrder = 6
object sboxOperations: TScrollBox
AnchorSideTop.Control = PanelAllProgress
AnchorSideBottom.Control = PanelAllProgress
AnchorSideBottom.Side = asrBottom
Left = 1
Height = 0
Top = 0
Width = 755
HorzScrollBar.Page = 755
VertScrollBar.Page = 1
Anchors = [akTop, akLeft, akRight, akBottom]
AutoSize = True
TabOrder = 0
OnMouseDown = sboxOperationsMouseDown
OnMouseMove = sboxOperationsMouseMove
OnMouseUp = sboxOperationsMouseUp
OnPaint = sboxOperationsPaint
end
end
object ConsoleSplitter: TSplitter
Cursor = crVSplit

View file

@ -46,7 +46,8 @@ uses
uCmdBox, uFilePanelSelect, uBriefFileView,
uFileView, uColumnsFileView, uFileSource, uFileViewNotebook, uFile,
uOperationsManager, uFileSourceOperation, uDrivesList, uTerminal, uClassesEx,
uXmlConfig, uDrive, uDriveWatcher, uDCVersion, uMainCommands, uFormCommands
uXmlConfig, uDrive, uDriveWatcher, uDCVersion, uMainCommands, uFormCommands,
uOperationsPanel
{$IFDEF LCLQT}
, Qt4, QtWidgets
{$ENDIF}
@ -179,7 +180,6 @@ type
Timer: TTimer;
PanelAllProgress: TPanel;
pbxRightDrive: TPaintBox;
sboxOperations: TScrollBox;
pbxLeftDrive: TPaintBox;
tbPaste: TMenuItem;
tbCopy: TMenuItem;
@ -416,7 +416,6 @@ type
NumberOfButton: Integer);
procedure MainToolBarToolButtonMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer; NumberOfButton: Integer);
procedure miLogMenuClick(Sender: TObject);
procedure miTrayIconExitClick(Sender: TObject);
procedure miTrayIconRestoreClick(Sender: TObject);
@ -479,13 +478,6 @@ type
procedure pnlNotebooksResize(Sender: TObject);
procedure pnlRightResize(Sender: TObject);
procedure sboxDrivePaint(Sender: TObject);
procedure sboxOperationsMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure sboxOperationsMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure sboxOperationsMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure sboxOperationsPaint(Sender: TObject);
procedure seLogWindowSpecialLineColors(Sender: TObject; Line: integer;
var Special: boolean; var FG, BG: TColor);
@ -523,6 +515,7 @@ type
can be used, because the user can do only one menu popup at a time. }
FDropParams: TDropParams;
FDrivesListPopup: TDrivesListPopup;
FOperationsPanel: TOperationsPanel;
// frost_asm begin
// mainsplitter
@ -532,8 +525,6 @@ type
// lastWindowState
lastWindowState:TWindowState;
// frost_asm end
PressLMB: boolean;
widthOfItem, ItemEnd: integer;
// for dragging buttons and etc
NumberOfMoveButton, NumberOfNewMoveButton: integer;
Draging : boolean;
@ -2976,198 +2967,6 @@ begin
end;
end;
procedure TfrmMain.sboxOperationsMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
OperationNumber: Integer;
CursorPos: TPoint;
OpManItem: TOperationsManagerItem;
begin
CursorPos := Mouse.CursorPos;
CursorPos := sboxOperations.ScreenToClient(CursorPos);
OperationNumber := CursorPos.X div widthOfItem;
if (OperationNumber < 0) or (OperationNumber > OperationsManager.OperationsCount) then Exit;
case Button of
mbMiddle:
begin
OperationsManager.MoveOperation(OperationNumber, OperationNumber - 1);
end;
mbRight:
begin
OpManItem := OperationsManager.GetItemByIndex(OperationNumber);
if Assigned(OpManItem) then
begin
if OpManItem.Operation.State = fsosRunning then
begin
OpManItem.PauseRunning := True;
OpManItem.Operation.Pause;
end
else
begin
//OperationsManager.InQueue(OpManItem.Handle, True);
end;
end;
end;
mbLeft:
begin
indexFocus:= OperationNumber;
PressLMB:=true;
ItemEnd:= OperationNumber;
end;
end;
end;
procedure TfrmMain.sboxOperationsMouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Integer);
begin
if PressLMB then ItemEnd:= X div widthOfItem;
end;
procedure TfrmMain.sboxOperationsMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
OperationDialog: TfrmFileOp;
OpManItem: TOperationsManagerItem;
begin
if Button=mbLeft then
begin
PressLMB := False;
if (ItemEnd < 0) then
OperationsManager.MoveOperation(IndexFocus, 0);
if (ItemEnd > OperationsManager.OperationsCount) then
OperationsManager.MoveOperation(IndexFocus, OperationsManager.OperationsCount);
if IndexFocus = ItemEnd then
begin
OpManItem := OperationsManager.GetItemByIndex(indexFocus);
if Assigned(OpManItem) then
TfrmFileOp.ShowFor(OpManItem.Handle);
end
else
OperationsManager.MoveOperation(IndexFocus, ItemEnd);
end;
IndexFocus:=ItemEnd;
end;
procedure TfrmMain.sboxOperationsPaint(Sender: TObject);
var
OpManItem: TOperationsManagerItem;
I: Integer;
OutString: String;
ARect: TRect;
HeightSbox: Integer;
AStart, AStop: TColor;
begin
if OperationsManager.OperationsCount > 0 then
begin
HeightSbox:= sboxOperations.Height;
ARect:= sboxOperations.ClientRect;
sboxOperations.Canvas.Pen.Color:= cl3DDkShadow;
sboxOperations.Canvas.Rectangle(ARect);
Inc(ARect.Left);
Inc(ARect.Top);
Dec(ARect.Right, 2);
Dec(ARect.Bottom);
sboxOperations.Canvas.GradientFill(ARect, LightColor(clBtnHiLight, 20),
clBtnFace, gdVertical);
// Calculate item width
if (sboxOperations.Width / OperationsManager.OperationsCount) < 120 then
widthOfItem := Round(sboxOperations.Width / OperationsManager.OperationsCount)
else
widthOfItem := 120;
for I := 0 to OperationsManager.OperationsCount - 1 do
begin
if (I = ItemEnd) and (PressLMB) or (I = IndexFocus) and (PressLMB) then
begin
sboxOperations.Canvas.Pen.Color := cl3DDkShadow;
sboxOperations.Canvas.Brush.Color := clMenuHighlight;
sboxOperations.Canvas.Brush.Style:= bsSolid;
// TODO: Localize strings
sboxOperations.Canvas.Rectangle(10 + (widthOfItem * I), 3, widthOfItem - 10 + (widthOfItem * I), sboxOperations.Height - 7);
if IndexFocus <> ItemEnd then OutString:= 'Move here' else OutString:= 'Move from';
if I = IndexFocus then OutString:= 'Move from';
sboxOperations.Canvas.Brush.Style:= bsClear;
sboxOperations.Canvas.TextOut(18 + (widthOfItem * I), 7, OutString);
end
else
begin
OpManItem := OperationsManager.GetItemByIndex(I);
if Assigned(OpManItem) then
begin
// set progress bar color by operation state
case OpManItem.Operation.State of
// Green if running
fsosRunning:
begin
AStart:= RGB(203, 233, 171);
AStop:= RGB(146, 208, 80);
end;
// Orange if in paused/waiting
fsosNotStarted, fsosPaused, fsosWaitingForFeedback, fsosWaitingForConnection:
begin
AStart:= RGB(255, 202, 100);
AStop:= RGB(255, 153, 4);
end;
// Red if stopped
fsosStopped:
begin
AStart:= RGB(255, 153, 149);
AStop:= RGB(255, 110, 103);
end;
end;
case OpManItem.Operation.ID of
fsoCopy, fsoCopyIn, fsoCopyOut:
OutString := 'Copying';
fsoMove:
OutString := 'Moving';
fsoDelete:
OutString := 'Delete';
fsoWipe:
OutString := 'Erasing';
fsoCalcChecksum:
OutString := 'Counting';
else
OutString := 'Unknown';
end;
OutString := IntToStr(OpManItem.Handle) + ': '
+ OutString + ' - '
+ FloatToStrF(OpManItem.Operation.Progress * 100, ffFixed, 0, 0) + ' %';
if TfrmFileOp.IsOpenedFor(OpManItem.Handle) then
sboxOperations.Canvas.Pen.Color := clMenuHighlight
else
sboxOperations.Canvas.Pen.Color := LightColor(cl3DDkShadow, 40);
sboxOperations.Canvas.Brush.Style:= bsClear;
// Draw border
sboxOperations.Canvas.Rectangle(2 + (widthOfItem * I), 2, widthOfItem + (widthOfItem * I), HeightSbox - 6);
// Draw progress bar
ARect.TopLeft.x:= 3 + (widthOfItem * I);
ARect.TopLeft.y:= 3;
ARect.BottomRight.x:= Round(5 + (widthOfItem * I) + (widthOfItem - 10) * OpManItem.Operation.Progress);
ARect.BottomRight.y:= HeightSbox - 7;
sboxOperations.Canvas.GradientFill(ARect, AStart, AStop, gdVertical);
// Draw output string
sboxOperations.Canvas.TextOut(3 + (widthOfItem * I), 2, OutString);
end;
end;
end;
end;
end;
procedure TfrmMain.seLogWindowSpecialLineColors(Sender: TObject; Line: integer;
var Special: boolean; var FG, BG: TColor);
var
@ -4037,6 +3836,16 @@ begin
end;
end;
if gPanelOfOp then
begin
FOperationsPanel := TOperationsPanel.Create(Self);
FOperationsPanel.Parent := PanelAllProgress;
FOperationsPanel.DoubleBuffered := True;
PanelAllProgress.OnResize := @FOperationsPanel.ParentResized;
end
else
FreeAndNil(FOperationsPanel);
// Log window
seLogWindow.Visible := gLogWindow;
LogSplitter.Visible := gLogWindow;
@ -4850,7 +4659,6 @@ begin
begin
if gPanelOfOp = True then
begin
PanelAllProgress.Height := sboxOperations.Canvas.TextHeight('Pg') * 2 + 8;
// Make panel visible if at least one operation has no form
visiblePanel:= False;
for i := 0 to OperationsManager.OperationsCount - 1 do
@ -4859,11 +4667,8 @@ begin
if not TfrmFileOp.IsOpenedFor(OpManItem.Handle) then
visiblePanel:= True;
end;
if visiblePanel = True then
PanelAllProgress.Visible:= True
else
PanelAllProgress.Visible:= False;
sboxOperations.Invalidate; // force redraw
PanelAllProgress.Visible := visiblePanel;
FOperationsPanel.UpdateView;
end;
if gProgInMenuBar = true then
@ -4884,7 +4689,6 @@ begin
AllOpCancel.Visible:= true;
end;
end;
if not(PanelAllProgress.Visible) then PressLMB:= PanelAllProgress.Visible;
end;
procedure TfrmMain.SetFileSystemPath(aFileView: TFileView; aPath: UTF8String);

View file

@ -127,9 +127,6 @@ type
procedure ShowOperationsViewer(AOperationHandle: TOperationHandle = InvalidOperationHandle);
var
IndexFocus: Integer = -1; // TODO: Remove later
implementation
{$R *.lfm}
@ -348,7 +345,7 @@ constructor TViewQueueItem.Create(ANode: TTreeNode; AQueueId: TOperationsManager
begin
FQueueIdentifier := AQueueId;
inherited Create(ANode);
FText := 'Queue [#' + IntToStr(AQueueId) + ']';
FText := rsDlgQueue + ' [#' + IntToStr(AQueueId) + ']';
end;
procedure TViewQueueItem.Draw(Canvas: TCanvas; NodeRect: TRect);

View file

@ -53,6 +53,7 @@ type
FList: TFPList;
FIdentifier: TOperationsManagerQueueIdentifier;
function GetItem(Index: Integer): TOperationsManagerItem;
function GetItemByHandle(Handle: TOperationHandle): TOperationsManagerItem;
function GetOperationsCount: Integer;
procedure RunNextOperation(Index: Integer);
procedure RunOperation(Item: TOperationsManagerItem);
@ -79,6 +80,7 @@ type
property Count: Integer read GetOperationsCount;
property Items[Index: Integer]: TOperationsManagerItem read GetItem;
property ItemByHandle[Handle: TOperationHandle]: TOperationsManagerItem read GetItemByHandle;
property Identifier: TOperationsManagerQueueIdentifier read FIdentifier;
end;
@ -241,6 +243,19 @@ begin
Result := TOperationsManagerItem(FList.Items[Index]);
end;
function TOperationsManagerQueue.GetItemByHandle(Handle: TOperationHandle): TOperationsManagerItem;
var
Index: Integer;
begin
for Index := 0 to Count - 1 do
begin
Result := Items[Index];
if Result.Handle = Handle then
Exit;
end;
Result := nil;
end;
function TOperationsManagerQueue.GetOperationsCount: Integer;
begin
Result := FList.Count;
@ -425,19 +440,15 @@ end;
function TOperationsManager.GetItemByHandle(Handle: TOperationHandle): TOperationsManagerItem;
var
OperIndex, QueueIndex: Integer;
Item: TOperationsManagerItem;
QueueIndex: Integer;
Queue: TOperationsManagerQueue;
begin
for QueueIndex := 0 to QueuesCount - 1 do
begin
Queue := QueueByIndex[QueueIndex];
for OperIndex := 0 to Queue.Count - 1 do
begin
Item := Queue.Items[OperIndex];
if Item.Handle = Handle then
Exit(Item);
end;
Queue := QueueByIndex[QueueIndex];
Result := Queue.ItemByHandle[Handle];
if Assigned(Result) then
Exit;
end;
Result := nil;
end;

View file

@ -219,9 +219,7 @@ resourcestring
rsDlgUnknownOperation = 'Unknown operation';
rsDlgOpStart = 'Start';
rsDlgOpPause = 'Pause';
rsDlgQueueIn = 'In';
rsDlgQueueOut = 'Out';
rsDlgOpCaption = 'Caption of operation';
rsDlgQueue = 'Queue';
// Viewer
rsViewAboutText = 'Internal Viewer of Double Commander.';
rsViewNotFound = '%s not found!';
@ -463,12 +461,6 @@ resourcestring
rsOperAborted = 'Aborted';
rsOperQueued = 'Queued';
// Operation starting options.
rsOperStartStateManualStart = 'Manual start';
rsOperStartStateAutoStart = 'Start';
rsOperStartStateQueueFirst = 'Queue as first';
rsOperStartStateQueueLast = 'Queue as last';
// Unhandled error.
rsUnhandledExceptionMessage =
'Please report this error to the bug tracker with a description '

436
src/uoperationspanel.pas Normal file
View file

@ -0,0 +1,436 @@
{
Double Commander
-------------------------------------------------------------------------
Panel displaying file operations.
Copyright (C) 2012 Przemysław Nagay (cobines@gmail.com)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
}
unit uOperationsPanel;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Controls, Forms, Graphics,
uFileSourceOperation;
type
{ TOperationsPanel }
TOperationsPanel = class(TScrollBox)
private
FOperations, FQueues: TFPList;
FParentWidth: Integer;
PressLMB: boolean;
ItemEnd: integer;
procedure ClearItems;
procedure DeleteItem(List: TFPList; Index: Integer);
function GetProgressString(Progress: Double): String;
function GetOperationDescription(Operation: TFileSourceOperation): String;
procedure GetStateColor(State: TFileSourceOperationState; out ColorFrom, ColorTo: TColor);
procedure StartPauseOperation(Operation: TFileSourceOperation);
procedure UpdateItems;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure Paint; override;
procedure ParentResized(Sender: TObject);
procedure UpdateView;
end;
implementation
uses
LCLIntf, LCLType, LCLProc, Math,
fViewOperations, fFileOpDlg,
uDCUtils, uLng,
uOperationsManager,
uFileSourceOperationTypes;
const
MinimumHeight = 25;
MaximumItemWidth = 150;
LeftRightTextMargin = 4;
TopBottomTextMargin = 2;
HorizontalSpaceBetween = 1;
PanelBorderWidth = 1;
type
TOperationPanelItem = record
Width: Integer;
OperationHandle: TOperationHandle;
QueueId: TOperationsManagerQueueIdentifier;
end;
POperationPanelItem = ^TOperationPanelItem;
{ TOperationsPanel }
procedure TOperationsPanel.ParentResized(Sender: TObject);
begin
FParentWidth := (Sender as TControl).Width;
UpdateItems;
end;
procedure TOperationsPanel.ClearItems;
var
p: Pointer;
begin
for p in FOperations do
Dispose(POperationPanelItem(p));
for p in FQueues do
Dispose(POperationPanelItem(p));
FOperations.Clear;
FQueues.Clear;
end;
procedure TOperationsPanel.DeleteItem(List: TFPList; Index: Integer);
begin
Dispose(POperationPanelItem(List[Index]));
List.Delete(Index);
end;
function TOperationsPanel.GetProgressString(Progress: Double): String;
begin
Result := FloatToStrF(Progress * 100, ffFixed, 0, 0) + ' %';
end;
function TOperationsPanel.GetOperationDescription(Operation: TFileSourceOperation): String;
begin
case Operation.ID of
fsoCopy, fsoCopyIn, fsoCopyOut:
Result := 'Copying';
fsoMove:
Result := 'Moving';
fsoDelete:
Result := 'Delete';
fsoWipe:
Result := 'Erasing';
fsoCalcChecksum:
Result := 'Counting';
else
Result := 'Unknown';
end;
end;
procedure TOperationsPanel.GetStateColor(State: TFileSourceOperationState; out ColorFrom, ColorTo: TColor);
begin
case State of
// Green if running
fsosRunning:
begin
ColorFrom:= RGB(203, 233, 171);
ColorTo:= RGB(146, 208, 80);
end;
// Orange if in waiting
fsosWaitingForFeedback, fsosWaitingForConnection:
begin
ColorFrom:= RGB(255, 202, 100);
ColorTo:= RGB(255, 153, 4);
end;
// Red if paused, stopped
fsosPaused, fsosStopped:
begin
ColorFrom:= RGB(255, 153, 149);
ColorTo:= RGB(255, 110, 103);
end;
else
begin
ColorFrom:= RGB(0, 0, 0);
ColorTo:= RGB(255, 255, 255);
end;
end;
end;
procedure TOperationsPanel.UpdateItems;
var
OpManItem: TOperationsManagerItem;
QueueIndex, OperIndex: Integer;
OutString: String;
ItemRect: TRect;
Queue: TOperationsManagerQueue;
OperationItem: POperationPanelItem;
OverallHeight: Integer = MinimumHeight;
OverallWidth: Integer = 0;
procedure SetSize;
begin
ItemRect := Rect(0, 0, 0, 0);
DrawText(Canvas.Handle, PChar(OutString), Length(OutString), ItemRect,
DT_NOPREFIX or DT_CALCRECT);
OperationItem^.Width :=
Min(ItemRect.Right + (LeftRightTextMargin + PanelBorderWidth) * 2, MaximumItemWidth);
OverallHeight :=
Max(ItemRect.Bottom + (TopBottomTextMargin + PanelBorderWidth) * 2, OverallHeight);
OverallWidth := OverallWidth + OperationItem^.Width + HorizontalSpaceBetween;
end;
begin
ClearItems;
for QueueIndex := 0 to OperationsManager.QueuesCount - 1 do
begin
Queue := OperationsManager.QueueByIndex[QueueIndex];
if Queue.Count > 0 then
begin
if Queue.Identifier = FreeOperationsQueueId then
begin
for OperIndex := 0 to Queue.Count - 1 do
begin
OpManItem := Queue.Items[OperIndex];
if Assigned(OpManItem) then
begin
New(OperationItem);
FOperations.Add(OperationItem);
OperationItem^.QueueId := Queue.Identifier;
OperationItem^.OperationHandle := OpManItem.Handle;
OutString := IntToStr(OpManItem.Handle) + ': ' +
GetOperationDescription(OpManItem.Operation) + ' - ' + GetProgressString(100);
SetSize;
end;
end;
end
else
begin
New(OperationItem);
FQueues.Add(OperationItem);
OperationItem^.QueueId := Queue.Identifier;
OperationItem^.OperationHandle := InvalidOperationHandle;
OutString := rsDlgQueue + ' ' + IntToStr(Queue.Identifier) + ' - ' + GetProgressString(100) +
LineEnding + GetOperationDescription(Queue.Items[0].Operation);
SetSize;
end;
end;
end;
ClientHeight := OverallHeight + 2;
ClientWidth := Max(OverallWidth - HorizontalSpaceBetween, FParentWidth);
end;
constructor TOperationsPanel.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FOperations := TFPList.Create;
FQueues := TFPList.Create;
end;
destructor TOperationsPanel.Destroy;
begin
inherited Destroy;
FOperations.Free;
FQueues.Free;
end;
procedure TOperationsPanel.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
ClickPos: TPoint;
OpManItem: TOperationsManagerItem;
procedure HandleItem(Item: POperationPanelItem);
var
Queue: TOperationsManagerQueue;
begin
Queue := OperationsManager.QueueByIdentifier[Item^.QueueId];
if Assigned(Queue) and (Queue.Count > 0) then
begin
if Item^.OperationHandle = InvalidOperationHandle then
begin
OpManItem := Queue.Items[0];
if Assigned(OpManItem) then
begin
case Button of
mbLeft:
StartPauseOperation(OpManItem.Operation);
end;
end;
end
else
begin
OpManItem := Queue.ItemByHandle[Item^.OperationHandle];
if Assigned(OpManItem) then
begin
case Button of
mbLeft:
StartPauseOperation(OpManItem.Operation);
mbMiddle:
TfrmFileOp.ShowFor(OpManItem.Handle);
end;
end;
end;
end;
end;
var
ItemRect: TRect;
Item: POperationPanelItem;
begin
inherited MouseDown(Button, Shift, X, Y);
ClickPos := Point(X, Y);
ItemRect := ClientRect;
InflateRect(ItemRect, -PanelBorderWidth, -PanelBorderWidth);
ItemRect.Right := ItemRect.Left - HorizontalSpaceBetween;
for Item in FQueues do
begin
ItemRect.Left := ItemRect.Right + HorizontalSpaceBetween;
ItemRect.Right := ItemRect.Left + Item^.Width;
if PtInRect(ItemRect, ClickPos) then
begin
HandleItem(Item);
Exit;
end;
end;
for Item in FOperations do
begin
ItemRect.Left := ItemRect.Right + HorizontalSpaceBetween;
ItemRect.Right := ItemRect.Left + Item^.Width;
if PtInRect(ItemRect, ClickPos) then
begin
HandleItem(Item);
Exit;
end;
end;
end;
procedure TOperationsPanel.Paint;
var
OpManItem: TOperationsManagerItem;
ARect, ItemRect: TRect;
ColorFrom, ColorTo: TColor;
Queue: TOperationsManagerQueue;
Item: POperationPanelItem;
i: Integer;
procedure DrawString(s: String);
begin
// Draw output string
Canvas.Brush.Style := bsClear;
ARect := ItemRect;
InflateRect(ARect, -4, -2);
DrawText(Canvas.Handle, PChar(s), Length(s), ARect, DT_LEFT or DT_VCENTER or DT_NOPREFIX);
end;
procedure DrawProgress(State: TFileSourceOperationState; Progress: Double);
begin
// Draw progress bar
GetStateColor(State, ColorFrom, ColorTo);
ARect := ItemRect;
InflateRect(ARect, -1, -1);
ARect.Right := ARect.Left + Round((ARect.Right - ARect.Left) * Progress);
Canvas.GradientFill(ARect, ColorFrom, ColorTo, gdVertical);
end;
begin
inherited Paint;
ItemRect := ClientRect;
Canvas.Pen.Color:= cl3DDkShadow;
Canvas.Rectangle(ItemRect);
InflateRect(ItemRect, -PanelBorderWidth, -PanelBorderWidth);
Canvas.GradientFill(ItemRect, LightColor(clBtnHiLight, 20), clBtnFace, gdVertical);
ItemRect.Right := ItemRect.Left - HorizontalSpaceBetween;
i := 0;
while i < FQueues.Count do
begin
Item := FQueues[i];
Queue := OperationsManager.QueueByIdentifier[Item^.QueueId];
if Assigned(Queue) and (Queue.Count > 0) then
begin
OpManItem := Queue.Items[0];
if Assigned(OpManItem) then
begin
ItemRect.Left := ItemRect.Right + HorizontalSpaceBetween;
ItemRect.Right := ItemRect.Left + Item^.Width;
// Draw border
Canvas.Pen.Color := LightColor(cl3DDkShadow, 25);
Canvas.Brush.Style := bsSolid;
Canvas.Rectangle(ItemRect);
DrawProgress(OpManItem.Operation.State, OpManItem.Operation.Progress / Queue.Count);
DrawString(rsDlgQueue + ' ' + IntToStr(Queue.Identifier) + ' - ' +
GetProgressString(OpManItem.Operation.Progress / Queue.Count) +
LineEnding + GetOperationDescription(Queue.Items[0].Operation));
Inc(i);
end
else
DeleteItem(FQueues, i);
end
else
DeleteItem(FQueues, i);
end;
i := 0;
while i < FOperations.Count do
begin
Item := FOperations[i];
Queue := OperationsManager.QueueByIdentifier[Item^.QueueId];
if Assigned(Queue) and (Queue.Count > 0) then
begin
OpManItem := Queue.ItemByHandle[Item^.OperationHandle];
if Assigned(OpManItem) then
begin
ItemRect.Left := ItemRect.Right + HorizontalSpaceBetween;
ItemRect.Right := ItemRect.Left + Item^.Width;
if TfrmFileOp.IsOpenedFor(OpManItem.Handle) then
Canvas.Pen.Color := clMenuHighlight
else
Canvas.Pen.Color := LightColor(cl3DDkShadow, 40);
// Draw border
Canvas.Brush.Style := bsSolid;
Canvas.Rectangle(ItemRect);
DrawProgress(OpManItem.Operation.State, OpManItem.Operation.Progress);
DrawString(IntToStr(OpManItem.Handle) + ': ' +
GetOperationDescription(OpManItem.Operation) + ' - ' +
GetProgressString(OpManItem.Operation.Progress));
Inc(i);
end
else
DeleteItem(FOperations, i);
end
else
DeleteItem(FOperations, i);
end;
end;
procedure TOperationsPanel.StartPauseOperation(Operation: TFileSourceOperation);
begin
if Operation.State = fsosRunning then
Operation.Pause
else
Operation.Start;
end;
procedure TOperationsPanel.UpdateView;
begin
UpdateItems;
Invalidate;
end;
end.