diff options
| author | Tomas Bzatek <tbzatek@users.sourceforge.net> | 2008-10-12 15:50:20 +0200 |
|---|---|---|
| committer | Tomas Bzatek <tbzatek@users.sourceforge.net> | 2008-10-12 15:50:20 +0200 |
| commit | f35af507573469b7c1692f01922d323bd1000fbc (patch) | |
| tree | 619e72d4aa486bc97974293cf045f263e98263b6 /UConnectionManager.pas | |
| parent | b417ac914af5e3dfeb27eb5bde6210f88c5b9ec4 (diff) | |
| download | tuxcmd-f35af507573469b7c1692f01922d323bd1000fbc.tar.xz | |
Connection Manager password callback improvements
Diffstat (limited to 'UConnectionManager.pas')
| -rw-r--r-- | UConnectionManager.pas | 190 |
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. |
