ADD: MacCloud/DropBox step-37: rename(F2) / create(F7) / delete(F8) Connections

This commit is contained in:
rich2014 2025-04-10 22:14:21 +08:00
commit 3faad8190a
3 changed files with 136 additions and 59 deletions

View file

@ -38,15 +38,19 @@ const
type
{ TCloudRootListFolder }
{ TCloudRootDriver }
TCloudRootListFolder = class( TCloudListFolder )
TCloudRootDriver = class( TCloudDriver )
private
_list: TFPList;
public
procedure listFolderBegin(const path: String); override;
function listFolderGetNextFile: TCloudFile; override;
procedure listFolderEnd; override;
public
procedure createFolder(const path: String); override;
procedure delete(const path: String); override;
procedure copyOrMove(const fromPath: String; const toPath: String; const needToMove: Boolean); override;
end;
procedure loadConfig( const path: String );
@ -64,7 +68,6 @@ end;
procedure ExtensionInitialize(StartupInfo: PExtensionStartupInfo); cdecl;
var
configPath: String;
pluginPath: String;
begin
try
configPath:= StartupInfo^.PluginConfDir + 'MacCloud.json';
@ -95,8 +98,8 @@ function FsFindFirstW(
path: pwidechar;
var FindData: TWIN32FINDDATAW ): THandle; cdecl;
var
parser: TCloudPathParser;
listFolder: TCloudListFolder;
parser: TCloudPathParser = nil;
driver: TCloudDriver;
function doFindFirst: THandle;
var
@ -106,12 +109,12 @@ var
utf8Path:= TStringUtil.widecharsToString(path);
parser:= TCloudPathParser.Create( utf8Path );
if utf8Path = PathDelim then
listFolder:= TCloudRootListFolder.Create
driver:= TCloudRootDriver.Create
else
listFolder:= parser.driver;
Result:= THandle( listFolder );
listFolder.listFolderBegin( parser.driverPath );
cloudFile:= listFolder.listFolderGetNextFile;
driver:= parser.driver;
Result:= THandle( driver );
driver.listFolderBegin( parser.driverPath );
cloudFile:= driver.listFolderGetNextFile;
if cloudFile = nil then
Exit( wfxInvalidHandle );
@ -132,20 +135,20 @@ begin
end;
end;
if (Result=wfxInvalidHandle) and Assigned(listFolder) then
listFolder.listFolderEnd;
if (Result=wfxInvalidHandle) and Assigned(driver) then
driver.listFolderEnd;
end;
function FsFindNextW(
handle: THandle;
var FindData:tWIN32FINDDATAW ): Bool; cdecl;
var
listFolder: TCloudListFolder;
driver: TCloudDriver;
cloudFile: TCloudFile;
begin
try
listFolder:= TCloudListFolder( handle );
cloudFile:= listFolder.listFolderGetNextFile;
driver:= TCloudDriver( handle );
cloudFile:= driver.listFolderGetNextFile;
if cloudFile = nil then
Exit( False );
@ -161,12 +164,12 @@ end;
function FsFindClose( handle: THandle ): Integer; cdecl;
var
listFolder: TCloudListFolder;
driver: TCloudDriver;
begin
Result:= 0;
try
listFolder:= TCloudListFolder( handle );
listFolder.listFolderEnd;
driver:= TCloudDriver( handle );
driver.listFolderEnd;
except
on e: Exception do begin
TMacCloudUtil.exceptionToResult( e );
@ -181,8 +184,8 @@ function FsGetFileW(
RemoteInfo: pRemoteInfo ): Integer; cdecl;
var
parser: TCloudPathParser;
callback: TCloudProgressCallback;
parser: TCloudPathParser = nil;
callback: TCloudProgressCallback = nil;
function doGetFile: Integer;
var
@ -194,6 +197,8 @@ var
begin
parser:= TCloudPathParser.Create( TStringUtil.widecharsToString(RemoteName) );
serverPath:= parser.driverPath;
if serverPath = EmptyStr then
raise ENotSupportedException.Create( 'Connection not support copying' );
localPath:= TStringUtil.widecharsToString( LocalName );
li.LowPart:= RemoteInfo^.SizeLow;
li.HighPart:= RemoteInfo^.SizeHigh;
@ -241,8 +246,8 @@ function FsPutFileW(
const
FS_EXISTS = FS_COPYFLAGS_EXISTS_SAMECASE or FS_COPYFLAGS_EXISTS_DIFFERENTCASE;
var
parser: TCloudPathParser;
callback: TCloudProgressCallback;
parser: TCloudPathParser = nil;
callback: TCloudProgressCallback = nil;
function doPutFile: Integer;
var
@ -253,6 +258,9 @@ var
begin
parser:= TCloudPathParser.Create( TStringUtil.widecharsToString(RemoteName) );
serverPath:= parser.driverPath;
if serverPath = EmptyStr then
raise ENotSupportedException.Create( 'Connection not support copying' );
localPath:= TStringUtil.widecharsToString( LocalName );
totalBytes:= TFileUtil.filesize( localPath );
exits:= (CopyFlags and FS_EXISTS <> 0);
@ -293,12 +301,20 @@ end;
function FsMkDirW( RemoteDir: pwidechar ): Bool; cdecl;
var
parser: TCloudPathParser;
parser: TCloudPathParser = nil;
procedure doCreateFolder;
var
driver: TCloudDriver;
begin
parser:= TCloudPathParser.Create( TStringUtil.widecharsToString(RemoteDir) );
parser.driver.createFolder( parser.driverPath );
if parser.driverPath = EmptyStr then begin
driver:= TCloudRootDriver.Create;
driver.createFolder( parser.connectionName );
end else begin
driver:= parser.driver;
driver.createFolder( parser.driverPath );
end;
end;
begin
@ -319,12 +335,22 @@ end;
function FsDeleteFileW( RemoteName: pwidechar ): Bool; cdecl;
var
parser: TCloudPathParser;
parser: TCloudPathParser = nil;
procedure doDelete;
var
utf8Path: String;
driver: TCloudDriver;
begin
parser:= TCloudPathParser.Create( TStringUtil.widecharsToString(RemoteName) );
parser.driver.delete( parser.driverPath );
utf8Path:= TStringUtil.widecharsToString(RemoteName);
parser:= TCloudPathParser.Create( utf8Path );
if parser.driverPath = EmptyStr then begin
driver:= TCloudRootDriver.Create;
driver.delete( parser.connectionName );
end else begin
driver:= parser.driver;
driver.delete( parser.driverPath );
end;
end;
begin
@ -354,22 +380,29 @@ function FsRenMovFileW(
Move, OverWrite: Bool;
RemoteInfo: pRemoteInfo ): Integer; cdecl;
var
parserOld: TCloudPathParser;
parserNew: TCloudPathParser;
parserOld: TCloudPathParser = nil;
parserNew: TCloudPathParser = nil;
function doCopyOrMove: Integer;
var
ret: Boolean;
driver: TCloudDriver;
begin
parserOld:= TCloudPathParser.Create( TStringUtil.widecharsToString(OldName) );
parserNew:= TCloudPathParser.Create( TStringUtil.widecharsToString(NewName) );
if parserOld.connection <> parserNew.connection then
raise ENotSupportedException.Create( 'Internal copy/move functions cannot be used between different accounts' );
ret:= macCloudPlugin.progress( oldName, newName, 0 ) = 0;
if ret then begin
parserNew.driver.copyOrMove( parserOld.driverPath, parserNew.driverPath, Move );
parserOld:= TCloudPathParser.Create( TStringUtil.widecharsToString(OldName) );
parserNew:= TCloudPathParser.Create( TStringUtil.widecharsToString(NewName) );
if parserOld.driverPath = EmptyStr then begin
if parserNew.driverPath <> EmptyStr then
raise ENotSupportedException.Create( 'Connection not support copying' );
driver:= TCloudRootDriver.Create;
driver.copyOrMove( parserOld.connectionName, parserNew.connectionName, True );
end else begin
if parserOld.connection <> parserNew.connection then
raise ENotSupportedException.Create( 'Internal copy/move functions cannot be used between different accounts' );
driver:= parserNew.driver;
driver.copyOrMove( parserOld.driverPath, parserNew.driverPath, Move );
end;
macCloudPlugin.progress( oldName, newName, 100 );
Result:= FS_FILE_OK;
end else
@ -395,7 +428,7 @@ function FsExecuteFileW(
RemoteName: pwidechar;
Verb: pwidechar ): Integer; cdecl;
var
parser: TCloudPathParser;
parser: TCloudPathParser = nil;
function doExecute: Integer;
var
@ -449,9 +482,9 @@ begin
strlcopy( DefRootName, 'cloud', maxlen );
end;
{ TCloudRootListFolder }
{ TCloudRootDriver }
procedure TCloudRootListFolder.listFolderBegin(const path: String);
procedure TCloudRootDriver.listFolderBegin(const path: String);
procedure addNewCommand;
var
cloudFile: TCloudFile;
@ -485,7 +518,7 @@ begin
addConnections;
end;
function TCloudRootListFolder.listFolderGetNextFile: TCloudFile;
function TCloudRootDriver.listFolderGetNextFile: TCloudFile;
begin
if _list.Count > 0 then begin
Result:= TCloudFile( _list.First );
@ -495,10 +528,40 @@ begin
end;
end;
procedure TCloudRootListFolder.listFolderEnd;
procedure TCloudRootDriver.listFolderEnd;
begin
FreeAndNil( _list );
self.Free;
end;
procedure TCloudRootDriver.createFolder(const path: String);
begin
TCloudOptionsUtil.addAndShow( path );
saveConfig( macCloudPlugin.configPath );
end;
procedure TCloudRootDriver.delete(const path: String);
var
connectionName: String absolute path;
begin
TLogUtil.logInformation( 'Connection Deleted: ' + connectionName );
cloudConnectionManager.delete( connectionName );
saveConfig( macCloudPlugin.configPath );
end;
procedure TCloudRootDriver.copyOrMove(const fromPath: String;
const toPath: String; const needToMove: Boolean);
var
connectionOldName: String absolute fromPath;
connectionNewName: String absolute toPath;
connection: TCloudConnection;
begin
if NOT needToMove then
raise ENotSupportedException.Create( 'Connection only support renaming' );
TLogUtil.logInformation( 'Connection Rename: ' + connectionOldName + ' --> ' + connectionNewName );
connection:= cloudConnectionManager.get( connectionOldName );
connection.name:= connectionNewName;
saveConfig( macCloudPlugin.configPath );
end;
end.

View file

@ -50,14 +50,7 @@ type
TCloudFiles = TFPList;
TCloudListFolder = class
public
procedure listFolderBegin( const path: String ); virtual; abstract;
function listFolderGetNextFile: TCloudFile; virtual; abstract;
procedure listFolderEnd; virtual; abstract;
end;
TCloudDriver = class( TCloudListFolder )
TCloudDriver = class
public
class function driverName: String; virtual; abstract;
class function isMatched( const name: String ): Boolean; virtual; abstract;
@ -68,6 +61,10 @@ type
function authorize: Boolean; virtual; abstract;
procedure unauthorize; virtual; abstract;
function authorized: Boolean; virtual; abstract;
public
procedure listFolderBegin( const path: String ); virtual; abstract;
function listFolderGetNextFile: TCloudFile; virtual; abstract;
procedure listFolderEnd; virtual; abstract;
public
procedure download(
const serverPath: String;
@ -123,7 +120,7 @@ type
constructor Create( const name: String; const driver: TCloudDriver;
const creationTime: TDateTime; const modificationTime: TDateTime );
destructor Destroy; override;
property name: String read _name;
property name: String read _name write _name;
property driver: TCloudDriver read _driver;
property creationTime: TDateTime read _creationTime;
property modificationTime: TDateTime read _modificationTime;
@ -144,6 +141,7 @@ type
public
procedure add( const connection: TCloudConnection );
function get( const name: String ): TCloudConnection;
procedure delete( const name: String );
property connections: TCloudConnections read _connections write setConnections;
end;
@ -284,6 +282,14 @@ begin
raise EArgumentException.Create( 'Connection not found in TCloudConnectionManager.get(): ' + name );
end;
procedure TCloudConnectionManager.delete(const name: String);
var
connection: TCloudConnection;
begin
connection:= self.get( name );
_connections.Remove( connection );
end;
initialization
cloudDriverManager:= TCloudDriverManager.Create;
cloudConnectionManager:= TCloudConnectionManager.Create;

View file

@ -19,8 +19,8 @@ type
private
class function createWindow: NSWindow;
public
class procedure show( const connectionName: String);
class procedure addAndShow;
class procedure show( const connectionName: String );
class procedure addAndShow( const connectionName: String = '' );
end;
implementation
@ -71,7 +71,7 @@ type
TCloudConfigItemsController = objcprotocol
function getConfigItems: NSArray; message 'TCloudConfigItemsController_getConfigItems';
procedure addConnection( sender: NSObject ); message 'TCloudConfigItemsController_addConnection:';
procedure newConnection( sender: NSObject ); message 'TCloudConfigItemsController_newConnection:';
procedure removeConnection( sender: NSObject ); message 'TCloudConfigItemsController_removeConnection:';
procedure saveConnection( sender: NSObject ); message 'TCloudConfigItemsController_saveConnection:';
procedure connectOrDisconnect( sender: NSObject ); message 'TCloudConfigItemsController_connectOrDisconnect:';
@ -121,10 +121,11 @@ type
public
procedure dealloc; override;
function getConfigItems: NSArray;
procedure addConnection( connectionName: NSString ); message 'TCloudOptionsWindow_addConnection:';
procedure loadConnections; message 'TCloudOptionsWindow_loadConnections';
procedure saveConnections; message 'TCloudOptionsWindow_saveConnections';
procedure selectConnection( name: NSString ); message 'TCloudOptionsWindow_selectConnection:';
procedure addConnection( sender: NSObject );
procedure newConnection( sender: NSObject );
procedure removeConnection( sender: NSObject );
procedure saveConnection( sender: NSObject );
procedure connectOrDisconnect( sender: NSObject );
@ -298,13 +299,15 @@ begin
end;
end;
procedure TCloudOptionsWindow.addConnection(sender: NSObject);
procedure TCloudOptionsWindow.addConnection( connectionName: NSString );
var
configItem: TConnectionConfigItem;
begin
if connectionName.length = 0 then
connectionName:= StringToNSString( 'New Connection' );
configItem:= TConnectionConfigItem.new;
configItem.setCreating( True );
configItem.setName( StringToNSString( 'New Connection *' ) );
configItem.setName( connectionName );
configItem.setDriver( cloudDriverManager.createInstance('DropBox') );
configItem.setCreationTime( LocalTimeToUniversal(now) );
configItem.setModificationTime( configItem.creationTime );
@ -314,6 +317,11 @@ begin
self.connectionListView.selectRow_byExtendingSelection( self.configItems.count-1, False );
end;
procedure TCloudOptionsWindow.newConnection(sender: NSObject);
begin
self.addConnection( nil );
end;
procedure TCloudOptionsWindow.removeConnection(sender: NSObject);
var
currentIndex: Integer;
@ -493,7 +501,7 @@ var
addButton.setBezelStyle( NSSmallSquareBezelStyle );
addButton.setImage( NSImage.imageNamed(NSImageNameAddTemplate) );
addButton.setTarget( win );
addButton.setAction( ObjCSelector('TCloudConfigItemsController_addConnection:') );
addButton.setAction( ObjCSelector('TCloudConfigItemsController_newConnection:') );
leftView.addSubview( addButton );
addButton.release;
@ -614,12 +622,12 @@ begin
NSApplication(NSApp).runModalForWindow( win );
end;
class procedure TCloudOptionsUtil.addAndShow;
class procedure TCloudOptionsUtil.addAndShow( const connectionName: String = '' );
var
win: NSWindow;
begin
win:= self.createWindow;
TCloudOptionsWindow(win).addConnection( nil );
TCloudOptionsWindow(win).addConnection( StringToNSString(connectionName) );
NSApplication(NSApp).runModalForWindow( win );
end;