summaryrefslogtreecommitdiff
path: root/UConnectionManager.pas
diff options
context:
space:
mode:
Diffstat (limited to 'UConnectionManager.pas')
-rw-r--r--UConnectionManager.pas190
1 files changed, 174 insertions, 16 deletions
diff --git a/UConnectionManager.pas b/UConnectionManager.pas
index 0fbb4d1..dc97e20 100644
--- a/UConnectionManager.pas
+++ b/UConnectionManager.pas
@@ -24,7 +24,7 @@ interface
uses
glib2, gdk2, gtk2, pango, SysUtils, Types, Classes, GTKControls, GTKForms, GTKStdCtrls, GTKExtCtrls, GTKConsts, GTKView,
GTKUtils, GTKDialogs, GTKPixbuf, GTKClasses,
- UCoreClasses;
+ UCore, UCoreClasses, UVFSCore, UEngines, URemoteWait;
type
TFConnectionManager = class(TGTKDialog)
@@ -38,6 +38,8 @@ type
ListViewTable: TGTKTable;
AddConnectionButton, EditButton, RemoveButton: TGTKImageButton;
ButtonBox: TGTKVButtonBox;
+ ActionButtonBox: TGTKHButtonBox;
+ ConnectButton, CloseButton: TGTKButton;
procedure FormCreate(Sender: TObject); override;
procedure ListViewSelectionChanged(Sender: TObject);
procedure FormKeyDown(Sender: TObject; Key: Word; Shift: TShiftState; var Accept: boolean);
@@ -46,8 +48,18 @@ type
procedure RemoveButtonClick(Sender: TObject);
procedure ListViewDblClick(Sender: TObject; Button: TGDKMouseButton; Shift: TShiftState; X, Y: Integer; var Accept: boolean);
procedure ListViewKeyDown(Sender: TObject; Key: Word; Shift: TShiftState; var Accept: boolean);
+ procedure CloseButtonClick(Sender: TObject);
+ procedure ConnectButtonClick(Sender: TObject);
private
+ FSilenceError: boolean;
+ AFRemoteWait: TFRemoteWait;
+ FActiveConnInfo: TConnMgrItem;
+ FVFSAskPasswordTry: integer;
procedure FillList;
+ procedure DoConnect;
+ public
+ SourcePanelEngine: TPanelEngine;
+ ConnectedEngine: TVFSEngine;
end;
var
@@ -55,19 +67,32 @@ var
implementation
-uses ULocale, UCoreUtils, UConfig, UCore, UConnectionProperties, UVFSCore;
-
-const Connect_Button_ID = integer(mbOK);
+uses ULocale, UCoreUtils, UConfig, UConnectionProperties, UGnome, uVFSprototypes;
procedure TFConnectionManager.FormCreate(Sender: TObject);
var Column: TGTKTreeViewColumn;
begin
+ ConnectedEngine := nil;
SetDefaultSize(550, 450);
Caption := LANGConnMgr_Caption;
- AddButton(LANGConnMgr_ConnectButton, Connect_Button_ID);
- Buttons := [mbClose];
+ Buttons := [];
ShowSeparator := False;
+
+ ConnectButton := TGTKButton.Create(Self);
+ ConnectButton.Caption := LANGConnMgr_ConnectButton;
+// ConnectButton.Default := True;
+ CloseButton := TGTKButton.CreateFromStock(Self, GTK_STOCK_CLOSE);
+// Default := ConnectButton;
+ ActionButtonBox := TGTKHButtonBox.Create(Self);
+ ActionButtonBox.Layout := blEnd;
+ ActionButtonBox.Spacing := 10;
+ ActionButtonBox.BorderWidth := 0;
+ ActionButtonBox.AddControlEnd(CloseButton);
+ ActionButtonBox.AddControlEnd(ConnectButton);
+
+ ActionArea.AddControlEx(ActionButtonBox, False, False, 0);
+
TitleEventBox := TGTKEventBox.Create(Self);
TitleLabel := TGTKLabel.Create(Self);
TitleLabel.Caption := Format('<span size="x-large" weight="ultrabold">%s</span>', [LANGConnMgr_OpenConnection]);
@@ -158,6 +183,8 @@ begin
AddConnectionButton.OnClick := AddConnectionButtonClick;
EditButton.OnClick := EditButtonClick;
RemoveButton.OnClick := RemoveButtonClick;
+ CloseButton.OnClick := CloseButtonClick;
+ ConnectButton.OnClick := ConnectButtonClick;
OnKeyDown := FormKeyDown;
end;
@@ -166,21 +193,21 @@ begin
try
EditButton.Enabled := Assigned(ListView.Selected);
RemoveButton.Enabled := Assigned(ListView.Selected);
- SetResponseSensitive(Connect_Button_ID, Assigned(ListView.Selected));
+ ConnectButton.Enabled := Assigned(ListView.Selected);
except end;
end;
procedure TFConnectionManager.FormKeyDown(Sender: TObject; Key: Word; Shift: TShiftState; var Accept: boolean);
begin
case Key of
- GDK_RETURN, GDK_KP_ENTER: if Assigned(ListView.Selected) then ModalResult := mbOK;
+ GDK_RETURN, GDK_KP_ENTER: if Assigned(ListView.Selected) then DoConnect;
GDK_ESCAPE: ModalResult := mbCancel;
end;
end;
procedure TFConnectionManager.ListViewDblClick(Sender: TObject; Button: TGDKMouseButton; Shift: TShiftState; X, Y: Integer; var Accept: boolean);
begin
- if Assigned(ListView.Selected) then ModalResult := mbOK;
+ if Assigned(ListView.Selected) then DoConnect;
end;
procedure TFConnectionManager.ListViewKeyDown(Sender: TObject; Key: Word; Shift: TShiftState; var Accept: boolean);
@@ -202,8 +229,7 @@ begin
ConnMgrItem := TConnMgrItem.Create;
with FConnectionProperties do begin
ConnMgrItem.ConnectionName := NameEntry.Text;
- ConnMgrItem.URI := MakeURI(False);
- ConnMgrItem.ServiceType := Copy(ConnMgrItem.URI, 1, Pos('://', ConnMgrItem.URI) - 1);
+ ConnMgrItem.ServiceType := GetService;
ConnMgrItem.Server := ServerEntry.Text;
ConnMgrItem.Username := UserNameEntry.Text;
ConnMgrItem.Password := PasswordEntry.Text;
@@ -234,7 +260,7 @@ begin
if ConnMgrItem = nil then Exit;
FConnectionProperties := TFConnectionProperties.Create(Self);
FConnectionProperties.NameEntry.Text := ConnMgrItem.ConnectionName;
- FConnectionProperties.URIEntry.Text := ConnMgrItem.URI;
+ FConnectionProperties.URIEntry.Text := ConstructURI(True, False, ConnMgrItem.ServiceType, ConnMgrItem.Server, ConnMgrItem.Username, ConnMgrItem.Password, ConnMgrItem.TargetDir);
FConnectionProperties.ServiceTypeOptionMenuChanged(Sender);
// Find the plugin by PluginID
for i := 0 to PluginList.Count - 1 do
@@ -246,8 +272,7 @@ begin
if FConnectionProperties.Run = mbOK then begin
with FConnectionProperties do begin
ConnMgrItem.ConnectionName := NameEntry.Text;
- ConnMgrItem.URI := MakeURI(False);
- ConnMgrItem.ServiceType := Copy(ConnMgrItem.URI, 1, Pos('://', ConnMgrItem.URI) - 1);
+ ConnMgrItem.ServiceType := GetService;
ConnMgrItem.Server := ServerEntry.Text;
ConnMgrItem.Username := UserNameEntry.Text;
ConnMgrItem.Password := PasswordEntry.Text;
@@ -299,14 +324,147 @@ begin
Item := ListView.Items.Add;
Item.SetValue(0, ConnMgrItem);
Item.SetValue(1, ConnMgrItem.ConnectionName);
- Item.SetValue(2, ConstructURI(True, ConnMgrItem.ServiceType, ConnMgrItem.Server, ConnMgrItem.Username,
- ConnMgrItem.Password, ConnMgrItem.TargetDir));
+ Item.SetValue(2, ConstructURI(True, True, ConnMgrItem.ServiceType, ConnMgrItem.Server, ConnMgrItem.Username,
+ ConnMgrItem.Password, ConnMgrItem.TargetDir));
end;
if (ConfConnMgrActiveItem < 0) or (ConfConnMgrActiveItem > ConnectionMgrList.Count) then
ConfConnMgrActiveItem := 0;
end;
+(********************************************************************************************************************************)
+procedure TFConnectionManager.CloseButtonClick(Sender: TObject);
+begin
+ ModalResult := mbCancel;
+end;
+
+procedure TFConnectionManager.ConnectButtonClick(Sender: TObject);
+begin
+ DoConnect;
+end;
+
+procedure vfs_ask_question_callback(const AMessage: PChar; const Choices: PPChar; choice: PInteger; user_data: Pointer); cdecl;
+var ConnMgr: TFConnectionManager;
+ DialogParent: PGtkWidget;
+begin
+ ConnMgr := user_data;
+ DialogParent := nil;
+// DebugMsg(['******* vfs_ask_question_callback spawned, user_data = 0x', IntToHex(QWord(user_data), 16), ', ThreadID = 0x', IntToHex(pthread_self, 16)]);
+ if ConnMgr is TFConnectionManager then begin
+ if ConnMgr.AFRemoteWait <> nil then DialogParent := ConnMgr.AFRemoteWait.FWidget
+ else DialogParent := ConnMgr.FWidget;
+ end;
+ HandleVFSAskQuestionCallback(DialogParent, AMessage, Choices, choice);
+ if ConnMgr is TFConnectionManager then begin
+ if choice <> nil then ConnMgr.FSilenceError := choice^ < 0;
+ end;
+end;
+
+function vfs_ask_password_callback(const AMessage: PChar; const default_user: PChar; const default_domain: PChar; flags: TVFSAskPasswordFlags;
+ username, password: PPChar; anonymous: PInteger; domain: PPChar; password_save: PVFSPasswordSave;
+ user_data: Pointer): LongBool; cdecl;
+var ConnMgr: TFConnectionManager;
+ DialogParent: PGtkWidget;
+begin
+ ConnMgr := user_data;
+ DialogParent := nil;
+// DebugMsg(['******* vfs_ask_password_callback spawned, user_data = 0x', IntToHex(QWord(user_data), 16), ', ThreadID = 0x', IntToHex(pthread_self, 16)]);
+ if ConnMgr is TFConnectionManager then begin
+ Inc(ConnMgr.FVFSAskPasswordTry);
+ if ConnMgr.AFRemoteWait <> nil then DialogParent := ConnMgr.AFRemoteWait.FWidget
+ else DialogParent := ConnMgr.FWidget;
+ flags := flags or VFS_ASK_PASSWORD_SAVE_INTERNAL;
+ end;
+
+ // First pass, supply stored password if we have one
+ if (ConnMgr is TFConnectionManager) and (ConnMgr.FVFSAskPasswordTry = 1) and (password <> nil) and
+ ((flags and VFS_ASK_PASSWORD_NEED_PASSWORD) = VFS_ASK_PASSWORD_NEED_PASSWORD) and ((flags and VFS_ASK_PASSWORD_NEED_USERNAME) = 0) and
+ (ConnMgr.FActiveConnInfo <> nil) and (Length(ConnMgr.FActiveConnInfo.Password) > 0) then
+ begin
+ DebugMsg(['(II) vfs_ask_password_callback: Supplying stored password from Connection Manager']);
+ Result := True;
+ password^ := g_strdup(PChar(ConnMgr.FActiveConnInfo.Password));
+ if (password_save <> nil) { and ConfGnomeKeyringEnabled} then password_save^ := VFS_PASSWORD_SAVE_PERMANENTLY;
+ end else begin
+ // Show password dialog and continue in loop
+ Result := HandleVFSAskPasswordCallback(DialogParent, AMessage, default_user, default_domain, flags, username, password, anonymous, domain, password_save);
+ if ConnMgr is TFConnectionManager then begin
+ ConnMgr.FSilenceError := Result = False;
+ // Save password back to Connection Manager
+ if Result and (password_save <> nil) and (password_save^ = VFS_PASSWORD_SAVE_PERMANENTLY) and
+ (ConnMgr.FActiveConnInfo <> nil) and (password <> nil) and (strlen(password^) > 0) then
+ begin
+ DebugMsg(['(II) vfs_ask_password_callback: Saving password to Connection Manager']);
+ ConnMgr.FActiveConnInfo.Password := password^;
+ end;
+ end;
+ end;
+end;
+
+procedure TFConnectionManager.DoConnect;
+var Engine: TVFSEngine;
+ i, j: integer;
+ VFSPlugin: TVFSPlugin;
+ b: boolean;
+begin
+ FSilenceError := False;
+
+ FActiveConnInfo := nil;
+ if ListView.Selected <> nil then FActiveConnInfo := ListView.Selected.AsPointer(0);
+ if FActiveConnInfo = nil then Exit;
+
+ if PluginList.Count = 0 then begin
+ Application.MessageBox(PGtkWindow(FWidget), LANGThereIsNoModuleAvailable, [mbOK], mbError, mbOK, mbOK);
+ Exit;
+ end;
+
+ // Find VFS module to use for this connection
+ VFSPlugin := nil;
+ if Length(FActiveConnInfo.PluginID) > 0 then
+ for i := 0 to PluginList.Count - 1 do
+ if TVFSPlugin(PluginList[i]).VFSName = FActiveConnInfo.PluginID then begin
+ VFSPlugin := PluginList[i];
+ Break;
+ end;
+ if VFSPlugin = nil then begin
+ for i := 0 to PluginList.Count - 1 do begin
+ if Length(TVFSPlugin(PluginList[i]).Services) > 0 then
+ for j := 0 to Length(TVFSPlugin(PluginList[i]).Services) - 1 do
+ if WideCompareText(TVFSPlugin(PluginList[i]).Services[j], FActiveConnInfo.ServiceType) = 0 then begin
+ VFSPlugin := PluginList[i];
+ Break;
+ end;
+ if VFSPlugin <> nil then Break;
+ end;
+ if VFSPlugin = nil then VFSPlugin := PluginList[0]; // Fallback in hope some other plugin can handle it
+ end;
+
+ if (SourcePanelEngine is TVFSEngine) and (Application.MessageBox(PGtkWindow(FWidget), LANGCloseOpenConnection, [mbYes, mbNo], mbWarning, mbYes, mbNo) <> mbYes) then Exit;
+
+ // Construct the VFS Engine and try to open the connection
+ Engine := TVFSEngine.Create(VFSPlugin);
+ Engine.ParentEngine := SourcePanelEngine;
+ Engine.SavePath := SourcePanelEngine.Path;
+
+ AFRemoteWait := TFRemoteWait.Create(Application);
+ AFRemoteWait.ParentForm := FConnectionManager;
+ AFRemoteWait.ShowModal;
+ Application.ProcessMessages;
+
+ FVFSAskPasswordTry := 0;
+ b := Engine.VFSOpenURI(UTF8ToStr(FActiveConnInfo.GetURI(False)), @vfs_ask_question_callback, @vfs_ask_password_callback, Self);
+
+ AFRemoteWait.Free;
+ AFRemoteWait := nil;
+ if not b then begin
+ if not FSilenceError then Application.MessageBox(PGtkWindow(FWidget), LANGCouldntOpenURI, [mbOK], mbError, mbOK, mbOK);
+ Exit;
+ end;
+
+ ConnectedEngine := Engine;
+ ModalResult := mbOK;
+end;
+
end.