From 2410121ddb703245cd1c967087749567f21f0397 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philipp=20H=C3=B6rist?= <forenjunkie@chello.at>
Date: Mon, 21 May 2018 21:18:38 +0200
Subject: [PATCH] Add dedicated zeroconf menu

---
 gajim/app_actions.py      | 587 ++++++++++++++++++++------------------
 gajim/application.py      | 111 +++----
 gajim/gui_menu_builder.py |  46 +--
 3 files changed, 389 insertions(+), 355 deletions(-)

diff --git a/gajim/app_actions.py b/gajim/app_actions.py
index 8d4f35a284..5206f901b2 100644
--- a/gajim/app_actions.py
+++ b/gajim/app_actions.py
@@ -1,24 +1,19 @@
-# -*- coding: utf-8 -*-
-## src/app_actions.py
-##
-## Copyright (C) 2017 Philipp Hörist <philipp AT hoerist.com>
-##
-## This file is part of Gajim.
-##
-## Gajim is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published
-## by the Free Software Foundation; version 3 only.
-##
-## Gajim is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
-##
-
-from gi.repository import Gtk
+#
+# Copyright (C) 2017 Philipp Hörist <philipp AT hoerist.com>
+#
+# This file is part of Gajim.
+#
+# Gajim is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published
+# by the Free Software Foundation; version 3 only.
+#
+# Gajim is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
 
 from gajim.common import app
 from gajim.common import helpers
@@ -36,263 +31,295 @@ from gajim.history_sync import HistorySyncAssistant
 from gajim.server_info import ServerInfoDialog
 
 
