mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
243 lines
7 KiB
ObjectPascal
243 lines
7 KiB
ObjectPascal
unit uConnectionManager;
|
|
|
|
{$mode delphi}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, uFileSource, uDrive, uDrivesList;
|
|
|
|
type
|
|
TFileSourceRecord = record
|
|
Count: Integer;
|
|
Name, Path: String;
|
|
FileSource: IFileSource;
|
|
end;
|
|
PFileSourceRecord = ^TFileSourceRecord;
|
|
|
|
function GetNetworkPath(ADrive: PDrive): String;
|
|
procedure UpdateDriveList(ADriveList: TDrivesList);
|
|
procedure ShowVirtualDriveMenu(ADrive: PDrive; X, Y : Integer; CloseEvent: TNotifyEvent);
|
|
|
|
procedure AddNetworkConnection(const Name, Path: String; FileSource: IFileSource);
|
|
procedure RemoveNetworkConnection(const Name, Path: String);
|
|
|
|
procedure CloseNetworkConnection();
|
|
|
|
var
|
|
WfxConnectionList: TStringList = nil;
|
|
|
|
implementation
|
|
|
|
uses
|
|
Forms, Menus, StrUtils, DCStrUtils, fMain, uWfxPluginFileSource, uLog,
|
|
uGlobs, uFileSourceUtil, uFileView;
|
|
|
|
var
|
|
ContextMenu: TPopupMenu = nil;
|
|
|
|
function GetConnectionName(const Name, Path: String): String; inline;
|
|
begin
|
|
Result:= Name + ': ' + Path;
|
|
end;
|
|
|
|
function NewFileSourceRecord(FileSource: IFileSource; const Name, Path: String): PFileSourceRecord;
|
|
begin
|
|
New(Result);
|
|
Result^.Count:= 1;
|
|
Result^.Name:= Name;
|
|
Result^.Path:= Path;
|
|
Result^.FileSource:= FileSource;
|
|
end;
|
|
|
|
procedure DisposeFileSourceRecord(FileSourceRecord: PFileSourceRecord);
|
|
begin
|
|
FileSourceRecord^.FileSource:= nil;
|
|
Dispose(FileSourceRecord);
|
|
end;
|
|
|
|
procedure CloseConnection(Index: Integer);
|
|
var
|
|
Connection: TFileSourceRecord;
|
|
FileSource: IWfxPluginFileSource;
|
|
begin
|
|
PFileSourceRecord(WfxConnectionList.Objects[Index]).Count:= 1;
|
|
Connection:= PFileSourceRecord(WfxConnectionList.Objects[Index])^;
|
|
FileSource:= Connection.FileSource as IWfxPluginFileSource;
|
|
if FileSource.WfxModule.WfxDisconnect(Connection.Path) then
|
|
begin
|
|
RemoveNetworkConnection(Connection.Name, Connection.Path);
|
|
end;
|
|
with frmMain do
|
|
begin
|
|
if ActiveFrame.FileSource.Equals(FileSource) and
|
|
IsInPath(Connection.Path, ActiveFrame.CurrentPath, True, True) then
|
|
begin
|
|
ActiveFrame.RemoveCurrentFileSource;
|
|
end
|
|
else if NotActiveFrame.FileSource.Equals(FileSource) and
|
|
IsInPath(Connection.Path, NotActiveFrame.CurrentPath, True, True) then
|
|
begin
|
|
NotActiveFrame.RemoveCurrentFileSource
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure OnNetworkDisconnect(Self, Sender: TObject);
|
|
var
|
|
Index: Integer;
|
|
MenuItem: TMenuItem absolute Sender;
|
|
begin
|
|
Index:= WfxConnectionList.IndexOf(MenuItem.Hint);
|
|
if Index >= 0 then CloseConnection(Index);
|
|
end;
|
|
|
|
function GetNetworkPath(ADrive: PDrive): String;
|
|
begin
|
|
Result:= ADrive^.DeviceId + StringReplace(ADrive^.Path, '\', '/', [rfReplaceAll]);
|
|
end;
|
|
|
|
procedure UpdateDriveList(ADriveList: TDrivesList);
|
|
var
|
|
Drive: PDrive;
|
|
Index: Integer;
|
|
FileSourceRecord: PFileSourceRecord;
|
|
begin
|
|
for Index:= 0 to WfxConnectionList.Count - 1 do
|
|
begin
|
|
FileSourceRecord:= PFileSourceRecord(WfxConnectionList.Objects[Index]);
|
|
New(Drive);
|
|
Drive^.DriveSize:= 0;
|
|
Drive^.IsMounted:= True;
|
|
Drive^.DriveType:= dtVirtual;
|
|
Drive^.Path:= FileSourceRecord.Path;
|
|
Drive^.DisplayName:= IntToStr(Index);
|
|
Drive^.DeviceId:= 'wfx://' + FileSourceRecord.Name;
|
|
Drive^.DriveLabel:= GetConnectionName(FileSourceRecord.Name, FileSourceRecord.Path);
|
|
ADriveList.Add(Drive);
|
|
end;
|
|
end;
|
|
|
|
procedure ShowVirtualDriveMenu(ADrive: PDrive; X, Y: Integer; CloseEvent: TNotifyEvent);
|
|
var
|
|
Handler: TMethod;
|
|
MenuItem: TMenuItem;
|
|
begin
|
|
if not StrBegins(ADrive^.DeviceId, 'wfx://') then
|
|
Exit;
|
|
|
|
// Free previous created menu
|
|
FreeAndNil(ContextMenu);
|
|
|
|
// Create new context menu
|
|
ContextMenu:= TPopupMenu.Create(nil);
|
|
ContextMenu.OnClose := CloseEvent;
|
|
|
|
MenuItem:= TMenuItem.Create(ContextMenu);
|
|
MenuItem.Caption:= ADrive.DriveLabel;
|
|
MenuItem.Enabled:= False;
|
|
ContextMenu.Items.Add(MenuItem);
|
|
|
|
MenuItem:= TMenuItem.Create(ContextMenu);
|
|
MenuItem.Caption:= '-';
|
|
ContextMenu.Items.Add(MenuItem);
|
|
|
|
MenuItem:= TMenuItem.Create(ContextMenu);
|
|
MenuItem.Caption:= frmMain.actNetworkDisconnect.Caption;
|
|
MenuItem.Hint:= ADrive.DriveLabel;
|
|
Handler.Data:= MenuItem;
|
|
Handler.Code:= @OnNetworkDisconnect;
|
|
MenuItem.OnClick:= TNotifyEvent(Handler);
|
|
ContextMenu.Items.Add(MenuItem);
|
|
|
|
// Show context menu
|
|
ContextMenu.PopUp(X, Y);
|
|
end;
|
|
|
|
procedure AddNetworkConnection(const Name, Path: String; FileSource: IFileSource);
|
|
var
|
|
Index: Integer;
|
|
ConnectionName: String;
|
|
FileSourceRecord: PFileSourceRecord;
|
|
begin
|
|
ConnectionName:= GetConnectionName(Name, Path);
|
|
Index:= WfxConnectionList.IndexOf(ConnectionName);
|
|
if Index >= 0 then begin
|
|
FileSourceRecord:= PFileSourceRecord(WfxConnectionList.Objects[Index]);
|
|
FileSourceRecord.Count:= FileSourceRecord.Count + 1;
|
|
end
|
|
else begin
|
|
FileSourceRecord:= NewFileSourceRecord(FileSource, Name, Path);
|
|
WfxConnectionList.AddObject(ConnectionName, TObject(FileSourceRecord));
|
|
with frmMain do
|
|
begin
|
|
miNetworkDisconnect.Enabled:= WfxConnectionList.Count > 0;
|
|
UpdateDiskCount;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure RemoveNetworkConnection(const Name, Path: String);
|
|
var
|
|
Index: Integer;
|
|
ConnectionName: String;
|
|
FileSourceRecord: PFileSourceRecord;
|
|
begin
|
|
ConnectionName:= GetConnectionName(Name, Path);
|
|
Index:= WfxConnectionList.IndexOf(ConnectionName);
|
|
if Index >= 0 then
|
|
with frmMain do
|
|
begin
|
|
FileSourceRecord:= PFileSourceRecord(WfxConnectionList.Objects[Index]);
|
|
FileSourceRecord^.Count:= FileSourceRecord^.Count - 1;
|
|
if FileSourceRecord^.Count > 0 then Exit;
|
|
DisposeFileSourceRecord(PFileSourceRecord(WfxConnectionList.Objects[Index]));
|
|
WfxConnectionList.Delete(Index);
|
|
miNetworkDisconnect.Enabled:= WfxConnectionList.Count > 0;
|
|
if WfxConnectionList.Count = 0 then
|
|
begin
|
|
if gLogWindow = False then
|
|
begin
|
|
ShowLogWindow(PtrInt(False));
|
|
end;
|
|
end;
|
|
UpdateDiskCount;
|
|
end;
|
|
end;
|
|
|
|
procedure CloseNetworkConnection;
|
|
var
|
|
Index: Integer;
|
|
ConnectionName: String;
|
|
FileView: TFileView = nil;
|
|
begin
|
|
if WfxConnectionList.Count > 0 then
|
|
with frmMain do
|
|
begin
|
|
if ActiveFrame.FileSource.IsInterface(IWfxPluginFileSource) and (ActiveFrame.CurrentPath <> PathDelim) then
|
|
FileView:= ActiveFrame
|
|
else if NotActiveFrame.FileSource.IsInterface(IWfxPluginFileSource) and (NotActiveFrame.CurrentPath <> PathDelim) then begin
|
|
FileView:= NotActiveFrame
|
|
end;
|
|
if Assigned(FileView) then
|
|
begin
|
|
ConnectionName:= ExtractWord(2, FileView.CurrentAddress, ['/']);
|
|
ConnectionName:= GetConnectionName(ConnectionName, PathDelim + ExtractWord(1, FileView.CurrentPath, [PathDelim]));
|
|
Index:= WfxConnectionList.IndexOf(ConnectionName);
|
|
if Index >= 0 then CloseConnection(Index);
|
|
end
|
|
// Close last connection
|
|
else begin
|
|
CloseConnection(WfxConnectionList.Count - 1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
initialization
|
|
WfxConnectionList:= TStringList.Create;
|
|
|
|
finalization
|
|
FreeAndNil(WfxConnectionList);
|
|
|
|
end.
|
|
|