summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomas Bzatek <tbzatek@users.sourceforge.net>2008-10-12 15:50:20 +0200
committerTomas Bzatek <tbzatek@users.sourceforge.net>2008-10-12 15:50:20 +0200
commitf35af507573469b7c1692f01922d323bd1000fbc (patch)
tree619e72d4aa486bc97974293cf045f263e98263b6
parentb417ac914af5e3dfeb27eb5bde6210f88c5b9ec4 (diff)
downloadtuxcmd-f35af507573469b7c1692f01922d323bd1000fbc.tar.xz
Connection Manager password callback improvements
-rw-r--r--UConfig.pas1
-rw-r--r--UConnectionManager.pas190
-rw-r--r--UConnectionProperties.pas28
-rw-r--r--UCore.pas13
-rw-r--r--UCoreUtils.pas7
-rw-r--r--UGnome.pas50
-rw-r--r--UMain.pas100
-rw-r--r--libgtk_kylix/GTKForms.pas22
-rw-r--r--vfs/UVFSCore.pas2
-rw-r--r--vfs/uVFSprototypes.pas15
10 files changed, 273 insertions, 155 deletions
diff --git a/UConfig.pas b/UConfig.pas
index 6da4faa..9ef8917 100644
--- a/UConfig.pas
+++ b/UConfig.pas
@@ -935,7 +935,6 @@ begin
Password := IniFile.ReadString(Sections[i], 'Password', '');
TargetDir := IniFile.ReadString(Sections[i], 'TargetDir', '');
PluginID := IniFile.ReadString(Sections[i], 'PluginID', '');
- URI := ConstructURI(False, ServiceType, Server, Username, Password, TargetDir);
end;
ConnectionMgrList.Add(Item);
end;
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.
diff --git a/UConnectionProperties.pas b/UConnectionProperties.pas
index 27d5bbe..99dbf9a 100644
--- a/UConnectionProperties.pas
+++ b/UConnectionProperties.pas
@@ -44,6 +44,7 @@ type
function ValidSettings: boolean;
public
function MakeURI(Hidden: boolean): string;
+ function GetService: string;
end;
var
@@ -297,25 +298,8 @@ begin
end;
function TFConnectionProperties.MakeURI(Hidden: boolean): string;
-var Prefix: string;
begin
- Prefix := ServiceTypeTable[ServiceTypeTable_Count, 1];
- if ServiceTypeOptionMenu.ItemIndex < ServiceTypeTable_Count - 1
- then Prefix := ServiceTypeTable[ServiceTypeOptionMenu.ItemIndex + 1, 1] else
- if Pos('://', URIEntry.Text) > 1 then Prefix := Copy(URIEntry.Text, 1, Pos('://', URIEntry.Text) - 1);
- Result := Prefix + '://';
- if Length(UserNameEntry.Text) > 0 then begin
- Result := Result + UserNameEntry.Text;
- if Length(PasswordEntry.Text) > 0 then
- if Hidden then Result := Result + ':' + StringOfChar('*', Length(PasswordEntry.Text))
- else Result := Result + ':' + PasswordEntry.Text;
- Result := Result + '@';
- end;
- Result := Result + ServerEntry.Text;
- if Length(TargetDirEntry.Text) > 0 then begin
- if TargetDirEntry.Text[1] <> '/' then Result := Result + '/';
- Result := Result + TargetDirEntry.Text;
- end;
+ Result := ConstructURI(True, Hidden, GetService, ServerEntry.Text, UserNameEntry.Text, PasswordEntry.Text, TargetDirEntry.Text);
end;
procedure TFConnectionProperties.ServiceTypeOptionMenuChanged(Sender: TObject);
@@ -328,6 +312,14 @@ begin
NameEntryChanged(Sender);
end;
+function TFConnectionProperties.GetService: string;
+begin
+ Result := ServiceTypeTable[ServiceTypeTable_Count, 1];
+ if ServiceTypeOptionMenu.ItemIndex < ServiceTypeTable_Count - 1
+ then Result := ServiceTypeTable[ServiceTypeOptionMenu.ItemIndex + 1, 1] else
+ if Pos('://', URIEntry.Text) > 1 then Result := Copy(URIEntry.Text, 1, Pos('://', URIEntry.Text) - 1);
+end;
+
end.
diff --git a/UCore.pas b/UCore.pas
index cdbbd06..0fbfbb7 100644
--- a/UCore.pas
+++ b/UCore.pas
@@ -193,9 +193,9 @@ type TMounterItem = class
TConnMgrItem = class
public
ConnectionName: string;
- URI: string; // generated at runtime
ServiceType, Server, Username, Password, TargetDir: string;
PluginID: string; // leave blank for default
+ function GetURI(IncludePassword: boolean): string;
end;
procedure FillDefaultFstabMounterItems;
@@ -2678,7 +2678,7 @@ var Thread: TOpenDirThread;
begin
if pthread_self = Application.ThreadID then begin
DebugMsg(['!! (WARNING): vfs_ask_question_callback called from the main thread, expected spawn from a OpenDirThread']);
- HandleVFSAskQuestionCallback(nil, AMessage, Choices, choice);
+ HandleVFSAskQuestionCallback(FMain.FWidget, AMessage, Choices, choice);
Exit;
end;
@@ -2706,7 +2706,7 @@ var Thread: TOpenDirThread;
begin
if pthread_self = Application.ThreadID then begin
DebugMsg(['!! (WARNING): vfs_ask_password_callback called from the main thread, expected spawn from a OpenDirThread']);
- Result := HandleVFSAskPasswordCallback(nil, AMessage, default_user, default_domain, flags, username, password, anonymous, domain, password_save);
+ Result := HandleVFSAskPasswordCallback(FMain.FWidget, AMessage, default_user, default_domain, flags, username, password, anonymous, domain, password_save);
Exit;
end;
@@ -2850,6 +2850,13 @@ begin
end;
+(********************************************************************************************************************************)
+(********************************************************************************************************************************)
+function TConnMgrItem.GetURI(IncludePassword: boolean): string;
+begin
+ Result := ConstructURI(IncludePassword, False, ServiceType, Server, Username, Password, TargetDir);
+end;
+
(********************************************************************************************************************************)
(********************************************************************************************************************************)
diff --git a/UCoreUtils.pas b/UCoreUtils.pas
index 87232d7..bcaa927 100644
--- a/UCoreUtils.pas
+++ b/UCoreUtils.pas
@@ -115,7 +115,7 @@ procedure GetFirstLastPanelColumn(var FirstColumn, LastColumn: integer);
procedure SetupColors;
-function ConstructURI(HidePasswd: boolean; Protocol, Server, Username, Password, Dir: string): string;
+function ConstructURI(IncludePasswd, HidePasswd: boolean; Protocol, Server, Username, Password, Dir: string): string;
function URIHidePassword(const SrcURI: string): string;
function StrTotimetDef(const S: string; const Default: time_t): time_t;
@@ -1038,14 +1038,15 @@ begin
end;
(********************************************************************************************************************************)
-function ConstructURI(HidePasswd: boolean; Protocol, Server, Username, Password, Dir: string): string;
+function ConstructURI(IncludePasswd, HidePasswd: boolean; Protocol, Server, Username, Password, Dir: string): string;
begin
Result := Protocol + '://';
if Length(Username) > 0 then begin
Result := Result + Username;
- if Length(Password) > 0 then
+ if (Length(Password) > 0) and IncludePasswd then begin
if HidePasswd then Result := Result + ':' + StringOfChar('*', Length(Password))
else Result := Result + ':' + Password;
+ end;
Result := Result + '@';
end;
Result := Result + Server;
diff --git a/UGnome.pas b/UGnome.pas
index c843e84..dc2529c 100644
--- a/UGnome.pas
+++ b/UGnome.pas
@@ -1256,7 +1256,7 @@ begin
GTK_BUTTONS_NONE, '%s', AMessage);
if primary <> nil then g_free (primary);
- gtk_window_set_title (PGtkWindow(dialog), 'VFS Question');
+// gtk_window_set_title (PGtkWindow(dialog), 'VFS Question');
// First count the items in the list then add the buttons in reverse order
while (TOpenPCharArray(choices)[len] <> nil)
@@ -1369,6 +1369,7 @@ var widget: PGtkWidget;
group: PGSList;
remember_box: PGtkWidget;
priv: TVFSAskPasswordCallbackPriv;
+ s: PChar;
begin
FillChar(priv, sizeof(priv), 0);
radio_forget := nil;
@@ -1378,7 +1379,7 @@ begin
widget := gtk_dialog_new ();
priv.dialog := PGtkDialog(widget);
window := PGtkWindow(widget);
- gtk_window_set_title (window, 'VFS Question');
+// gtk_window_set_title (window, 'VFS Question');
// Set the dialog up with HIG properties
gtk_dialog_set_has_separator (priv.dialog, False);
@@ -1392,7 +1393,7 @@ begin
gtk_dialog_add_buttons (priv.dialog,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- 'Co_nnect', GTK_RESPONSE_OK,
+ PChar(LANGConnMgr_ConnectButton), GTK_RESPONSE_OK,
nil);
gtk_dialog_set_default_response (priv.dialog, GTK_RESPONSE_OK);
@@ -1419,7 +1420,7 @@ begin
vbox := gtk_vbox_new (FALSE, 6);
gtk_box_pack_start (GTK_BOX (main_vbox), vbox, FALSE, FALSE, 0);
- can_anonymous := (Integer(flags) and Integer(VFS_ASK_PASSWORD_ANONYMOUS_SUPPORTED)) = Integer(VFS_ASK_PASSWORD_ANONYMOUS_SUPPORTED);
+ can_anonymous := (flags and VFS_ASK_PASSWORD_ANONYMOUS_SUPPORTED) = VFS_ASK_PASSWORD_ANONYMOUS_SUPPORTED;
if can_anonymous then begin
anon_box := gtk_vbox_new (FALSE, 6);
@@ -1436,9 +1437,9 @@ begin
end;
rows := 0;
- if (Integer(flags) and Integer(VFS_ASK_PASSWORD_NEED_PASSWORD)) = Integer(VFS_ASK_PASSWORD_NEED_PASSWORD) then Inc(rows);
- if (Integer(flags) and Integer(VFS_ASK_PASSWORD_NEED_USERNAME)) = Integer(VFS_ASK_PASSWORD_NEED_USERNAME) then Inc(rows);
- if (Integer(flags) and Integer(VFS_ASK_PASSWORD_NEED_DOMAIN)) = Integer(VFS_ASK_PASSWORD_NEED_DOMAIN) then Inc(rows);
+ if (flags and VFS_ASK_PASSWORD_NEED_PASSWORD) = VFS_ASK_PASSWORD_NEED_PASSWORD then Inc(rows);
+ if (flags and VFS_ASK_PASSWORD_NEED_USERNAME) = VFS_ASK_PASSWORD_NEED_USERNAME then Inc(rows);
+ if (flags and VFS_ASK_PASSWORD_NEED_DOMAIN) = VFS_ASK_PASSWORD_NEED_DOMAIN then Inc(rows);
// The table that holds the entries
priv.entry_container := gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
@@ -1452,34 +1453,47 @@ begin
gtk_container_add (GTK_CONTAINER (priv.entry_container), table);
Rows := 0;
- if (Integer(flags) and Integer(VFS_ASK_PASSWORD_NEED_USERNAME)) = Integer(VFS_ASK_PASSWORD_NEED_USERNAME) then begin
+ if (flags and VFS_ASK_PASSWORD_NEED_USERNAME) = VFS_ASK_PASSWORD_NEED_USERNAME then begin
priv.username_entry := table_add_entry (table, rows, '_Username:', default_user, @priv);
Inc(Rows);
end;
- if (Integer(flags) and Integer(VFS_ASK_PASSWORD_NEED_DOMAIN)) = Integer(VFS_ASK_PASSWORD_NEED_DOMAIN) then begin
+ if (flags and VFS_ASK_PASSWORD_NEED_DOMAIN) = VFS_ASK_PASSWORD_NEED_DOMAIN then begin
priv.domain_entry := table_add_entry (table, rows, '_Domain:', default_domain, @priv);
Inc(Rows);
end;
- if (Integer(flags) and Integer(VFS_ASK_PASSWORD_NEED_PASSWORD)) = Integer(VFS_ASK_PASSWORD_NEED_PASSWORD) then begin
+ if (flags and VFS_ASK_PASSWORD_NEED_PASSWORD) = VFS_ASK_PASSWORD_NEED_PASSWORD then begin
priv.password_entry := table_add_entry (table, rows, '_Password:', nil, @priv);
// Inc(Rows);
gtk_entry_set_visibility (GTK_ENTRY (priv.password_entry), FALSE);
end;
- if (Integer(flags) and Integer(VFS_ASK_PASSWORD_SAVING_SUPPORTED)) = Integer(VFS_ASK_PASSWORD_SAVING_SUPPORTED) then begin
+ if ((flags and VFS_ASK_PASSWORD_SAVING_SUPPORTED) = VFS_ASK_PASSWORD_SAVING_SUPPORTED) or
+ ((flags and VFS_ASK_PASSWORD_SAVE_INTERNAL) = VFS_ASK_PASSWORD_SAVE_INTERNAL) then
+ begin
remember_box := gtk_vbox_new (FALSE, 6);
gtk_box_pack_start (GTK_BOX (vbox), remember_box, FALSE, FALSE, 0);
- radio_forget := gtk_radio_button_new_with_mnemonic (nil, 'Forget password _immediately');
+ if (flags and VFS_ASK_PASSWORD_SAVING_SUPPORTED) = 0 then s := 'Do not save password'
+ else s := 'Forget password _immediately';
+ radio_forget := gtk_radio_button_new_with_mnemonic (nil, s);
gtk_box_pack_start (GTK_BOX (remember_box), radio_forget, FALSE, FALSE, 0);
group := gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio_forget));
- radio_session := gtk_radio_button_new_with_mnemonic (group, 'Remember password until you _logout');
- gtk_box_pack_start (GTK_BOX (remember_box), radio_session, FALSE, FALSE, 0);
+ // gnome-keyring only
+ if (flags and VFS_ASK_PASSWORD_SAVING_SUPPORTED) = VFS_ASK_PASSWORD_SAVING_SUPPORTED then begin
+ radio_session := gtk_radio_button_new_with_mnemonic (group, 'Remember password until you _logout');
+ gtk_box_pack_start (GTK_BOX (remember_box), radio_session, FALSE, FALSE, 0);
+ group := gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio_session));
+ end;
- group := gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio_session));
- radio_remember := gtk_radio_button_new_with_mnemonic (group, 'Remember _forever');
+ if (flags and VFS_ASK_PASSWORD_SAVING_SUPPORTED) = 0 then s := '_Save password in Connection Manager'
+ else s := 'Remember _forever';
+ radio_remember := gtk_radio_button_new_with_mnemonic (group, s);
gtk_box_pack_start (GTK_BOX (remember_box), radio_remember, FALSE, FALSE, 0);
+
+ // Select to save password when internal saving is supported
+ if (flags and VFS_ASK_PASSWORD_SAVE_INTERNAL) = VFS_ASK_PASSWORD_SAVE_INTERNAL
+ then gtk_toggle_button_set_active(PGtkToggleButton(radio_remember), True);
end;
// The anonymous option will be active by default, ensure the toggled signal is emitted for it.
@@ -1495,9 +1509,9 @@ begin
if (priv.domain_entry <> nil) and (domain <> nil) then domain^ := g_strdup(gtk_entry_get_text(priv.domain_entry));
if (priv.password_entry <> nil) and (password <> nil) then password^ := g_strdup(gtk_entry_get_text(priv.password_entry));
if (priv.choice_anon <> nil) and (anonymous <> nil) then anonymous^ := Ord(gtk_toggle_button_get_active(PGtkToggleButton(priv.choice_anon)));
- if (password_save <> nil) and (radio_forget <> nil) and (radio_session <> nil) and (radio_remember <> nil) then begin
+ if (password_save <> nil) and (radio_forget <> nil) and (radio_remember <> nil) then begin
if gtk_toggle_button_get_active(PGtkToggleButton(radio_forget)) then password_save^ := VFS_PASSWORD_SAVE_NEVER else
- if gtk_toggle_button_get_active(PGtkToggleButton(radio_session)) then password_save^ := VFS_PASSWORD_SAVE_FOR_SESSION else
+ if (radio_session <> nil) and gtk_toggle_button_get_active(PGtkToggleButton(radio_session)) then password_save^ := VFS_PASSWORD_SAVE_FOR_SESSION else
if gtk_toggle_button_get_active(PGtkToggleButton(radio_remember)) then password_save^ := VFS_PASSWORD_SAVE_PERMANENTLY;
end;
end;
diff --git a/UMain.pas b/UMain.pas
index c01b01f..719ac2d 100644
--- a/UMain.pas
+++ b/UMain.pas
@@ -1726,6 +1726,7 @@ var ListView: TGTKListView;
end;
procedure DoThread;
+ var DialogParent: PGtkWidget;
begin
try
OpenDirThread.AEngine := Engine;
@@ -1757,13 +1758,17 @@ var ListView: TGTKListView;
if OpenDirThread.VFSAskQuestion_Display then begin
OpenDirThread.VFSAskQuestion_Display := False;
DebugMsg(['Main thread: displaying question dialog']);
- HandleVFSAskQuestionCallback(FRemoteWait.FWidget, OpenDirThread.VFSAskQuestion_Message, OpenDirThread.VFSAskQuestion_Choices, OpenDirThread.VFSAskQuestion_Choice);
+ if FRemoteWait.Visible then DialogParent := FRemoteWait.FWidget
+ else DialogParent := FWidget;
+ HandleVFSAskQuestionCallback(DialogParent, OpenDirThread.VFSAskQuestion_Message, OpenDirThread.VFSAskQuestion_Choices, OpenDirThread.VFSAskQuestion_Choice);
OpenDirThread.VFSCallbackEvent.SetEvent;
end;
if OpenDirThread.VFSAskPassword_Display then begin
OpenDirThread.VFSAskPassword_Display := False;
DebugMsg(['Main thread: displaying password prompt']);
- OpenDirThread.VFSAskPassword_Result := HandleVFSAskPasswordCallback(FRemoteWait.FWidget,
+ if FRemoteWait.Visible then DialogParent := FRemoteWait.FWidget
+ else DialogParent := FWidget;
+ OpenDirThread.VFSAskPassword_Result := HandleVFSAskPasswordCallback(DialogParent,
OpenDirThread.VFSAskPassword_Message,
OpenDirThread.VFSAskPassword_default_user,
OpenDirThread.VFSAskPassword_default_domain,
@@ -5958,94 +5963,23 @@ end;
(********************************************************************************************************************************)
(********************************************************************************************************************************)
-procedure vfs_ask_question_callback(const AMessage: PChar; const Choices: PPChar; choice: PInteger; user_data: Pointer); cdecl;
-begin
-// DebugMsg(['******* vfs_ask_question_callback spawned, user_data = 0x', IntToHex(QWord(user_data), 16), ', ThreadID = 0x', IntToHex(pthread_self, 16)]);
- HandleVFSAskQuestionCallback(user_data, AMessage, Choices, choice);
-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;
-begin
-// DebugMsg(['******* vfs_ask_password_callback spawned, user_data = 0x', IntToHex(QWord(user_data), 16), ', ThreadID = 0x', IntToHex(pthread_self, 16)]);
- Result := HandleVFSAskPasswordCallback(user_data, AMessage, default_user, default_domain, flags, username, password, anonymous, domain, password_save);
-// DebugMsg(['after vfs_ask_password_callback: password = ', password^]);
-end;
-
procedure TFMain.miOpenConnectionClick(Sender: TObject);
-var Engine: TVFSEngine;
- SourceEngine: TPanelEngine;
- i, j: integer;
- VFSPlugin: TVFSPlugin;
- ConnInfo: TConnMgrItem;
- b: boolean;
+var b: boolean;
begin
try
InternalLock;
- ConnInfo := nil;
-
+
FConnectionManager := TFConnectionManager.Create(Self);
+ if LeftLastFocused then FConnectionManager.SourcePanelEngine := LeftPanelEngine
+ else FConnectionManager.SourcePanelEngine := RightPanelEngine;
b := FConnectionManager.Run = mbOK;
- if FConnectionManager.ListView.Selected <> nil then begin
- ConnInfo := FConnectionManager.ListView.Selected.AsPointer(0);
- ConfConnMgrActiveItem := FConnectionManager.ListView.Selected.Index;
- end;
- WriteConnections; // Save the list to the file
+ if FConnectionManager.ListView.Selected <> nil then ConfConnMgrActiveItem := FConnectionManager.ListView.Selected.Index;
+ WriteConnections; // Save connection manager data
- if b then begin
- if PluginList.Count = 0 then begin
- Application.MessageBox(LANGThereIsNoModuleAvailable, [mbOK], mbError, mbOK, mbOK);
- Exit;
- end;
- if ConnInfo = nil then Exit;
-
- // Find the VFS module to use for this connection
- VFSPlugin := nil;
- if Length(ConnInfo.PluginID) > 0 then
- for i := 0 to PluginList.Count - 1 do
- if TVFSPlugin(PluginList[i]).VFSName = ConnInfo.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], ConnInfo.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 something else could handle it
- end;
-
- if (LeftLastFocused and (LeftPanelEngine is TVFSEngine)) or ((not LeftLastFocused) and (RightPanelEngine is TVFSEngine)) then
- begin
- if Application.MessageBox(LANGCloseOpenConnection, [mbYes, mbNo], mbWarning, mbYes, mbNo) <> mbYes then Exit;
- CloseVFS(LeftLastFocused, True);
- end;
-
- // Construct the VFS Engine and try to open the connection
- if LeftLastFocused then SourceEngine := LeftPanelEngine
- else SourceEngine := RightPanelEngine;
- Engine := TVFSEngine.Create(VFSPlugin);
- Engine.ParentEngine := SourceEngine;
- Engine.SavePath := SourceEngine.Path;
-
- FRemoteWait := TFRemoteWait.Create(Application);
- FRemoteWait.ParentForm := FConnectionManager;
- FRemoteWait.ShowModal;
- Application.ProcessMessages;
- b := Engine.VFSOpenURI(UTF8ToStr(ConnInfo.URI), @vfs_ask_question_callback, @vfs_ask_password_callback, FRemoteWait.FWidget);
- FRemoteWait.Free;
- if not b then begin
- Application.MessageBox(LANGCouldntOpenURI, [mbOK], mbError, mbOK, mbOK);
- Exit;
- end;
- if LeftLastFocused then LeftPanelEngine := Engine
- else RightPanelEngine := Engine;
+ if b and (FConnectionManager.ConnectedEngine <> nil) then begin
+ if FConnectionManager.SourcePanelEngine is TVFSEngine then CloseVFS(LeftLastFocused, True);
+ if LeftLastFocused then LeftPanelEngine := FConnectionManager.ConnectedEngine
+ else RightPanelEngine := FConnectionManager.ConnectedEngine;
DoRefresh(LeftLastFocused, False, False);
end;
finally
diff --git a/libgtk_kylix/GTKForms.pas b/libgtk_kylix/GTKForms.pas
index 0f85652..7b23879 100644
--- a/libgtk_kylix/GTKForms.pas
+++ b/libgtk_kylix/GTKForms.pas
@@ -1,6 +1,6 @@
(*
GTK-Kylix Library: GTKForms - Basic windows (TGTKForm, TGTKDialog), TGTKApplication, TGDKScreen
- Version 0.6.27 (last updated 2008-10-11)
+ Version 0.6.28 (last updated 2008-10-12)
Copyright (C) 2007 Tomas Bzatek <tbzatek@users.sourceforge.net>
This library is free software; you can redistribute it and/or
@@ -194,7 +194,9 @@ type // Some basic types
procedure HookSynchronizeWakeup;
procedure Initialize;
function MessageBox(const Text: string; Buttons: TMessageButtons = [mbOK]; Style: TMessageStyle = mbInfo;
- Default: TMessageButton = mbNone; Escape: TMessageButton = mbNone): TMessageButton;
+ Default: TMessageButton = mbNone; Escape: TMessageButton = mbNone): TMessageButton; overload;
+ function MessageBox(ParentWindow: PGtkWindow; const Text: string; Buttons: TMessageButtons = [mbOK]; Style: TMessageStyle = mbInfo;
+ Default: TMessageButton = mbNone; Escape: TMessageButton = mbNone): TMessageButton; overload;
procedure ProcessMessages;
procedure Run;
procedure ShowException(E: Exception);
@@ -716,9 +718,18 @@ end;
function TGTKApplication.MessageBox(const Text: string; Buttons: TMessageButtons; Style: TMessageStyle;
Default, Escape: TMessageButton): TMessageButton;
+var DialogParent: PGtkWindow;
+begin
+ if Screen.FormCount > 0
+ then DialogParent := PGtkWindow(Screen.Forms[0].FWidget)
+ else DialogParent := nil;
+ Result := MessageBox(DialogParent, Text, Buttons, Style, Default, Escape);
+end;
+
+function TGTKApplication.MessageBox(ParentWindow: PGtkWindow; const Text: string; Buttons: TMessageButtons = [mbOK]; Style: TMessageStyle = mbInfo;
+ Default: TMessageButton = mbNone; Escape: TMessageButton = mbNone): TMessageButton; overload;
const TMessageStyleID : array[0..3] of TGtkMessageType = (GTK_MESSAGE_ERROR, GTK_MESSAGE_INFO, GTK_MESSAGE_QUESTION, GTK_MESSAGE_WARNING);
var Dialog: PGtkWidget;
- DialogParent: PGtkWindow;
i: integer;
begin
if Application.Terminated then
@@ -726,10 +737,7 @@ begin
Result := Escape;
Exit;
end;
- if Screen.FormCount > 0
- then DialogParent := PGtkWindow(Screen.Forms[0].FWidget)
- else DialogParent := nil;
- Dialog := gtk_message_dialog_new(DialogParent, GTK_DIALOG_MODAL or GTK_DIALOG_DESTROY_WITH_PARENT, TMessageStyleID[Integer(Style)],
+ Dialog := gtk_message_dialog_new(ParentWindow, GTK_DIALOG_MODAL or GTK_DIALOG_DESTROY_WITH_PARENT, TMessageStyleID[Integer(Style)],
GTK_BUTTONS_NONE, StringToPgchar(Text));
for i := 1 to NumMessageButtons do
if TMessageButton(i - 1) in Buttons
diff --git a/vfs/UVFSCore.pas b/vfs/UVFSCore.pas
index e884a09..ee2a6ca 100644
--- a/vfs/UVFSCore.pas
+++ b/vfs/UVFSCore.pas
@@ -486,7 +486,7 @@ end;
function TVFSEngine.GetPrefix: string;
begin
if (FGlobs <> nil) and (@FSourcePlugin.FVFSGetPrefix <> nil)
- then Result := URIHidePassword(FSourcePlugin.FVFSGetPrefix(FGlobs))
+ then Result := FSourcePlugin.FVFSGetPrefix(FGlobs)
else Result := 'VFS';
end;
diff --git a/vfs/uVFSprototypes.pas b/vfs/uVFSprototypes.pas
index 18830aa..7cff78b 100644
--- a/vfs/uVFSprototypes.pas
+++ b/vfs/uVFSprototypes.pas
@@ -64,6 +64,12 @@ const
cVFS_OpenWrite = 1;
cVFS_OpenAppend = 2;
+ VFS_ASK_PASSWORD_NEED_PASSWORD = 1 shl 0;
+ VFS_ASK_PASSWORD_NEED_USERNAME = 1 shl 1;
+ VFS_ASK_PASSWORD_NEED_DOMAIN = 1 shl 2;
+ VFS_ASK_PASSWORD_SAVING_SUPPORTED = 1 shl 3; // Plugin reports if gnome-keyring is available
+ VFS_ASK_PASSWORD_ANONYMOUS_SUPPORTED = 1 shl 4;
+ VFS_ASK_PASSWORD_SAVE_INTERNAL = 1 shl 15; // Save password into internal Connection Manager
type
@@ -76,13 +82,10 @@ type
// File descriptor for Open, Read, Write, Close, Seek operations
TVFSFileDes = Pointer;
- TVFSAskPasswordFlags = (VFS_ASK_PASSWORD_NEED_PASSWORD = 1 shl 0,
- VFS_ASK_PASSWORD_NEED_USERNAME = 1 shl 1,
- VFS_ASK_PASSWORD_NEED_DOMAIN = 1 shl 2,
- VFS_ASK_PASSWORD_SAVING_SUPPORTED = 1 shl 3,
- VFS_ASK_PASSWORD_ANONYMOUS_SUPPORTED = 1 shl 4);
+ TVFSAskPasswordFlags = Longint;
PVFSPasswordSave = ^TVFSPasswordSave;
+ // Let plugin save the password, usually to gnome-keyring
TVFSPasswordSave = (VFS_PASSWORD_SAVE_NEVER,
VFS_PASSWORD_SAVE_FOR_SESSION,
VFS_PASSWORD_SAVE_PERMANENTLY);
@@ -173,6 +176,7 @@ type
TVFSOpen = function (g:TVFSGlobs; const sName: PChar): TVFSResult; cdecl;
// TODO: Opens the location (file or URI/URL)
+ // In case of URI, do not supply password encoded in the string; plugin will automatically spawn the TVFSAskPasswordCallback callback
TVFSLogin = function (g:TVFSGlobs; const User, Pass: PChar): TVFSResult; cdecl;
// TODO: Performs login to the server
TVFSClose = function (g:TVFSGlobs): TVFSResult; cdecl;
@@ -265,6 +269,7 @@ type
user_data: Pointer); cdecl;
PVFSAskPasswordCallback = ^TVFSAskPasswordCallback;
+ // Remember to allocate passed strings separately (use strdup() when setting reply)
TVFSAskPasswordCallback = function (const AMessage: PChar;
const default_user: PChar;
const default_domain: PChar;