-class AppActions():
-    ''' Action Callbacks '''
-    def __init__(self, application: Gtk.Application):
-        self.application = application
-
-    # General Actions
-
-    def on_add_contact_jid(self, action, param):
-        dialogs.AddNewContactWindow(None, param.get_string())
-
-    # Application Menu Actions
-
-    def on_preferences(self, action, param):
-        if 'preferences' in interface.instances:
-            interface.instances['preferences'].window.present()
-        else:
-            interface.instances['preferences'] = \
-                config.PreferencesWindow()
-
-    def on_plugins(self, action, param):
-        if 'plugins' in interface.instances:
-            interface.instances['plugins'].window.present()
-        else:
-            interface.instances['plugins'] = gajim.plugins.gui.PluginsWindow()
-
-    def on_accounts(self, action, param):
-        if 'accounts' in app.interface.instances:
-            app.interface.instances['accounts'].present()
-        else:
-            app.interface.instances['accounts'] = accounts_window.AccountsWindow()
-
-    def on_history_manager(self, action, param):
-        from gajim.history_manager import HistoryManager
-        HistoryManager()
-
-    def on_manage_bookmarks(self, action, param):
-        config.ManageBookmarksWindow()
-
-    def on_quit(self, action, param):
-        interface.roster.on_quit_request()
-
-    def on_new_chat(self, action, param):
-        if 'start_chat' in app.interface.instances:
-            app.interface.instances['start_chat'].present()
-        else:
-            app.interface.instances['start_chat'] = dialogs.StartChatDialog()
-
-    # Accounts Actions
-
-    def on_profile(self, action, param):
-        interface.edit_own_details(param.get_string())
-
-    def on_activate_bookmark(self, action, param):
-        dict_ = param.unpack()
-        account, jid, nick, password = \
-            dict_['account'], dict_['jid'], None, None
-        if 'nick' in dict_:
-            nick = dict_['nick']
-        if 'password' in dict_:
-            password = dict_['password']
-        interface.join_gc_room(account, jid, nick, password)
-
-    def on_send_server_message(self, action, param):
-        account = param.get_string()
-        server = app.config.get_per('accounts', account, 'hostname')
-        server += '/announce/online'
-        dialogs.SingleMessageWindow(account, server, 'send')
-
-    def on_service_disco(self, action, param):
-        account = param.get_string()
-        server_jid = app.config.get_per('accounts', account, 'hostname')
-        if server_jid in interface.instances[account]['disco']:
-            interface.instances[account]['disco'][server_jid].\
-                window.present()
-        else:
-            try:
-                # Object will add itself to the window dict
-                disco.ServiceDiscoveryWindow(account, address_entry=True)
-            except GajimGeneralException:
-                pass
-
-    def on_join_gc(self, action, param):
-        account = param.get_string()
-        invisible_show = app.SHOW_LIST.index('invisible')
-        if app.connections[account].connected == invisible_show:
-            app.interface.raise_dialog('join-while-invisible')
+# General Actions
+
+def on_add_contact_jid(action, param):
+    dialogs.AddNewContactWindow(None, param.get_string())
+
+# Application Menu Actions
+
+
+def on_preferences(action, param):
+    if 'preferences' in interface.instances:
+        interface.instances['preferences'].window.present()
+    else:
+        interface.instances['preferences'] = \
+            config.PreferencesWindow()
+
+
+def on_plugins(action, param):
+    if 'plugins' in interface.instances:
+        interface.instances['plugins'].window.present()
+    else:
+        interface.instances['plugins'] = gajim.plugins.gui.PluginsWindow()
+
+
+def on_accounts(action, param):
+    if 'accounts' in app.interface.instances:
+        app.interface.instances['accounts'].present()
+    else:
+        app.interface.instances['accounts'] = accounts_window.AccountsWindow()
+
+
+def on_history_manager(action, param):
+    from gajim.history_manager import HistoryManager
+    HistoryManager()
+
+
+def on_manage_bookmarks(action, param):
+    config.ManageBookmarksWindow()
+
+
+def on_quit(action, param):
+    interface.roster.on_quit_request()
+
+
+def on_new_chat(action, param):
+    if 'start_chat' in app.interface.instances:
+        app.interface.instances['start_chat'].present()
+    else:
+        app.interface.instances['start_chat'] = dialogs.StartChatDialog()
+
+# Accounts Actions
+
+
+def on_profile(action, param):
+    interface.edit_own_details(param.get_string())
+
+
+def on_activate_bookmark(action, param):
+    dict_ = param.unpack()
+    account, jid, nick, password = \
+        dict_['account'], dict_['jid'], None, None
+    if 'nick' in dict_:
+        nick = dict_['nick']
+    if 'password' in dict_:
+        password = dict_['password']
+    interface.join_gc_room(account, jid, nick, password)
+
+
+def on_send_server_message(action, param):
+    account = param.get_string()
+    server = app.config.get_per('accounts', account, 'hostname')
+    server += '/announce/online'
+    dialogs.SingleMessageWindow(account, server, 'send')
+
+
+def on_service_disco(action, param):
+    account = param.get_string()
+    server_jid = app.config.get_per('accounts', account, 'hostname')
+    if server_jid in interface.instances[account]['disco']:
+        interface.instances[account]['disco'][server_jid].\
+            window.present()
+    else:
+        try:
+            # Object will add itself to the window dict
+            disco.ServiceDiscoveryWindow(account, address_entry=True)
+        except GajimGeneralException:
+            pass
+
+
+def on_join_gc(action, param):
+    account = param.get_string()
+    invisible_show = app.SHOW_LIST.index('invisible')
+    if app.connections[account].connected == invisible_show:
+        app.interface.raise_dialog('join-while-invisible')
+        return
+    if 'join_gc' in interface.instances[account]:
+        interface.instances[account]['join_gc'].present()
+    else:
+        interface.instances[account]['join_gc'] = \
+            dialogs.JoinGroupchatWindow(account, None)
+
+
+def on_add_contact(action, param):
+    dialogs.AddNewContactWindow(param.get_string())
+
+
+def on_single_message(action, param):
+    dialogs.SingleMessageWindow(param.get_string(), action='send')
+
+
+def on_merge_accounts(action, param):
+    action.set_state(param)
+    value = param.get_boolean()
+    app.config.set('mergeaccounts', value)
+    # Do not merge accounts if only one active
+    if len(app.connections) >= 2:
+        app.interface.roster.regroup = value
+    else:
+        app.interface.roster.regroup = False
+    app.interface.roster.setup_and_draw_roster()
+
+
+def on_use_pgp_agent(action, param):
+    action.set_state(param)
+    app.config.set('use_gpg_agent', param.get_boolean())
+
+
+def on_add_account(action, param):
+    if 'account_creation_wizard' in app.interface.instances:
+        app.interface.instances['account_creation_wizard'].window.present()
+    else:
+        app.interface.instances['account_creation_wizard'] = \
+            config.AccountCreationWizardWindow()
+
+
+def on_import_contacts(action, param):
+    account = param.get_string()
+    if 'import_contacts' in app.interface.instances:
+        app.interface.instances['import_contacts'].dialog.present()
+    else:
+        app.interface.instances['import_contacts'] = \
+            dialogs.SynchroniseSelectAccountDialog(account)
+
+# Advanced Actions
+
+
+def on_archiving_preferences(action, param):
+    account = param.get_string()
+    if 'archiving_preferences' in interface.instances[account]:
+        interface.instances[account]['archiving_preferences'].window.\
+            present()
+    else:
+        interface.instances[account]['archiving_preferences'] = \
+            dialogs.Archiving313PreferencesWindow(account)
+
+
+def on_history_sync(action, param):
+    account = param.get_string()
+    if 'history_sync' in interface.instances[account]:
+        interface.instances[account]['history_sync'].present()
+    else:
+        interface.instances[account]['history_sync'] = \
+            HistorySyncAssistant(account, interface.roster.window)
+
+
+def on_privacy_lists(action, param):
+    account = param.get_string()
+    if 'privacy_lists' in interface.instances[account]:
+        interface.instances[account]['privacy_lists'].window.present()
+    else:
+        interface.instances[account]['privacy_lists'] = \
+            dialogs.PrivacyListsWindow(account)
+
+
+def on_server_info(action, param):
+    account = param.get_string()
+    if 'server_info' in interface.instances[account]:
+        interface.instances[account]['server_info'].present()
+    else:
+        interface.instances[account]['server_info'] = \
+            ServerInfoDialog(account)
+
+
+def on_xml_console(action, param):
+    account = param.get_string()
+    if 'xml_console' in interface.instances[account]:
+        interface.instances[account]['xml_console'].present()
+    else:
+        interface.instances[account]['xml_console'] = \
+            dialogs.XMLConsoleWindow(account)
+
+
+def on_manage_proxies(action, param):
+    if 'manage_proxies' in app.interface.instances:
+        app.interface.instances['manage_proxies'].window.present()
+    else:
+        app.interface.instances['manage_proxies'] = \
+            config.ManageProxiesWindow(interface.roster.window)
+
+# Admin Actions
+
+
+def on_set_motd(action, param):
+    account = param.get_string()
+    server = app.config.get_per('accounts', account, 'hostname')
+    server += '/announce/motd'
+    dialogs.SingleMessageWindow(account, server, 'send')
+
+
+def on_update_motd(action, param):
+    account = param.get_string()
+    server = app.config.get_per('accounts', account, 'hostname')
+    server += '/announce/motd/update'
+    dialogs.SingleMessageWindow(account, server, 'send')
+
+
+def on_delete_motd(action, param):
+    account = param.get_string()
+    server = app.config.get_per('accounts', account, 'hostname')
+    server += '/announce/motd/delete'
+    app.connections[account].send_motd(server)
+
+# Help Actions
+
+
+def on_contents(action, param):
+    helpers.launch_browser_mailer(
+        'url', 'https://dev.gajim.org/gajim/gajim/wikis')
+
+
+def on_faq(action, param):
+    helpers.launch_browser_mailer(
+        'url', 'https://dev.gajim.org/gajim/gajim/wikis/help/gajimfaq')
+
+
+def on_keyboard_shortcuts(action, param):
+    shortcuts_window.show(app.app.get_active_window())
+
+
+def on_features(action, param):
+    features_window.FeaturesWindow()
+
+
+def on_about(action, param):
+    dialogs.AboutDialog()
+
+# View Actions
+
+
+def on_file_transfers(action, param):
+    if interface.instances['file_transfers']. \
+            window.get_property('visible'):
+        interface.instances['file_transfers'].window.present()
+    else:
+        interface.instances['file_transfers'].window.show_all()
+
+
+def on_history(action, param):
+    if 'logs' in interface.instances:
+        interface.instances['logs'].window.present()
+    else:
+        interface.instances['logs'] = history_window.\
+            HistoryWindow()
+
+
+def on_open_event(action, param):
+    dict_ = param.unpack()
+    app.interface.handle_event(
+        dict_['account'], dict_['jid'], dict_['type_'])
+
+
+# Other Actions
+
+def toggle_ipython(action, param):
+    """
+    Show/hide the ipython window
+    """
+    win = app.ipython_window
+    if win and win.window.is_visible():
+        win.present()
+    else:
+        app.interface.create_ipython_window()
+
+
+def show_next_pending_event(action, param):
+    """
+    Show the window(s) with next pending event in tabbed/group chats
+    """
+    if app.events.get_nb_events():
+        account, jid, event = app.events.get_first_systray_event()
+        if not event:
             return
