1
0
mirror of https://github.com/winscp/winscp.git synced 2026-10-24 02:28:55 +03:00
Files
winscp/source/packages/filemng/FileOperator.pas
Martin Prikryl b6538ca27f Removing some unused code
Source commit: 6be26458abcef70a5b7978296a6a3430a7e8fdee
2025-09-24 01:11:17 +02:00

303 lines
13 KiB
ObjectPascal

unit FileOperator;
{
+------------------------------------------------------------------------------+
| TFileOperator Component Version 1.02 / 1999 |
+------------------------------------------------------------------------------+
| Author: Ingo Eckel |
| |
| Based on the TFileOperator component written by Glen Why 1996 |
| Enhancements: uses TStringList as operands, undo functionality implemented. |
+------------------------------------------------------------------------------+
| Description: |
| This component encapsulates the ShFileOperation API of Microsoft Windows. |
| Performs a copy, move, rename, or delete operation on a file system object. |
| It also allows to undo the last operation, if a copy or move operation |
| was performed. |
+------------------------------------------------------------------------------+
| Properties: |
| |
| OperandFrom: |
| Stringlist, that contains the names of the source files, |
| wildcard filename (*.*) is accepted. |
| |
| OperandTo: |
| Stringlist that specifies the destination for the moved, |
| copied or renamed file. Should be the target directory, when |
| performing a copy or move operation. |
| |
| WantMappingHandle: True, if shFileOperation should create a filename- |
| mapping of the processed files. This mapping is allocated by |
| shFileOperation and will be automatically deallocated by the |
| component. |
| |
| Operation: |
| -foCopy Copies the files specified by OperandFrom to the location |
| specified by OperandTo. |
| -foDelete Deletes the files specified by OperandFrom (OperandTo |
| ignored). |
| -foMove Moves the files specified by OperandFrom to the location |
| specified by OperandTo. |
| -foRename Renames the files specified by OperandFrom. |
| |
| Options: |
| -foAllowUndo Preserves undo information, if possible. |
| -foConfirmMouse Not implemented. |
| -foFilesOnly Performs the operation only on files if a wildcard |
| filename (*.*) is specified. |
| -foMultiDestFiles Indicates that the OperandTo member specifies multiple|
| destination files (one for each source file) rather |
| than one directory where all source files are |
| to be deposited. |
| Note: not compatible with undo operation. |
| -foNoConfirmation Responds with "yes to all" for any dialog box that |
| is displayed. |
| -fofNoConfirmMkDir Does not confirm the creation of a new directory |
| if the operation requires one to be created. |
| -foRenameOnCollision Gives the file being operated on a new name |
| (such as "Copy #1 of...") in a move, copy, |
| or rename operation if a file of the target name |
| already exists. |
| Note: not compatible with undo operation. |
| -foSilent Does not display a progress dialog box. |
| -foSimpleProgress Displays a progress dialog box, but does not show |
| the filenames. |
| |
| Title: String to use as the title for a progress dialog box. |
| This member is used only if Options includes fofSimpleProgress. |
| |
| WantMappingHandle After execution should a file mapping be returned. |
| Works only, when option foMultiDestFiles used. |
| Note: don't know, how to use this. |
| |
+------------------------------------------------------------------------------+
| Methods: |
| |
| Function Execute : Boolean; |
| Performs the copy, move, rename, or delete operation. |
| Returns zero if successful or nonzero value if an error occurs. |
| |
+------------------------------------------------------------------------------+
| Events: |
+------------------------------------------------------------------------------+
}
{==============================================================}
interface
{==============================================================}
uses
Windows, Classes, Forms, Controls, ShellAPI, BaseUtils, SysUtils;
Type
TFileOperation = ( foCopy, foDelete, foMove, foRename );
TFileOperationFlag = ( foAllowUndo, foConfirmMouse, foFilesOnly,
foMultiDestFiles, foNoConfirmation, foNoConfirmMkDir,
foRenameOnCollision, foSilent, foSimpleProgress);
TFileOperationFlags = set of TFileOperationFlag;
{==============================================================}
TFileOperator = class
{==============================================================}
private
{==============================================================}
FData : TShFileOpStruct;
FFrom : TStringList;
FTo : TStringList;
fOwner : TWinControl;
Procedure SetOperation( Value :TFileOperation );
Function GetOperation :TFileOperation;
Function GetWantMappingHandle :Boolean;
Procedure SetWantMappingHandle ( Value :Boolean );
Procedure SetFlags( Value :TFileOperationFlags );
Function GetFlags :TFileOperationFlags;
Function GetOperFlag( F :Cardinal ) :Boolean;
Procedure SetOperFlag( F :Cardinal; V :Boolean );
{==============================================================}
public
{==============================================================}
Property OperandFrom : TStringList Read fFrom Write fFrom;
Property OperandTo : TStringList Read FTo Write fTo;
Constructor Create(Owner: TWinControl);
Destructor Destroy; override;
Function Execute : Boolean;
{==============================================================}
published
{==============================================================}
Property Operation : TFileOperation Read GetOperation Write SetOperation Stored false;
Property Flags : TFileOperationFlags Read GetFlags Write SetFlags Stored false;
Property WantMappingHandle :Boolean Read GetWantMappingHandle Write SetWantMappingHandle Stored false;
end;
const
FileOperatorDefaultFlags = [foAllowUndo, foNoConfirmMkDir];
{==============================================================}
implementation
{==============================================================}
uses
PasTools;
{ TFileOperator }
procedure TFileOperator.SetOperation( Value :TFileOperation );
begin
with FData do
case Value of
foCopy : wFunc := FO_COPY;
foDelete : wFunc := FO_DELETE;
foRename : wFunc := FO_RENAME;
foMove : wFunc := FO_MOVE;
end;
end; {SetOperation}
function TFileOperator.GetOperation :TFileOperation;
begin
result := foCopy;
case FData.wFunc of
FO_COPY : result := foCopy;
FO_DELETE : result := foDelete;
FO_RENAME : result := foRename;
FO_MOVE : result := foMove;
end;
end; {GetOperation}
function TFileOperator.GetWantMappingHandle :Boolean;
begin
result := GetOperFlag( FOF_WANTMAPPINGHANDLE );
end;
procedure TFileOperator.SetWantMappingHandle ( Value :Boolean );
begin
SetOperFlag( FOF_WANTMAPPINGHANDLE, Value );
end;
procedure TFileOperator.SetFlags( Value :TFileOperationFlags );
begin
SetOperFlag( FOF_ALLOWUNDO, foAllowUndo in Value );
SetOperFlag( FOF_CONFIRMMOUSE, foConfirmMouse in Value );
SetOperFlag( FOF_FILESONLY, foFilesOnly in Value );
SetOperFlag( FOF_MULTIDESTFILES, foMultiDestFiles in Value );
SetOperFlag( FOF_NOCONFIRMATION, foNoConfirmation in Value );
SetOperFlag( FOF_NOCONFIRMMKDIR, foNoConfirmMkDir in Value );
SetOperFlag( FOF_RENAMEONCOLLISION, foRenameOnCollision in Value );
SetOperFlag( FOF_SILENT, foSilent in Value );
SetOperFlag( FOF_SIMPLEPROGRESS, foSimpleProgress in Value );
end; {SetFlags}
function TFileOperator.GetFlags :TFileOperationFlags;
begin
result := [];
if GetOperFlag( FOF_ALLOWUNDO ) then include( result, foAllowUndo );
if GetOperFlag( FOF_CONFIRMMOUSE ) then include( result, foConfirmMouse );
if GetOperFlag( FOF_FILESONLY ) then include( result, foFilesOnly );
if GetOperFlag( FOF_MULTIDESTFILES ) then include( result, foMultiDestFiles );
if GetOperFlag( FOF_NOCONFIRMATION ) then include( result, foNoConfirmation );
if GetOperFlag( FOF_NOCONFIRMMKDIR ) then include( result, foNoConfirmMkDir );
if GetOperFlag( FOF_RENAMEONCOLLISION ) then include( result, foRenameOnCollision );
if GetOperFlag( FOF_SILENT ) then include( result, foSilent );
if GetOperFlag( FOF_SIMPLEPROGRESS ) then include( result, foSimpleProgress );
end; {GetFlags}
function TFileOperator.GetOperFlag( F :Cardinal ):boolean;
begin
result := ( FData.fFlags and F ) <> 0;
end;
procedure TFileOperator.SetOperFlag( F :Cardinal; V :Boolean );
begin
with FData do
if V then
fFlags := fFlags or F
else fFlags := fFlags and ( not F );
end;
Constructor TFileOperator.Create(Owner: TWinControl);
begin
inherited Create;
fFrom := TStringList.Create;
fTo := TStringList.Create;
fOwner := Owner;
FData.fFlags := 0;
Flags := FileOperatorDefaultFlags;
end; {Create}
function TFileOperator.Execute : Boolean;
Var SFrom : String;
sTo : String;
Function ConvertOperand(List : TStringList) : String;
Var i : Integer;
Begin
Result := '';
For i := 0 to Pred(List.Count) Do
Begin
// SHFileOperation does not support long paths anyway
Result := Result + ApiPath(List[i]);
SetLength(Result, Succ(Length(Result)));
Result[Length(Result)] := #0;
End;
SetLength(Result, Succ(Length(Result)));
Result[Length(Result)] := #0;
End; {ConvertOperand}
begin {Execute}
SFrom := ConvertOperand(FFrom);
STo := ConvertOperand(FTo);
FData.pFrom := PChar( SFrom );
FData.pTo := PChar( STo );
IF Assigned(fOwner) and fOwner.HandleAllocated Then
FData.Wnd := fOwner.Handle
Else
FData.Wnd := Application.Handle;
Try
IF Assigned(FData.hNameMappings) Then
shFreeNameMappings(THandle(FData.hNameMappings));
Finally
FData.hNameMappings := NIL;
End;
Try
Try
IF Operation = foRename Then
Result := RenameFile(FFrom[0], FTo[0])
Else
Result := ShFileOperation( FData ) = 0;
Finally
FFrom.Clear;
FTo.Clear;
End;
Except
Result := False;
End;
end; {Execute}
destructor TFileOperator.Destroy;
begin
IF Assigned(FFrom) Then
FFrom.Free;
IF Assigned(FTo) Then
FTo.Free;
IF Assigned(FData.hNameMappings) Then
shFreeNameMappings(THandle(FData.hNameMappings));
inherited Destroy;
end; {Destroy}
end.