diff --git a/gajim/gtk/account_page.py b/gajim/gtk/account_page.py index c60adc5d5965ecda842b791348b8eab78b9011f3..cbdd5e11a68259cbbe2d2873b2f1a3f60e07f9e0 100644 --- a/gajim/gtk/account_page.py +++ b/gajim/gtk/account_page.py @@ -19,13 +19,13 @@ from gajim.common import ged from gajim.common.const import AvatarSize from gajim.common.i18n import _ -from gajim.common.nec import EventHelper from .roster import Roster from .status_selector import StatusSelector from .notification_manager import NotificationManager from .util import get_builder from .util import open_window +from .util import EventHelper ROSTER_MENU_DICT = { 'show-offline': _('Show Offline Contacts'), diff --git a/gajim/gtk/account_side_bar.py b/gajim/gtk/account_side_bar.py index 949bb6d7553e8cc67424189dd623b8e31f571ec8..21dc2ad9135f24735d6de2074a49becf498e41ce 100644 --- a/gajim/gtk/account_side_bar.py +++ b/gajim/gtk/account_side_bar.py @@ -35,7 +35,10 @@ def add_account(self, account): self.add(Account(account)) def remove_account(self, account): - pass + for row in self.get_children(): + if row.account == account: + row.destroy() + return @staticmethod def _on_row_activated(_listbox, row): @@ -97,6 +100,7 @@ def __init__(self, account): self._contact.connect('avatar-update', self._on_avatar_update) self._contact.connect('presence-update', self._on_presence_update) + self.connect('destroy', self._on_destroy) self._update_image() def _on_presence_update(self, _contact, _signal_name): @@ -110,3 +114,7 @@ def _update_image(self): self.get_scale_factor(), style='round-corners') self.set_from_surface(surface) + + def _on_destroy(self, *args): + self._contact.disconnect_all_from_obj(self) + app.check_finalize(self) diff --git a/gajim/gtk/accounts.py b/gajim/gtk/accounts.py index d4cfe8e09c30f8d6be5ee7c5d4900c0b7f3c2df6..f186cb8cef0f20da65e6ef10156ecafdb13462ac 100644 --- a/gajim/gtk/accounts.py +++ b/gajim/gtk/accounts.py @@ -23,6 +23,7 @@ from gi.repository import GObject from gajim.common import app +from gajim.common import ged from gajim.common import passwords from gajim.common.i18n import _ from gajim.common.i18n import Q_ @@ -535,9 +536,19 @@ def _set_label(self, active): self._switch_state_label.set_text(text) def _on_enable_switch(self, switch, state, account): + def _on_disconnect(event): + if event.account != account: + return + app.ged.remove_event_handler('account-disconnected', + ged.CORE, + _on_disconnect) + app.interface.disable_account(account) + def _disable(): + app.ged.register_event_handler('account-disconnected', + ged.CORE, + _on_disconnect) app.connections[account].change_status('offline', 'offline') - app.interface.disable_account(account) switch.set_state(state) self._set_label(state) diff --git a/gajim/gtk/chat_list.py b/gajim/gtk/chat_list.py index f10d19124195b25a762537717336080efd06d767..f95f9eebb9ace774b4e396a1b18a2b881dade500 100644 --- a/gajim/gtk/chat_list.py +++ b/gajim/gtk/chat_list.py @@ -168,6 +168,12 @@ def remove_chat(self, account, jid): self.remove(row) row.destroy() + def remove_chats_for_account(self, account): + for row_account, jid in list(self._chats.keys()): + if row_account != account: + continue + self.remove_chat(account, jid) + def get_selected_chat(self): row = self.get_selected_row() if row is None: diff --git a/gajim/gtk/chat_list_stack.py b/gajim/gtk/chat_list_stack.py index 3eadac18fa8ed91630c57b29b4cd850698541e13..b45e2e5fd130d17ae0d80163aad7e789ec928dd4 100644 --- a/gajim/gtk/chat_list_stack.py +++ b/gajim/gtk/chat_list_stack.py @@ -102,12 +102,17 @@ def get_chatlist(self, workspace_id): return self._chat_lists[workspace_id] def get_selected_chat(self): + chat_list = self.get_current_chat_list() + if chat_list is None: + return None + return chat_list.get_selected_chat() + + def get_current_chat_list(self): workspace_id = self.get_visible_child_name() if workspace_id == 'empty': return None - chat_list = self._chat_lists[workspace_id] - return chat_list.get_selected_chat() + return self._chat_lists[workspace_id] def is_chat_active(self, account, jid): chat = self.get_selected_chat() @@ -202,6 +207,11 @@ def remove_chat(self, workspace_id, account, jid): self.store_open_chats(workspace_id) self.emit('chat-removed', account, jid, type_) + def remove_chats_for_account(self, account): + for workspace_id, chat_list in self._chat_lists.items(): + chat_list.remove_chats_for_account(account) + self.store_open_chats(workspace_id) + def _find_chat(self, account, jid): for chat_list in self._chat_lists.values(): if chat_list.contains_chat(account, jid): diff --git a/gajim/gtk/chat_page.py b/gajim/gtk/chat_page.py index d753da81f901d90663e77313191d1fcb61ab5b73..a48bc818e83f8091ff226c9c320ad664ab6bfe91 100644 --- a/gajim/gtk/chat_page.py +++ b/gajim/gtk/chat_page.py @@ -235,6 +235,14 @@ def _on_chat_removed(self, _chat_list, account, jid, type_): client = app.get_client(account) client.get_module('MUC').leave(jid) + def remove_chats_for_account(self, account): + chat_list = self._chat_list_stack.get_current_chat_list() + if chat_list is not None: + chat_list.unselect_all() + + self._chat_list_stack.remove_chats_for_account(account) + self._chat_stack.remove_chats_for_account(account) + def get_control(self, account, jid): return self._chat_stack.get_control(account, jid) diff --git a/gajim/gtk/chat_stack.py b/gajim/gtk/chat_stack.py index 6730277f3061ed57ca39cbea7e8784d050e6fc56..0fbc888d331e162517313d38594dc504618560b6 100644 --- a/gajim/gtk/chat_stack.py +++ b/gajim/gtk/chat_stack.py @@ -91,3 +91,9 @@ def clear(self): def process_event(self, event): control = self.get_control(event.account, event.jid) control.process_event(event) + + def remove_chats_for_account(self, account): + for chat_account, jid in list(self._controls.keys()): + if chat_account != account: + continue + self.remove_chat(account, jid) diff --git a/gajim/gtk/controls/groupchat.py b/gajim/gtk/controls/groupchat.py index 8bb1eaae4f7c4221a45177dc077c5c68d9d580bd..3ae87a7e4cb4d009b9f5b8ade0a1bf9f1fbe1cae 100644 --- a/gajim/gtk/controls/groupchat.py +++ b/gajim/gtk/controls/groupchat.py @@ -1336,12 +1336,6 @@ def shutdown(self, reason=None): app.plugin_manager.remove_gui_extension_point( 'groupchat_control', self) - # They can already be removed by the destroy function - # TODO remove - if self.room_jid in app.contacts.get_gc_list(self.account): - app.contacts.remove_room(self.account, self.room_jid) - del app.gc_connected[self.account][self.room_jid] - self.roster.destroy() self.roster = None diff --git a/gajim/gtk/main.py b/gajim/gtk/main.py index 64aaa6b52e3974fafa2ccb5704349b017eeda986..ff3f14d20c663ae83c2dd260508234b0c7521421 100644 --- a/gajim/gtk/main.py +++ b/gajim/gtk/main.py @@ -74,6 +74,8 @@ def __init__(self): ('muc-disco-update', ged.GUI1, self._on_event), ('our-show', ged.GUI1, self._on_our_show), ('signed-in', ged.GUI1, self._on_signed_in), + ('account-enabled', ged.GUI1, self._on_account_enabled), + ('account-disabled', ged.GUI1, self._on_account_disabled), ]) self._load_chats() @@ -81,6 +83,17 @@ def __init__(self): self._add_actions2() self.show_all() + def _on_account_enabled(self, event): + self._account_side_bar.add_account(event.account) + self._main_stack.add_account_page(event.account) + + def _on_account_disabled(self, event): + workspace_id = self._workspace_side_bar.get_first_workspace() + self.activate_workspace(workspace_id) + self._account_side_bar.remove_account(event.account) + self._main_stack.remove_account_page(event.account) + self._main_stack.remove_chats_for_account(event.account) + @staticmethod def _on_our_show(event): if event.show == 'offline': diff --git a/gajim/gtk/main_stack.py b/gajim/gtk/main_stack.py index cd0bc6265b7eb59a9b57556c2a0f8789ccea05fe..3bb8b0fe243d4c3f2b2a9c27b33d1c3401c69a16 100644 --- a/gajim/gtk/main_stack.py +++ b/gajim/gtk/main_stack.py @@ -24,13 +24,25 @@ class MainStack(Gtk.Stack): def __init__(self): Gtk.Stack.__init__(self) + self.add_named(Gtk.Box(), 'empty') + self._chat_page = ChatPage() self._chat_page.connect('chat-selected', self._on_chat_selected) self.add_named(self._chat_page, 'chats') for account in list(app.connections.keys()): - account_page = AccountPage(account) - self.add_named(account_page, account) + self.add_account_page(account) + + def add_account_page(self, account): + account_page = AccountPage(account) + self.add_named(account_page, account) + + def remove_account_page(self, account): + account_page = self.get_child_by_name(account) + account_page.destroy() + + def remove_chats_for_account(self, account): + self._chat_page.remove_chats_for_account(account) def show_chats(self, workspace_id): self._chat_page.show_workspace_chats(workspace_id) @@ -46,7 +58,10 @@ def get_chat_page(self): return self.get_child_by_name('chats') def process_event(self, event): + empty_box = self.get_child_by_name('empty') for page in self.get_children(): + if page is empty_box: + continue page.process_event(event) def _on_chat_selected(self, *args): diff --git a/gajim/gtk/roster.py b/gajim/gtk/roster.py index 1ed26e10fddbec33612cabc93db2b1dd60c6d167..a1fdb4502978ec92b25cefd21d6418d338f7d181 100644 --- a/gajim/gtk/roster.py +++ b/gajim/gtk/roster.py @@ -615,8 +615,8 @@ def _on_destroy(self, _roster): self._group_refs.clear() self._unset_model() self._roster = None + self._enable_sort(False) self._store.clear() - self._store.reset_default_sort_func() self._store = None # self._tooltip.destroy() # self._tooltip = None diff --git a/gajim/gui_interface.py b/gajim/gui_interface.py index 3eeda6f9dccb7ec5c2f4217b0bf5c2379f951ba2..7d68df4ca515d0d4ecfd4ccad477f7cc0b11af11 100644 --- a/gajim/gui_interface.py +++ b/gajim/gui_interface.py @@ -1417,12 +1417,16 @@ def enable_account(self, account): 'name') app.block_signed_in_notifications[account] = True app.last_message_time[account] = {} - # refresh roster - gui_menu_builder.build_accounts_menu() - app.connections[account].change_status('online', '') app.settings.set_account_setting(account, 'active', True) + gui_menu_builder.build_accounts_menu() app.app.update_app_actions_state() + + app.nec.push_incoming_event(NetworkEvent( + 'account-enabled', + account=account)) + + app.connections[account].change_status('online', '') window = get_app_window('AccountsWindow') if window is not None: GLib.idle_add(window.enable_account, account, True) @@ -1435,6 +1439,15 @@ def disable_account(self, account): continue win.destroy() + app.settings.set_account_setting(account, 'roster_version', '') + app.settings.set_account_setting(account, 'active', False) + gui_menu_builder.build_accounts_menu() + app.app.update_app_actions_state() + + app.nec.push_incoming_event(NetworkEvent( + 'account-disabled', + account=account)) + if account == app.ZEROCONF_ACC_NAME: app.connections[account].disable_account() app.connections[account].cleanup() @@ -1450,11 +1463,6 @@ def disable_account(self, account): del app.newly_added[account] del app.last_message_time[account] - app.settings.set_account_setting(account, 'roster_version', '') - gui_menu_builder.build_accounts_menu() - app.settings.set_account_setting(account, 'active', False) - app.app.update_app_actions_state() - def remove_account(self, account): if app.settings.get_account_setting(account, 'active'): self.disable_account(account)