-        if 'join_gc' in interface.instances[account]:
-            interface.instances[account]['join_gc'].present()
-        else:
-            interface.instances[account]['join_gc'] = \
-                dialogs.JoinGroupchatWindow(account, None)
-
-    def on_add_contact(self, action, param):
-        dialogs.AddNewContactWindow(param.get_string())
-
-    def on_single_message(self, action, param):
-        dialogs.SingleMessageWindow(param.get_string(), action='send')
-
-    def on_merge_accounts(self, action, param):
-        action.set_state(param)
-        value = param.get_boolean()
-        app.config.set('mergeaccounts', value)
-        if len(app.connections) >= 2: # Do not merge accounts if only one active
-            app.interface.roster.regroup = value
-        else:
-            app.interface.roster.regroup = False
-        app.interface.roster.setup_and_draw_roster()
-
-    def on_use_pgp_agent(self, action, param):
-        action.set_state(param)
-        app.config.set('use_gpg_agent', param.get_boolean())
-
-    def on_add_account(self, action, param):
-        if 'account_creation_wizard' in app.interface.instances:
-            app.interface.instances['account_creation_wizard'].window.present()
-        else:
-            app.interface.instances['account_creation_wizard'] = \
-               config.AccountCreationWizardWindow()
-
-    def on_import_contacts(self, action, param):
-        account = param.get_string()
-        if 'import_contacts' in app.interface.instances:
-            app.interface.instances['import_contacts'].dialog.present()
-        else:
-            app.interface.instances['import_contacts'] = \
-                dialogs.SynchroniseSelectAccountDialog(account)
-
-    # Advanced Actions
-
-    def on_archiving_preferences(self, action, param):
-        account = param.get_string()
-        if 'archiving_preferences' in interface.instances[account]:
-            interface.instances[account]['archiving_preferences'].window.\
-                present()
-        else:
-            interface.instances[account]['archiving_preferences'] = \
-                dialogs.Archiving313PreferencesWindow(account)
-
-    def on_history_sync(self, action, param):
-        account = param.get_string()
-        if 'history_sync' in interface.instances[account]:
-            interface.instances[account]['history_sync'].present()
-        else:
-            interface.instances[account]['history_sync'] = \
-                    HistorySyncAssistant(account, interface.roster.window)
-
-    def on_privacy_lists(self, action, param):
-        account = param.get_string()
-        if 'privacy_lists' in interface.instances[account]:
-            interface.instances[account]['privacy_lists'].window.present()
-        else:
-            interface.instances[account]['privacy_lists'] = \
-                    dialogs.PrivacyListsWindow(account)
-
-    def on_server_info(self, action, param):
-        account = param.get_string()
-        if 'server_info' in interface.instances[account]:
-            interface.instances[account]['server_info'].present()
-        else:
-            interface.instances[account]['server_info'] = \
-                    ServerInfoDialog(account)
-
-    def on_xml_console(self, action, param):
-        account = param.get_string()
-        if 'xml_console' in interface.instances[account]:
-            interface.instances[account]['xml_console'].present()
-        else:
-            interface.instances[account]['xml_console'] = \
-                dialogs.XMLConsoleWindow(account)
-
-    def on_manage_proxies(self, action, param):
-        if 'manage_proxies' in app.interface.instances:
-            app.interface.instances['manage_proxies'].window.present()
-        else:
-            app.interface.instances['manage_proxies'] = \
-                config.ManageProxiesWindow(interface.roster.window)
-
-    # Admin Actions
-
-    def on_set_motd(self, action, param):
-        account = param.get_string()
-        server = app.config.get_per('accounts', account, 'hostname')
-        server += '/announce/motd'
-        dialogs.SingleMessageWindow(account, server, 'send')
-
-    def on_update_motd(self, action, param):
-        account = param.get_string()
-        server = app.config.get_per('accounts', account, 'hostname')
-        server += '/announce/motd/update'
-        dialogs.SingleMessageWindow(account, server, 'send')
-
-    def on_delete_motd(self, action, param):
-        account = param.get_string()
-        server = app.config.get_per('accounts', account, 'hostname')
-        server += '/announce/motd/delete'
-        app.connections[account].send_motd(server)
-
-    # Help Actions
-
-    def on_contents(self, action, param):
-        helpers.launch_browser_mailer(
-            'url', 'https://dev.gajim.org/gajim/gajim/wikis')
-
-    def on_faq(self, action, param):
-        helpers.launch_browser_mailer(
-            'url', 'https://dev.gajim.org/gajim/gajim/wikis/help/gajimfaq')
-
-    def on_keyboard_shortcuts(self, action, param):
-        shortcuts_window.show(self.application.get_active_window())
-
-    def on_features(self, action, param):
-        features_window.FeaturesWindow()
-
-    def on_about(self, action, param):
-        dialogs.AboutDialog()
-
-    # View Actions
-
-    def on_file_transfers(self, action, param):
-        if interface.instances['file_transfers']. \
-                window.get_property('visible'):
-            interface.instances['file_transfers'].window.present()
-        else:
-            interface.instances['file_transfers'].window.show_all()
-
-    def on_history(self, action, param):
-        if 'logs' in interface.instances:
-            interface.instances['logs'].window.present()
-        else:
-            interface.instances['logs'] = history_window.\
-                HistoryWindow()
-
-    def on_open_event(self, action, param):
-        dict_ = param.unpack()
-        app.interface.handle_event(dict_['account'], dict_['jid'],
-            dict_['type_'])
-
-
-    # Other Actions
-
-    def toggle_ipython(self, action, param):
-        """
-        Show/hide the ipython window
-        """
-        win = app.ipython_window
-        if win and win.window.is_visible():
-            win.present()
-        else:
-           app.interface.create_ipython_window()
-
-    def show_next_pending_event(self, action, param):
-        """
-        Show the window(s) with next pending event in tabbed/group chats
-        """
-        if app.events.get_nb_events():
-            account, jid, event = app.events.get_first_systray_event()
-            if not event:
-                return
-            app.interface.handle_event(account, jid, event.type_)
+        app.interface.handle_event(account, jid, event.type_)
diff --git a/gajim/application.py b/gajim/application.py
index 954c5dfe98..310fa0246d 100644
--- a/gajim/application.py
+++ b/gajim/application.py
@@ -284,37 +284,14 @@ class GajimApplication(Gtk.Application):
 
     def add_actions(self):
         ''' Build Application Actions '''
