diff --git a/gajim/config.py b/gajim/config.py index b31d1928145327dcc1422dfd56d0aff681ba3077..9092fe727f26bde5289cdb55471e0c3cb3763e6b 100644 --- a/gajim/config.py +++ b/gajim/config.py @@ -30,19 +30,6 @@ from gi.repository import Gtk from gi.repository import GObject -from gajim.common import app -from gajim.common import passwords -from gajim.common.i18n import _ - -from gajim import dialogs - -from gajim import gui_menu_builder - -from gajim.gtk.dialogs import ConfirmationDialog -from gajim.gtk.dialogs import ConfirmationDialogDoubleRadio -from gajim.gtk.dialogs import ErrorDialog -from gajim.gtk.util import get_builder - class FakeDataForm(Gtk.Table): """ @@ -94,131 +81,3 @@ class FakeDataForm(Gtk.Table): for name in self.entries: self.infos[name] = self.entries[name].get_text() return self.infos - -#---------- RemoveAccountWindow class -------------# -class RemoveAccountWindow: - """ - Ask for removing from gajim only or from gajim and server too and do - removing of the account given - """ - - def on_remove_account_window_destroy(self, widget): - if self.account in app.interface.instances: - del app.interface.instances[self.account]['remove_account'] - - def on_cancel_button_clicked(self, widget): - self.window.destroy() - - def __init__(self, account): - self.account = account - xml = get_builder('remove_account_window.ui') - self.window = xml.get_object('remove_account_window') - active_window = app.app.get_active_window() - self.window.set_transient_for(active_window) - self.remove_and_unregister_radiobutton = xml.get_object( - 'remove_and_unregister_radiobutton') - self.window.set_title(_('Removing %s account') % self.account) - xml.connect_signals(self) - self.window.show_all() - - def on_remove_button_clicked(self, widget): - def remove(): - if self.account in app.connections and \ - app.connections[self.account].connected and \ - not self.remove_and_unregister_radiobutton.get_active(): - # change status to offline only if we will not remove this JID from - # server - app.connections[self.account].change_status('offline', 'offline') - if self.remove_and_unregister_radiobutton.get_active(): - if not self.account in app.connections: - ErrorDialog( - _('Account is disabled'), - _('To unregister from a server, account must be ' - 'enabled.'), - transient_for=self.window) - return - if not app.connections[self.account].password: - def on_ok(passphrase, checked): - if passphrase == -1: - # We don't remove account cause we canceled pw window - return - app.connections[self.account].password = passphrase - app.connections[self.account].unregister_account( - self._on_remove_success) - - dialogs.PassphraseDialog( - _('Password Required'), - _('Enter your password for account %s') % self.account, - _('Save password'), ok_handler=on_ok, - transient_for=self.window) - return - app.connections[self.account].unregister_account( - self._on_remove_success) - else: - self._on_remove_success(True) - - if self.account in app.connections and \ - app.connections[self.account].connected: - ConfirmationDialog( - _('Account "%s" is connected to the server') % self.account, - _('If you remove it, the connection will be lost.'), - on_response_ok=remove, - transient_for=self.window) - else: - remove() - - def on_remove_responce_ok(self, is_checked): - if is_checked[0]: - self._on_remove_success(True) - - def _on_remove_success(self, res): - # action of unregistration has failed, we don't remove the account - # Error message is send by connect_and_auth() - if not res: - ConfirmationDialogDoubleRadio( - _('Connection to server %s failed') % self.account, - _('What would you like to do?'), - _('Remove only from Gajim'), - _('Don\'t remove anything. I\'ll try again later'), - on_response_ok=self.on_remove_responce_ok, is_modal=False, - transient_for=self.window) - return - # Close all opened windows - app.interface.roster.close_all(self.account, force=True) - if self.account in app.connections: - app.connections[self.account].disconnect(reconnect=False) - app.connections[self.account].cleanup() - del app.connections[self.account] - app.logger.remove_roster(app.get_jid_from_account(self.account)) - # Delete password must be before del_per() because it calls set_per() - # which would recreate the account with defaults values if not found - passwords.delete_password(self.account) - app.config.del_per('accounts', self.account) - del app.interface.instances[self.account] - if self.account in app.nicks: - del app.interface.minimized_controls[self.account] - del app.nicks[self.account] - del app.block_signed_in_notifications[self.account] - del app.groups[self.account] - app.contacts.remove_account(self.account) - del app.gc_connected[self.account] - del app.automatic_rooms[self.account] - del app.to_be_removed[self.account] - del app.newly_added[self.account] - del app.sleeper_state[self.account] - del app.last_message_time[self.account] - del app.status_before_autoaway[self.account] - del app.gajim_optional_features[self.account] - del app.caps_hash[self.account] - if len(app.connections) >= 2: # Do not merge accounts if only one exists - app.interface.roster.regroup = app.config.get('mergeaccounts') - else: - app.interface.roster.regroup = False - app.interface.roster.setup_and_draw_roster() - app.app.remove_account_actions(self.account) - gui_menu_builder.build_accounts_menu() - - window = app.get_app_window('AccountsWindow') - if window is not None: - window.remove_account(self.account) - self.window.destroy() diff --git a/gajim/data/gui/remove_account_window.ui b/gajim/data/gui/remove_account_window.ui index c1e18e3e3b71f4022f55bb834aa59dbfb1f0d670..8efbbaff2b29264d5f85fa0f7413d0b65cce04ec 100644 --- a/gajim/data/gui/remove_account_window.ui +++ b/gajim/data/gui/remove_account_window.ui @@ -1,119 +1,115 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.18.3 --> +<!-- Generated with glade 3.22.1 --> <interface> - <requires lib="gtk+" version="3.12"/> - <object class="GtkImage" id="image1"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="stock">gtk-delete</property> - </object> + <requires lib="gtk+" version="3.20"/> <object class="GtkWindow" id="remove_account_window"> <property name="can_focus">False</property> - <property name="border_width">6</property> + <property name="border_width">18</property> <property name="type_hint">dialog</property> <signal name="destroy" handler="on_remove_account_window_destroy" swapped="no"/> <child> - <object class="GtkBox" id="vbox69"> + <placeholder/> + </child> + <child> + <object class="GtkBox"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="border_width">3</property> <property name="orientation">vertical</property> - <property name="spacing">6</property> + <property name="spacing">18</property> <child> - <object class="GtkBox" id="hbox2951"> + <object class="GtkLabel"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="spacing">6</property> + <property name="halign">start</property> + <property name="label" translatable="yes">What do you want to do?</property> + <property name="use_markup">True</property> + <style> + <class name="large-header"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">12</property> <child> - <object class="GtkImage" id="image498"> + <object class="GtkImage"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="stock">gtk-dialog-question</property> + <property name="icon_name">user-trash</property> <property name="icon_size">6</property> </object> <packing> <property name="expand">False</property> - <property name="fill">False</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> - <object class="GtkFrame" id="frame30"> + <object class="GtkBox"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="label_xalign">0</property> - <property name="shadow_type">none</property> + <property name="orientation">vertical</property> + <property name="spacing">6</property> <child> - <object class="GtkBox" id="vbox1"> + <object class="GtkRadioButton" id="remove_only_radiobutton"> + <property name="label" translatable="yes">Remove account _only from Gajim</property> <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="margin_left">12</property> - <property name="border_width">6</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkRadioButton" id="remove_only_radiobutton"> - <property name="label" translatable="yes">Remove account _only from Gajim</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="xalign">0</property> - <property name="active">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkRadioButton" id="remove_and_unregister_radiobutton"> - <property name="label" translatable="yes">Remove account from Gajim and from _server</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="xalign">0</property> - <property name="draw_indicator">True</property> - <property name="group">remove_only_radiobutton</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="halign">start</property> + <property name="use_underline">True</property> + <property name="active">True</property> + <property name="draw_indicator">True</property> </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> </child> - <child type="label"> - <object class="GtkLabel" id="label242"> + <child> + <object class="GtkRadioButton" id="remove_and_unregister_radiobutton"> + <property name="label" translatable="yes">Remove account from Gajim and from _server</property> <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes"><b>What do you want to do?</b></property> - <property name="use_markup">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="halign">start</property> + <property name="use_underline">True</property> + <property name="active">True</property> + <property name="draw_indicator">True</property> + <property name="group">remove_only_radiobutton</property> </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> </child> </object> <packing> <property name="expand">False</property> - <property name="fill">False</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> </object> <packing> <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> + <property name="fill">True</property> + <property name="position">1</property> </packing> </child> <child> - <object class="GtkButtonBox" id="hbuttonbox16"> + <object class="GtkButtonBox"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="border_width">6</property> <property name="spacing">12</property> <property name="layout_style">end</property> <child> @@ -139,9 +135,11 @@ <property name="can_focus">True</property> <property name="can_default">True</property> <property name="receives_default">False</property> - <property name="image">image1</property> <property name="use_underline">True</property> <signal name="clicked" handler="on_remove_button_clicked" swapped="no"/> + <style> + <class name="destructive-action"/> + </style> </object> <packing> <property name="expand">False</property> @@ -153,7 +151,7 @@ <packing> <property name="expand">False</property> <property name="fill">False</property> - <property name="position">1</property> + <property name="position">2</property> </packing> </child> </object> diff --git a/gajim/gtk/accounts.py b/gajim/gtk/accounts.py index aab4bb4f82390ac775151bd14a598ceafaf190a5..48f52fd5bd7301a7d5caf014888383ac7184cf2b 100644 --- a/gajim/gtk/accounts.py +++ b/gajim/gtk/accounts.py @@ -30,12 +30,14 @@ from gajim.common.const import OptionKind from gajim.common.const import OptionType from gajim import gui_menu_builder -from gajim import config +from gajim.dialogs import PassphraseDialog from gajim.options_dialog import OptionsDialog from gajim.options_dialog import OptionsBox from gajim.gtk.dialogs import ConfirmationDialog +from gajim.gtk.dialogs import ConfirmationDialogDoubleRadio +from gajim.gtk.dialogs import ErrorDialog from gajim.gtk.dialogs import YesNoDialog from gajim.gtk.util import get_icon_name from gajim.gtk.util import get_builder @@ -220,7 +222,7 @@ class AccountsWindow(Gtk.ApplicationWindow): if account not in app.interface.instances: app.interface.instances[account] = {} app.interface.instances[account]['remove_account'] = \ - config.RemoveAccountWindow(account) + RemoveAccountWindow(account) if win_opened: ConfirmationDialog( _('You have opened chat in account %s') % account, @@ -811,3 +813,131 @@ class LoginDialog(OptionsDialog): savepass = app.config.get_per('accounts', self.account, 'savepass') if not savepass: passwords.delete_password(self.account) + + +class RemoveAccountWindow: + """ + Ask whether to remove from gajim only or both from gajim and the server, + then remove the account given + """ + + def on_remove_account_window_destroy(self, widget): + if self.account in app.interface.instances: + del app.interface.instances[self.account]['remove_account'] + + def on_cancel_button_clicked(self, widget): + self._ui.remove_account_window.destroy() + + def __init__(self, account): + self.account = account + self._ui = get_builder('remove_account_window.ui') + active_window = app.app.get_active_window() + self._ui.remove_account_window.set_transient_for(active_window) + self._ui.remove_account_window.set_title(_('Removing account %s') % self.account) + self._ui.connect_signals(self) + self._ui.remove_account_window.show_all() + + def on_remove_button_clicked(self, widget): + def remove(): + if self.account in app.connections and \ + app.connections[self.account].connected and \ + not self._ui.remove_and_unregister_radiobutton.get_active(): + # change status to offline only if we will not remove this JID from + # server + app.connections[self.account].change_status('offline', 'offline') + if self._ui.remove_and_unregister_radiobutton.get_active(): + if not self.account in app.connections: + ErrorDialog( + _('Account is disabled'), + _('To unregister from a server, the account must be ' + 'enabled.'), + transient_for=self._ui.remove_account_window) + return + if not app.connections[self.account].password: + def on_ok(passphrase, checked): + if passphrase == -1: + # We don't remove account cause we canceled pw window + return + app.connections[self.account].password = passphrase + app.connections[self.account].unregister_account( + self._on_remove_success) + + PassphraseDialog( + _('Password required'), + _('Enter your password for account %s') % self.account, + _('Save password'), ok_handler=on_ok, + transient_for=self._ui.remove_account_window) + return + app.connections[self.account].unregister_account( + self._on_remove_success) + else: + self._on_remove_success(True) + + if self.account in app.connections and \ + app.connections[self.account].connected: + ConfirmationDialog( + _('Account "%s" is connected to the server') % self.account, + _('If you remove it, the connection will be lost.'), + on_response_ok=remove, + transient_for=self._ui.remove_account_window) + else: + remove() + + def on_remove_response_ok(self, is_checked): + if is_checked[0]: + self._on_remove_success(True) + + def _on_remove_success(self, res): + # action of unregistration has failed, we don't remove the account + # Error message is send by connect_and_auth() + if not res: + ConfirmationDialogDoubleRadio( + _('Connection to server %s failed') % self.account, + _('What would you like to do?'), + _('Remove only from Gajim'), + _('Don\'t remove anything. I\'ll try again later'), + on_response_ok=self.on_remove_response_ok, is_modal=False, + transient_for=self._ui.remove_account_window) + return + # Close all opened windows + app.interface.roster.close_all(self.account, force=True) + if self.account in app.connections: + app.connections[self.account].disconnect(reconnect=False) + app.connections[self.account].cleanup() + del app.connections[self.account] + app.logger.remove_roster(app.get_jid_from_account(self.account)) + # Delete password must be before del_per() because it calls set_per() + # which would recreate the account with defaults values if not found + passwords.delete_password(self.account) + app.config.del_per('accounts', self.account) + del app.interface.instances[self.account] + if self.account in app.nicks: + del app.interface.minimized_controls[self.account] + del app.nicks[self.account] + del app.block_signed_in_notifications[self.account] + del app.groups[self.account] + app.contacts.remove_account(self.account) + del app.gc_connected[self.account] + del app.automatic_rooms[self.account] + del app.to_be_removed[self.account] + del app.newly_added[self.account] + del app.sleeper_state[self.account] + del app.last_message_time[self.account] + del app.status_before_autoaway[self.account] + del app.gajim_optional_features[self.account] + del app.caps_hash[self.account] + if len(app.connections) >= 2: # Do not merge accounts if only one exists + app.interface.roster.regroup = app.config.get('mergeaccounts') + else: + app.interface.roster.regroup = False + app.interface.roster.setup_and_draw_roster() + app.app.remove_account_actions(self.account) + gui_menu_builder.build_accounts_menu() + + window = app.get_app_window('AccountsWindow') + if window is not None: + window.remove_account(self.account) + self._ui.remove_account_window.destroy() + + def destroy(self): + self._ui.remove_account_window.destroy()