-        from gajim.app_actions import AppActions
-        action = AppActions(self)
-
-        self.account_actions = [
-            ('-start-single-chat', action.on_single_message, 'online', 's'),
-            ('-join-groupchat', action.on_join_gc, 'online', 's'),
-            ('-add-contact', action.on_add_contact, 'online', 's'),
-            ('-services', action.on_service_disco, 'online', 's'),
-            ('-profile', action.on_profile, 'feature', 's'),
-            ('-xml-console', action.on_xml_console, 'always', 's'),
-            ('-server-info', action.on_server_info, 'online', 's'),
-            ('-archive', action.on_archiving_preferences, 'feature', 's'),
-            ('-sync-history', action.on_history_sync, 'online', 's'),
-            ('-privacylists', action.on_privacy_lists, 'feature', 's'),
-            ('-send-server-message',
-                action.on_send_server_message, 'online', 's'),
-            ('-set-motd', action.on_set_motd, 'online', 's'),
-            ('-update-motd', action.on_update_motd, 'online', 's'),
-            ('-delete-motd', action.on_delete_motd, 'online', 's'),
-            ('-activate-bookmark',
-                action.on_activate_bookmark, 'online', 'a{sv}'),
-            ('-open-event', action.on_open_event, 'always', 'a{sv}'),
-            ('-import-contacts', action.on_import_contacts, 'online', 's'),
-        ]
+        from gajim import app_actions
 
         # General Stateful Actions
 
         act = Gio.SimpleAction.new_stateful(
             'merge', None,
             GLib.Variant.new_boolean(app.config.get('mergeaccounts')))
-        act.connect('change-state', action.on_merge_accounts)
+        act.connect('change-state', app_actions.on_merge_accounts)
         self.add_action(act)
 
         act = Gio.SimpleAction.new_stateful(
@@ -324,40 +301,38 @@ class GajimApplication(Gtk.Application):
 
         # General Actions
 
-        self.general_actions = [
-            ('quit', action.on_quit),
-            ('accounts', action.on_accounts),
-            ('add-account', action.on_add_account),
-            ('manage-proxies', action.on_manage_proxies),
-            ('start-chat', action.on_new_chat),
-            ('bookmarks', action.on_manage_bookmarks),
-            ('history-manager', action.on_history_manager),
-            ('preferences', action.on_preferences),
-            ('plugins', action.on_plugins),
-            ('file-transfer', action.on_file_transfers),
-            ('history', action.on_history),
-            ('shortcuts', action.on_keyboard_shortcuts),
-            ('features', action.on_features),
-            ('content', action.on_contents),
-            ('about', action.on_about),
-            ('faq', action.on_faq),
-            ('ipython', action.toggle_ipython),
-            ('show-next-pending-event', action.show_next_pending_event),
+        general_actions = [
+            ('quit', app_actions.on_quit),
+            ('accounts', app_actions.on_accounts),
+            ('add-account', app_actions.on_add_account),
+            ('manage-proxies', app_actions.on_manage_proxies),
+            ('start-chat', app_actions.on_new_chat),
+            ('bookmarks', app_actions.on_manage_bookmarks),
+            ('history-manager', app_actions.on_history_manager),
+            ('preferences', app_actions.on_preferences),
+            ('plugins', app_actions.on_plugins),
+            ('file-transfer', app_actions.on_file_transfers),
+            ('history', app_actions.on_history),
+            ('shortcuts', app_actions.on_keyboard_shortcuts),
+            ('features', app_actions.on_features),
+            ('content', app_actions.on_contents),
+            ('about', app_actions.on_about),
+            ('faq', app_actions.on_faq),
+            ('ipython', app_actions.toggle_ipython),
+            ('show-next-pending-event', app_actions.show_next_pending_event),
         ]
 
         act = Gio.SimpleAction.new('add-contact', GLib.VariantType.new('s'))
-        act.connect("activate", action.on_add_contact_jid)
+        act.connect("activate", app_actions.on_add_contact_jid)
         self.add_action(act)
 
-        for action in self.general_actions:
+        for action in general_actions:
             action_name, func = action
             act = Gio.SimpleAction.new(action_name, None)
             act.connect("activate", func)
             self.add_action(act)
 
         accounts_list = sorted(app.config.get_per('accounts'))
-        if 'Local' in accounts_list:
-            accounts_list.remove('Local')
         if not accounts_list:
             return
         if len(accounts_list) > 1:
@@ -366,10 +341,38 @@ class GajimApplication(Gtk.Application):
         else:
             self.add_account_actions(accounts_list[0])
 
-    def add_account_actions(self, account):
+    def _get_account_actions(self, account):
+        from gajim import app_actions
+
         if account == 'Local':
-            return
-        for action in self.account_actions:
+            return [
+                ('-xml-console', app_actions.on_xml_console, 'always', 's')
+            ]
+
+        return [
+            ('-start-single-chat', app_actions.on_single_message, 'online', 's'),
+            ('-join-groupchat', app_actions.on_join_gc, 'online', 's'),
+            ('-add-contact', app_actions.on_add_contact, 'online', 's'),
+            ('-services', app_actions.on_service_disco, 'online', 's'),
+            ('-profile', app_actions.on_profile, 'feature', 's'),
+            ('-xml-console', app_actions.on_xml_console, 'always', 's'),
+            ('-server-info', app_actions.on_server_info, 'online', 's'),
+            ('-archive', app_actions.on_archiving_preferences, 'feature', 's'),
+            ('-sync-history', app_actions.on_history_sync, 'online', 's'),
+            ('-privacylists', app_actions.on_privacy_lists, 'feature', 's'),
+            ('-send-server-message',
+                app_actions.on_send_server_message, 'online', 's'),
+            ('-set-motd', app_actions.on_set_motd, 'online', 's'),
+            ('-update-motd', app_actions.on_update_motd, 'online', 's'),
+            ('-delete-motd', app_actions.on_delete_motd, 'online', 's'),
+            ('-activate-bookmark',
+                app_actions.on_activate_bookmark, 'online', 'a{sv}'),
+            ('-open-event', app_actions.on_open_event, 'always', 'a{sv}'),
+            ('-import-contacts', app_actions.on_import_contacts, 'online', 's'),
+        ]
+
+    def add_account_actions(self, account):
+        for action in self._get_account_actions(account):
             action_name, func, state, type_ = action
             action_name = account + action_name
             if self.lookup_action(action_name):
@@ -383,14 +386,12 @@ class GajimApplication(Gtk.Application):
             self.add_action(act)
 
     def remove_account_actions(self, account):
-        for action in self.account_actions:
+        for action in self._get_account_actions(account):
             action_name = account + action[0]
             self.remove_action(action_name)
 
     def set_account_actions_state(self, account, new_state=False):
-        if account == 'Local':
-            return
-        for action in self.account_actions:
+        for action in self._get_account_actions(account):
             action_name, _, state, _ = action
             if not new_state and state in ('online', 'feature'):
                 # We go offline
diff --git a/gajim/gui_menu_builder.py b/gajim/gui_menu_builder.py
index ca25141667..fbddd89ae1 100644
--- a/gajim/gui_menu_builder.py
+++ b/gajim/gui_menu_builder.py
@@ -727,25 +727,29 @@ def get_account_menu(account):
         sub menu: list
     '''
     account_menu = [
-            ('-add-contact', _('Add Contact…')),
-            ('-join-groupchat', _('Join Group Chat')),
-            ('-profile', _('Profile')),
-            ('-services', _('Discover Services')),
-            ('-start-single-chat', _('Send Single Message…')),
-            (_('Advanced'), [
-                ('-archive', _('Archiving Preferences')),
-                ('-sync-history', _('Synchronise History')),
-                ('-privacylists', _('Privacy Lists')),
-                ('-server-info', _('Server Info')),
-                ('-xml-console', _('XML Console'))
-                ]),
-            (_('Admin'), [
-                ('-send-server-message', _('Send Server Message…')),
-                ('-set-motd', _('Set MOTD…')),
-                ('-update-motd', _('Update MOTD…')),
-                ('-delete-motd', _('Delete MOTD…'))
-                ]),
-            ]
+        ('-add-contact', _('Add Contact…')),
+        ('-join-groupchat', _('Join Group Chat')),
+        ('-profile', _('Profile')),
+        ('-services', _('Discover Services')),
+        ('-start-single-chat', _('Send Single Message…')),
+        (_('Advanced'), [
+            ('-archive', _('Archiving Preferences')),
+            ('-sync-history', _('Synchronise History')),
+            ('-privacylists', _('Privacy Lists')),
+            ('-server-info', _('Server Info')),
+            ('-xml-console', _('XML Console'))
+        ]),
+        (_('Admin'), [
+            ('-send-server-message', _('Send Server Message…')),
+            ('-set-motd', _('Set MOTD…')),
+            ('-update-motd', _('Update MOTD…')),
+            ('-delete-motd', _('Delete MOTD…'))
+        ]),
+    ]
+
+    zeroconf_menu = [
+        ('-xml-console', _('XML Console')),
+    ]
 
     def build_menu(preset):
         menu = Gio.Menu()
@@ -769,6 +773,8 @@ def get_account_menu(account):
                 menu.append_submenu(label, submenu)
         return menu
 
+    if account == 'Local':
+        return build_menu(zeroconf_menu)
     return build_menu(account_menu)
 
 
@@ -781,7 +787,7 @@ def build_accounts_menu():
 
     acc_menu = menubar.get_item_link(menu_position, 'submenu')
     acc_menu.remove_all()
-    accounts_list = sorted(app.contacts.get_accounts(zeroconf=False))
+    accounts_list = sorted(app.contacts.get_accounts())
     if not accounts_list:
         no_accounts = _('No Accounts available')
         acc_menu.append_item(Gio.MenuItem.new(no_accounts, None))
-- 
GitLab