diff --git a/data/glade/chat_control_popup_menu.glade b/data/glade/chat_control_popup_menu.glade deleted file mode 100644 index 1c923adbd..000000000 --- a/data/glade/chat_control_popup_menu.glade +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - True - _Add to Roster - True - - - - True - gtk-add - 1 - - - - - - - True - Send _File - True - - - - True - gtk-save - 1 - - - - - - - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - True - Invite _Contacts - True - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - gtk-missing-image - - - - - - - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - True - - - - - True - Toggle Open_PGP Encryption - True - - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Toggle End to End Encryption - True - - - - - - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - True - - - - - True - gtk-info - True - True - - - - - True - _History - True - - - True - gtk-justify-fill - 1 - - - - - - diff --git a/data/glade/roster_contact_context_menu.glade b/data/glade/contact_context_menu.glade similarity index 70% rename from data/glade/roster_contact_context_menu.glade rename to data/glade/contact_context_menu.glade index 0629a8029..59989970d 100644 --- a/data/glade/roster_contact_context_menu.glade +++ b/data/glade/contact_context_menu.glade @@ -1,102 +1,150 @@ - - - + - + + + - True Start _Chat + True True + False - + True gtk-jump-to - 1 + 1 - True Send Single _Message... + True True + False - + True gtk-new - 1 + 1 - True Send _File... + True True + False - + True gtk-save - 1 + 1 - True In_vite to + True True + False - + True - gtk-go-back - 1 + gtk-missing-image + 1 - + + Invite _Contacts + True + True + False + + + True + gtk-missing-image + 1 + + + + + + + True + + + + + True + Toggle Open_PGP Encryption + True + + + + + True + Toggle End to End Encryption + True + + + + True - True Send Cus_tom Status + True True + False True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + gtk-missing-image + 1 + + + E_xecute Command... True - Execute Command... True + False - + True gtk-execute - 1 + 1 + _Manage Contact True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - _Manage Contact True + False True @@ -105,11 +153,12 @@ _Rename... True + False - + True gtk-refresh - 1 + 1 @@ -118,12 +167,12 @@ Edit _Groups... True + False - + True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK gtk-edit - 1 + 1 @@ -132,42 +181,44 @@ Assign Open_PGP Key... True + False - + True gtk-dialog-authentication - 1 + 1 + Set Custom _Avatar... True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Set Custom _Avatar... True + False - + True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK gtk-orientation-portrait - 1 + 1 - True Add Special _Notification... + True True + False - + True gtk-info - 1 + 1 @@ -182,46 +233,50 @@ _Subscription True + False - True _Allow him/her to see my status + True True + False - + True gtk-go-up - 1 + 1 - True A_sk to see his/her status + True True + False - + True gtk-go-down - 1 + 1 - True _Forbid him/her to see my status + True True + False - + True gtk-stop - 1 + 1 @@ -229,66 +284,70 @@ - + True gtk-dialog-question - 1 + 1 - True _Unblock + True True + False - + True gtk-stop - 1 + 1 - True _Block + True True + False - + True gtk-stop - 1 + 1 - True _Unignore + True True + False - + True gtk-stop - 1 + 1 - True _Ignore + True True + False - + True gtk-stop - 1 + 1 @@ -297,11 +356,12 @@ _Add to Roster... True + False - + True gtk-add - 1 + 1 @@ -310,11 +370,12 @@ Remo_ve True + False - + True gtk-remove - 1 + 1 @@ -322,17 +383,16 @@ - + True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK gtk-properties - 1 + 1 - + True @@ -347,11 +407,12 @@ _History True + False - + True gtk-justify-fill - 1 + 1 diff --git a/data/glade/zeroconf_contact_context_menu.glade b/data/glade/zeroconf_contact_context_menu.glade deleted file mode 100644 index 93d901f1c..000000000 --- a/data/glade/zeroconf_contact_context_menu.glade +++ /dev/null @@ -1,169 +0,0 @@ - - - - - - - - Start _Chat - True - True - False - - - True - gtk-jump-to - 1 - - - - - - - Send _File - True - True - False - - - True - gtk-save - 1 - - - - - - - True - - - - - Execute Command... - True - False - - - True - gtk-execute - 1 - - - - - - - _Manage Contact - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - True - False - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - _Rename - True - False - - - True - gtk-refresh - 1 - - - - - - - Edit _Groups - True - False - - - True - gtk-edit - 1 - - - - - - - Assign Open_PGP Key - True - False - - - - True - gtk-dialog-authentication - 1 - - - - - - - Add Special _Notification - True - True - False - - - True - gtk-info - 1 - - - - - - - - - True - gtk-properties - 1 - - - - - - - True - - - - - _Information - True - False - - - True - gtk-info - 1 - - - - - - - _History - True - False - - - True - gtk-justify-fill - 1 - - - - - - diff --git a/src/chat_control.py b/src/chat_control.py index 1dc544bef..559c99521 100644 --- a/src/chat_control.py +++ b/src/chat_control.py @@ -33,6 +33,7 @@ import gtk import pango import gobject import gtkgui_helpers +import gui_menu_builder import message_control import dialogs import history_window @@ -874,7 +875,7 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools): def on_actions_button_clicked(self, widget): '''popup action menu''' - menu = self.prepare_context_menu(True) + menu = self.prepare_context_menu(hide_buttonbar_items=True) menu.show_all() gtkgui_helpers.popup_emoticons_under_button(menu, widget, self.parent_win) @@ -2068,135 +2069,19 @@ class ChatControl(ChatControlBase): return tab_img - def prepare_context_menu(self, hide_buttonbar_entries = False): + def prepare_context_menu(self, hide_buttonbar_items=False): '''sets compact view menuitem active state sets active and sensitivity state for toggle_gpg_menuitem sets sensitivity for history_menuitem (False for tranasports) and file_transfer_menuitem and hide()/show() for add_to_roster_menuitem ''' - xml = gtkgui_helpers.get_glade('chat_control_popup_menu.glade') - menu = xml.get_widget('chat_control_popup_menu') - - add_to_roster_menuitem = xml.get_widget('add_to_roster_menuitem') - history_menuitem = xml.get_widget('history_menuitem') - toggle_gpg_menuitem = xml.get_widget('toggle_gpg_menuitem') - toggle_e2e_menuitem = xml.get_widget('toggle_e2e_menuitem') - send_file_menuitem = xml.get_widget('send_file_menuitem') - information_menuitem = xml.get_widget('information_menuitem') - convert_to_gc_menuitem = xml.get_widget('convert_to_groupchat') - separatormenuitem1 = xml.get_widget('separatormenuitem1') - separatormenuitem2 = xml.get_widget('separatormenuitem2') - - # add a special img for send file menuitem - path_to_upload_img = os.path.join(gajim.DATA_DIR, 'pixmaps', 'upload.png') - img = gtk.Image() - img.set_from_file(path_to_upload_img) - send_file_menuitem.set_image(img) - - muc_icon = gtkgui_helpers.load_icon('muc_active') - if muc_icon: - convert_to_gc_menuitem.set_image(muc_icon) - - if not hide_buttonbar_entries: - history_menuitem.show() - send_file_menuitem.show() - information_menuitem.show() - convert_to_gc_menuitem.show() - separatormenuitem1.show() - separatormenuitem2.show() - - ag = gtk.accel_groups_from_object(self.parent_win.window)[0] - send_file_menuitem.add_accelerator('activate', ag, gtk.keysyms.f, gtk.gdk.CONTROL_MASK, - gtk.ACCEL_VISIBLE) - convert_to_gc_menuitem.add_accelerator('activate', ag, gtk.keysyms.g, gtk.gdk.CONTROL_MASK, - gtk.ACCEL_VISIBLE) - history_menuitem.add_accelerator('activate', ag, gtk.keysyms.h, gtk.gdk.CONTROL_MASK, - gtk.ACCEL_VISIBLE) - information_menuitem.add_accelerator('activate', ag, gtk.keysyms.i, - gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) - - contact = self.parent_win.get_active_contact() - jid = contact.jid - - e2e_is_active = self.session is not None and self.session.enable_encryption - - # check if we support and use gpg - if not gajim.config.get_per('accounts', self.account, 'keyid') or\ - not gajim.connections[self.account].USE_GPG or\ - gajim.jid_is_transport(jid): - toggle_gpg_menuitem.set_sensitive(False) - else: - toggle_gpg_menuitem.set_sensitive(self.gpg_is_active or not e2e_is_active) - toggle_gpg_menuitem.set_active(self.gpg_is_active) - - # disable esessions if we or the other client don't support them - if not gajim.HAVE_PYCRYPTO or not contact.supports(NS_ESESSION) or \ - not gajim.config.get_per('accounts', self.account, 'enable_esessions'): - toggle_e2e_menuitem.set_sensitive(False) - else: - toggle_e2e_menuitem.set_active(e2e_is_active) - toggle_e2e_menuitem.set_sensitive(e2e_is_active or not self.gpg_is_active) - - # add_to_roster_menuitem - if not hide_buttonbar_entries and _('Not in Roster') in contact.groups: - add_to_roster_menuitem.show() - - # check if it's possible to send a file - if contact.supports(NS_FILE): - send_file_menuitem.set_sensitive(True) - else: - send_file_menuitem.set_sensitive(False) - - # check if it's possible to convert to groupchat - if contact.supports(NS_MUC): - convert_to_gc_menuitem.set_sensitive(True) - else: - convert_to_gc_menuitem.set_sensitive(False) - - # connect signals - id_ = history_menuitem.connect('activate', - self._on_history_menuitem_activate) - self.handlers[id_] = history_menuitem - id_ = send_file_menuitem.connect('activate', - self._on_send_file_menuitem_activate) - self.handlers[id_] = send_file_menuitem - id_ = add_to_roster_menuitem.connect('activate', - self._on_add_to_roster_menuitem_activate) - self.handlers[id_] = add_to_roster_menuitem - id_ = toggle_gpg_menuitem.connect('activate', - self._on_toggle_gpg_menuitem_activate) - self.handlers[id_] = toggle_gpg_menuitem - id_ = toggle_e2e_menuitem.connect('activate', - self._on_toggle_e2e_menuitem_activate) - self.handlers[id_] = toggle_e2e_menuitem - id_ = information_menuitem.connect('activate', - self._on_contact_information_menuitem_activate) - self.handlers[id_] = information_menuitem - id_ = convert_to_gc_menuitem.connect('activate', - self._on_convert_to_gc_menuitem_activate) - self.handlers[id_] = convert_to_gc_menuitem - - menu.connect('selection-done', self.destroy_menu, - send_file_menuitem, convert_to_gc_menuitem, - information_menuitem, history_menuitem) + menu = gui_menu_builder.get_contact_menu(self.contact, self.account, + use_multiple_contacts=False, show_start_chat=False, + show_encryption=True, control=self, + show_buttonbar_items=not hide_buttonbar_items) return menu - def destroy_menu(self, menu, send_file_menuitem, - convert_to_gc_menuitem, information_menuitem, history_menuitem): - # destroy accelerators - ag = gtk.accel_groups_from_object(self.parent_win.window)[0] - send_file_menuitem.remove_accelerator(ag, gtk.keysyms.f, - gtk.gdk.CONTROL_MASK) - convert_to_gc_menuitem.remove_accelerator(ag, gtk.keysyms.g, - gtk.gdk.CONTROL_MASK) - information_menuitem.remove_accelerator(ag, gtk.keysyms.i, - gtk.gdk.CONTROL_MASK) - history_menuitem.remove_accelerator(ag, gtk.keysyms.h, - gtk.gdk.CONTROL_MASK) - # destroy menu - menu.destroy() - def send_chatstate(self, state, contact = None): ''' sends OUR chatstate as STANDLONE chat state message (eg. no body) to contact only if new chatstate is different from the previous one diff --git a/src/gajim.py b/src/gajim.py index b488bf68c..5eb571592 100644 --- a/src/gajim.py +++ b/src/gajim.py @@ -2646,7 +2646,7 @@ class Interface: #detects eg. *b* *bold* *bold bold* test *bold* *bold*! (*bold*) #doesn't detect (it's a feature :P) * bold* *bold * * bold * test*bold* formatting = r'|(? +## +## 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 . +## + +import gtk +import os +import gtkgui_helpers +import message_control + +from common import gajim +from common import helpers +from common.xmpp.protocol import NS_COMMANDS, NS_FILE, NS_MUC, NS_ESESSION + +def build_resources_submenu(contacts, account, action, room_jid=None, +room_account=None, cap=None): + ''' Build a submenu with contact's resources. + room_jid and room_account are for action self.on_invite_to_room ''' + sub_menu = gtk.Menu() + + iconset = gajim.config.get('iconset') + if not iconset: + iconset = gajim.config.DEFAULT_ICONSET + path = os.path.join(helpers.get_iconset_path(iconset), '16x16') + for c in contacts: + # icon MUST be different instance for every item + state_images = gtkgui_helpers.load_iconset(path) + item = gtk.ImageMenuItem('%s (%s)' % (c.resource, str(c.priority))) + icon_name = helpers.get_icon_name_to_show(c, account) + icon = state_images[icon_name] + item.set_image(icon) + sub_menu.append(item) + + if action == roster.on_invite_to_room: + item.connect('activate', action, [(c, account)], room_jid, + room_account, c.resource) + elif action == roster.on_invite_to_new_room: + item.connect('activate', action, [(c, account)], c.resource) + else: # start_chat, execute_command, send_file + item.connect('activate', action, c, account, c.resource) + + if cap and not c.supports(cap): + item.set_sensitive(False) + + return sub_menu + +def build_invite_submenu(invite_menuitem, list_): + '''list_ in a list of (contact, account)''' + roster = gajim.interface.roster + # used if we invite only one contact with several resources + contact_list = [] + if len(list_) == 1: + contact, account = list_[0] + contact_list = gajim.contacts.get_contacts(account, contact.jid) + contacts_transport = -1 + connected_accounts = [] + # -1 is at start, False when not from the same, None when jabber + for (contact, account) in list_: + if not account in connected_accounts: + connected_accounts.append(account) + transport = gajim.get_transport_name_from_jid(contact.jid) + if contacts_transport == -1: + contacts_transport = transport + elif contacts_transport != transport: + contacts_transport = False + + if contacts_transport == False: + # they are not all from the same transport + invite_menuitem.set_sensitive(False) + return + invite_to_submenu = gtk.Menu() + invite_menuitem.set_submenu(invite_to_submenu) + invite_to_new_room_menuitem = gtk.ImageMenuItem(_('_New Group Chat')) + icon = gtk.image_new_from_stock(gtk.STOCK_NEW, gtk.ICON_SIZE_MENU) + invite_to_new_room_menuitem.set_image(icon) + if len(contact_list) > 1: # several resources + invite_to_new_room_menuitem.set_submenu(build_resources_submenu( + contact_list, account, roster.on_invite_to_new_room, cap=NS_MUC)) + elif len(list_) == 1 and contact.supports(NS_MUC): + invite_menuitem.set_sensitive(True) + # use resource if it's self contact + if contact.jid == gajim.get_jid_from_account(account): + resource = contact.resource + else: + resource = None + invite_to_new_room_menuitem.connect('activate', + roster.on_invite_to_new_room, list_, resource) + else: + invite_menuitem.set_sensitive(False) + # transform None in 'jabber' + c_t = contacts_transport or 'jabber' + muc_jid = {} + for account in connected_accounts: + for t in gajim.connections[account].muc_jid: + muc_jid[t] = gajim.connections[account].muc_jid[t] + if c_t not in muc_jid: + invite_to_new_room_menuitem.set_sensitive(False) + rooms = [] # a list of (room_jid, account) tuple + invite_to_submenu.append(invite_to_new_room_menuitem) + rooms = [] # a list of (room_jid, account) tuple + minimized_controls = [] + for account in connected_accounts: + minimized_controls += gajim.interface.minimized_controls[account].values() + for gc_control in gajim.interface.msg_win_mgr.get_controls( + message_control.TYPE_GC) + minimized_controls: + acct = gc_control.account + room_jid = gc_control.room_jid + if room_jid in gajim.gc_connected[acct] and \ + gajim.gc_connected[acct][room_jid] and \ + contacts_transport == gajim.get_transport_name_from_jid(room_jid): + rooms.append((room_jid, acct)) + if len(rooms): + item = gtk.SeparatorMenuItem() # separator + invite_to_submenu.append(item) + for (room_jid, account) in rooms: + menuitem = gtk.MenuItem(room_jid.split('@')[0]) + if len(contact_list) > 1: # several resources + menuitem.set_submenu(build_resources_submenu( + contact_list, account, roster.on_invite_to_room, room_jid, + account)) + else: + # use resource if it's self contact + if contact.jid == gajim.get_jid_from_account(account): + resource = contact.resource + else: + resource = None + menuitem.connect('activate', roster.on_invite_to_room, list_, + room_jid, account, resource) + invite_to_submenu.append(menuitem) + +def get_contact_menu(contact, account, use_multiple_contacts=True, +show_start_chat=True, show_encryption=False, show_buttonbar_items=True, +control=None): + ''' Build contact popup menu for roster and chat window. + If control is not set, we hide invite_contacts_menuitem''' + if not contact: + return + + jid = contact.jid + our_jid = jid == gajim.get_jid_from_account(account) + roster = gajim.interface.roster + + xml = gtkgui_helpers.get_glade('contact_context_menu.glade') + contact_context_menu = xml.get_widget('contact_context_menu') + + start_chat_menuitem = xml.get_widget('start_chat_menuitem') + execute_command_menuitem = xml.get_widget('execute_command_menuitem') + rename_menuitem = xml.get_widget('rename_menuitem') + edit_groups_menuitem = xml.get_widget('edit_groups_menuitem') + send_file_menuitem = xml.get_widget('send_file_menuitem') + assign_openpgp_key_menuitem = xml.get_widget('assign_openpgp_key_menuitem') + add_special_notification_menuitem = xml.get_widget( + 'add_special_notification_menuitem') + information_menuitem = xml.get_widget('information_menuitem') + history_menuitem = xml.get_widget('history_menuitem') + send_custom_status_menuitem = xml.get_widget('send_custom_status_menuitem') + send_single_message_menuitem = xml.get_widget('send_single_message_menuitem') + invite_menuitem = xml.get_widget('invite_menuitem') + block_menuitem = xml.get_widget('block_menuitem') + unblock_menuitem = xml.get_widget('unblock_menuitem') + ignore_menuitem = xml.get_widget('ignore_menuitem') + unignore_menuitem = xml.get_widget('unignore_menuitem') + set_custom_avatar_menuitem = xml.get_widget('set_custom_avatar_menuitem') + # Subscription submenu + subscription_menuitem = xml.get_widget('subscription_menuitem') + send_auth_menuitem, ask_auth_menuitem, revoke_auth_menuitem = \ + subscription_menuitem.get_submenu().get_children() + add_to_roster_menuitem = xml.get_widget('add_to_roster_menuitem') + remove_from_roster_menuitem = xml.get_widget( + 'remove_from_roster_menuitem') + manage_contact_menuitem = xml.get_widget('manage_contact') + convert_to_gc_menuitem = xml.get_widget('convert_to_groupchat_menuitem') + encryption_separator = xml.get_widget('encryption_separator') + toggle_gpg_menuitem = xml.get_widget('toggle_gpg_menuitem') + toggle_e2e_menuitem = xml.get_widget('toggle_e2e_menuitem') + last_separator = xml.get_widget('last_separator') + + items_to_hide = [] + + # add a special img for send file menuitem + path_to_upload_img = os.path.join(gajim.DATA_DIR, 'pixmaps', 'upload.png') + img = gtk.Image() + img.set_from_file(path_to_upload_img) + send_file_menuitem.set_image(img) + + if not our_jid: + # add a special img for rename menuitem + path_to_kbd_input_img = os.path.join(gajim.DATA_DIR, 'pixmaps', + 'kbd_input.png') + img = gtk.Image() + img.set_from_file(path_to_kbd_input_img) + rename_menuitem.set_image(img) + + muc_icon = gtkgui_helpers.load_icon('muc_active') + if muc_icon: + convert_to_gc_menuitem.set_image(muc_icon) + + contacts = gajim.contacts.get_contacts(account, jid) + if len(contacts) > 1 and use_multiple_contacts: # several resources + start_chat_menuitem.set_submenu(build_resources_submenu(contacts, + account, gajim.interface.on_open_chat_window)) + send_file_menuitem.set_submenu(build_resources_submenu(contacts, + account, roster.on_send_file_menuitem_activate, cap=NS_FILE)) + execute_command_menuitem.set_submenu(build_resources_submenu( + contacts, account, roster.on_execute_command, cap=NS_COMMANDS)) + else: + start_chat_menuitem.connect('activate', + gajim.interface.on_open_chat_window, contact, account) + if contact.supports(NS_FILE): + send_file_menuitem.set_sensitive(True) + send_file_menuitem.connect('activate', + roster.on_send_file_menuitem_activate, contact, account) + else: + send_file_menuitem.set_sensitive(False) + + if contact.supports(NS_COMMANDS): + execute_command_menuitem.set_sensitive(True) + execute_command_menuitem.connect('activate', roster.on_execute_command, + contact, account, contact.resource) + else: + execute_command_menuitem.set_sensitive(False) + + rename_menuitem.connect('activate', roster.on_rename, 'contact', jid, + account) + history_menuitem.connect('activate', roster.on_history, contact, account) + + if _('Not in Roster') not in contact.get_shown_groups(): + # contact is in normal group + edit_groups_menuitem.connect('activate', roster.on_edit_groups, [(contact, + account)]) + + if gajim.connections[account].gpg: + assign_openpgp_key_menuitem.connect('activate', + roster.on_assign_pgp_key, contact, account) + else: + assign_openpgp_key_menuitem.set_sensitive(False) + else: + # contact is in group 'Not in Roster' + edit_groups_menuitem.set_sensitive(False) + assign_openpgp_key_menuitem.set_sensitive(False) + + # Hide items when it's self contact row + if our_jid: + items_to_hide += [rename_menuitem, edit_groups_menuitem] + + # Unsensitive many items when account is offline + if gajim.account_is_disconnected(account): + for widget in (start_chat_menuitem, rename_menuitem, + edit_groups_menuitem, send_file_menuitem): + widget.set_sensitive(False) + + if not show_start_chat: + items_to_hide.append(start_chat_menuitem) + + if not show_encryption or not control: + items_to_hide += [encryption_separator, toggle_gpg_menuitem, + toggle_e2e_menuitem] + else: + e2e_is_active = control.session is not None and \ + control.session.enable_encryption + + # check if we support and use gpg + if not gajim.config.get_per('accounts', account, 'keyid') or \ + not gajim.connections[account].USE_GPG or gajim.jid_is_transport( + contact.jid): + toggle_gpg_menuitem.set_sensitive(False) + else: + toggle_gpg_menuitem.set_sensitive(control.gpg_is_active or \ + not e2e_is_active) + toggle_gpg_menuitem.set_active(control.gpg_is_active) + + # disable esessions if we or the other client don't support them + if not gajim.HAVE_PYCRYPTO or not contact.supports(NS_ESESSION) or \ + not gajim.config.get_per('accounts', account, 'enable_esessions'): + toggle_e2e_menuitem.set_sensitive(False) + else: + toggle_e2e_menuitem.set_active(e2e_is_active) + toggle_e2e_menuitem.set_sensitive(e2e_is_active or \ + not control.gpg_is_active) + + if not show_buttonbar_items: + items_to_hide += [history_menuitem, send_file_menuitem, + information_menuitem, convert_to_gc_menuitem, last_separator] + + if not control: + items_to_hide.append(convert_to_gc_menuitem) + + for item in items_to_hide: + item.set_no_show_all(True) + item.hide() + + # Zeroconf Account + if gajim.config.get_per('accounts', account, 'is_zeroconf'): + for item in (send_custom_status_menuitem, send_single_message_menuitem, + invite_menuitem, block_menuitem, unblock_menuitem, ignore_menuitem, + unignore_menuitem, set_custom_avatar_menuitem, subscription_menuitem, + manage_contact_menuitem): + item.set_no_show_all(True) + item.hide() + + if contact.show in ('offline', 'error'): + information_menuitem.set_sensitive(False) + send_file_menuitem.set_sensitive(False) + else: + information_menuitem.connect('activate', roster.on_info_zeroconf, + contact, account) + + contact_context_menu.connect('selection-done', + gtkgui_helpers.destroy_widget) + contact_context_menu.show_all() + return contact_context_menu + + # normal account + + # send custom status icon + blocked = False + if helpers.jid_is_blocked(account, jid): + blocked = True + else: + for group in contact.get_shown_groups(): + if helpers.group_is_blocked(account, group): + blocked = True + break + if gajim.get_transport_name_from_jid(jid, use_config_setting=False): + # Transport contact, send custom status unavailable + send_custom_status_menuitem.set_sensitive(False) + elif blocked: + send_custom_status_menuitem.set_image(gtkgui_helpers.load_icon('offline')) + send_custom_status_menuitem.set_sensitive(False) + elif account in gajim.interface.status_sent_to_users and \ + jid in gajim.interface.status_sent_to_users[account]: + send_custom_status_menuitem.set_image(gtkgui_helpers.load_icon( + gajim.interface.status_sent_to_users[account][jid])) + else: + icon = gtk.image_new_from_stock(gtk.STOCK_NETWORK, gtk.ICON_SIZE_MENU) + send_custom_status_menuitem.set_image(icon) + + muc_icon = gtkgui_helpers.load_icon('muc_active') + if muc_icon: + invite_menuitem.set_image(muc_icon) + + build_invite_submenu(invite_menuitem, [(contact, account)]) + + # One or several resource, we do the same for send_custom_status + status_menuitems = gtk.Menu() + send_custom_status_menuitem.set_submenu(status_menuitems) + iconset = gajim.config.get('iconset') + path = os.path.join(helpers.get_iconset_path(iconset), '16x16') + for s in ('online', 'chat', 'away', 'xa', 'dnd', 'offline'): + # icon MUST be different instance for every item + state_images = gtkgui_helpers.load_iconset(path) + status_menuitem = gtk.ImageMenuItem(helpers.get_uf_show(s)) + status_menuitem.connect('activate', roster.on_send_custom_status, + [(contact, account)], s) + icon = state_images[s] + status_menuitem.set_image(icon) + status_menuitems.append(status_menuitem) + + send_single_message_menuitem.connect('activate', + roster.on_send_single_message_menuitem_activate, account, contact) + + remove_from_roster_menuitem.connect('activate', roster.on_req_usub, + [(contact, account)]) + information_menuitem.connect('activate', roster.on_info, contact, account) + + if _('Not in Roster') not in contact.get_shown_groups(): + # contact is in normal group + add_to_roster_menuitem.hide() + add_to_roster_menuitem.set_no_show_all(True) + + if contact.sub in ('from', 'both'): + send_auth_menuitem.set_sensitive(False) + else: + send_auth_menuitem.connect('activate', roster.authorize, jid, account) + if contact.sub in ('to', 'both'): + ask_auth_menuitem.set_sensitive(False) + add_special_notification_menuitem.connect('activate', + roster.on_add_special_notification_menuitem_activate, jid) + else: + ask_auth_menuitem.connect('activate', roster.req_sub, jid, + _('I would like to add you to my roster'), account, + contact.groups, contact.name) + if contact.sub in ('to', 'none') or gajim.get_transport_name_from_jid( + jid, use_config_setting=False): + revoke_auth_menuitem.set_sensitive(False) + else: + revoke_auth_menuitem.connect('activate', roster.revoke_auth, jid, + account) + + else: + # contact is in group 'Not in Roster' + add_to_roster_menuitem.set_no_show_all(False) + subscription_menuitem.set_sensitive(False) + + add_to_roster_menuitem.connect('activate', roster.on_add_to_roster, + contact, account) + + set_custom_avatar_menuitem.connect('activate', + roster.on_set_custom_avatar_activate, contact, account) + + # Hide items when it's self contact row + if our_jid: + manage_contact_menuitem.set_sensitive(False) + + # Unsensitive items when account is offline + if gajim.account_is_disconnected(account): + for widget in (send_single_message_menuitem, subscription_menuitem, + add_to_roster_menuitem, remove_from_roster_menuitem, + execute_command_menuitem, send_custom_status_menuitem): + widget.set_sensitive(False) + + if gajim.connections[account] and gajim.connections[account].\ + privacy_rules_supported: + if helpers.jid_is_blocked(account, jid): + block_menuitem.set_no_show_all(True) + block_menuitem.hide() + if gajim.get_transport_name_from_jid(jid, use_config_setting=False): + unblock_menuitem.set_no_show_all(True) + unblock_menuitem.hide() + unignore_menuitem.set_no_show_all(False) + unignore_menuitem.connect('activate', roster.on_unblock, [(contact, + account)]) + else: + unblock_menuitem.connect('activate', roster.on_unblock, [(contact, + account)]) + else: + unblock_menuitem.set_no_show_all(True) + unblock_menuitem.hide() + if gajim.get_transport_name_from_jid(jid, use_config_setting=False): + block_menuitem.set_no_show_all(True) + block_menuitem.hide() + ignore_menuitem.set_no_show_all(False) + ignore_menuitem.connect('activate', roster.on_block, [(contact, + account)]) + else: + block_menuitem.connect('activate', roster.on_block, [(contact, + account)]) + else: + unblock_menuitem.set_no_show_all(True) + block_menuitem.set_sensitive(False) + unblock_menuitem.hide() + + contact_context_menu.connect('selection-done', gtkgui_helpers.destroy_widget) + contact_context_menu.show_all() + return contact_context_menu + +# vim: se ts=3: diff --git a/src/roster_window.py b/src/roster_window.py index 378773955..24a0b340f 100644 --- a/src/roster_window.py +++ b/src/roster_window.py @@ -46,6 +46,7 @@ import vcard import config import disco import gtkgui_helpers +import gui_menu_builder import cell_renderer_image import tooltips import message_control @@ -64,7 +65,7 @@ from common import dbus_support if dbus_support.supported: import dbus -from common.xmpp.protocol import NS_COMMANDS, NS_FILE, NS_MUC +from common.xmpp.protocol import NS_FILE from common.pep import MOODS, ACTIVITIES #(icon, name, type, jid, account, editable, second pixbuf) @@ -5239,7 +5240,7 @@ class RosterWindow: if muc_icon: invite_menuitem.set_image(muc_icon) - self.build_invite_submenu(invite_menuitem, list_online) + gui_menu_builder.build_invite_submenu(invite_menuitem, list_online) menu.append(invite_menuitem) # Send Custom Status @@ -5346,373 +5347,11 @@ class RosterWindow: jid = model[titer][C_JID].decode('utf-8') tree_path = model.get_path(titer) account = model[titer][C_ACCOUNT].decode('utf-8') - our_jid = jid == gajim.get_jid_from_account(account) contact = gajim.contacts.get_contact_with_highest_priority(account, jid) - if not contact: - return - - # Zeroconf Account - if gajim.config.get_per('accounts', account, 'is_zeroconf'): - xml = gtkgui_helpers.get_glade('zeroconf_contact_context_menu.glade') - zeroconf_contact_context_menu = xml.get_widget( - 'zeroconf_contact_context_menu') - - start_chat_menuitem = xml.get_widget('start_chat_menuitem') - execute_command_menuitem = xml.get_widget('execute_command_menuitem') - rename_menuitem = xml.get_widget('rename_menuitem') - edit_groups_menuitem = xml.get_widget('edit_groups_menuitem') - send_file_menuitem = xml.get_widget('send_file_menuitem') - assign_openpgp_key_menuitem = xml.get_widget( - 'assign_openpgp_key_menuitem') - add_special_notification_menuitem = xml.get_widget( - 'add_special_notification_menuitem') - - # add a special img for send file menuitem - path_to_upload_img = os.path.join(gajim.DATA_DIR, 'pixmaps', - 'upload.png') - img = gtk.Image() - img.set_from_file(path_to_upload_img) - send_file_menuitem.set_image(img) - - if not our_jid: - # add a special img for rename menuitem - path_to_kbd_input_img = os.path.join(gajim.DATA_DIR, 'pixmaps', - 'kbd_input.png') - img = gtk.Image() - img.set_from_file(path_to_kbd_input_img) - rename_menuitem.set_image(img) - - above_information_separator = xml.get_widget( - 'above_information_separator') - - information_menuitem = xml.get_widget('information_menuitem') - history_menuitem = xml.get_widget('history_menuitem') - - contacts = gajim.contacts.get_contacts(account, jid) - if len(contacts) > 1: # several resources - sub_menu = gtk.Menu() - start_chat_menuitem.set_submenu(sub_menu) - - iconset = gajim.config.get('iconset') - path = os.path.join(helpers.get_iconset_path(iconset), '16x16') - for c in contacts: - # icon MUST be different instance for every item - state_images = gtkgui_helpers.load_iconset(path) - item = gtk.ImageMenuItem('%s (%s)' % (c.resource, - str(c.priority))) - icon_name = helpers.get_icon_name_to_show(c, account) - icon = state_images[icon_name] - item.set_image(icon) - sub_menu.append(item) - item.connect('activate', gajim.interface.on_open_chat_window, \ - c, account, c.resource) - - else: # one resource - start_chat_menuitem.connect('activate', - self.on_roster_treeview_row_activated, tree_path) - - if contact.supports(NS_FILE): - send_file_menuitem.set_sensitive(True) - send_file_menuitem.connect('activate', - self.on_send_file_menuitem_activate, contact, account) - else: - send_file_menuitem.set_sensitive(False) - - execute_command_menuitem.connect('activate', - self.on_execute_command, contact, account) - - rename_menuitem.connect('activate', self.on_rename, 'contact', jid, - account) - if contact.show in ('offline', 'error'): - information_menuitem.set_sensitive(False) - send_file_menuitem.set_sensitive(False) - else: - information_menuitem.connect('activate', self.on_info_zeroconf, - contact, account) - history_menuitem.connect('activate', self.on_history, contact, - account) - - if _('Not in Roster') not in contact.get_shown_groups(): - # contact is in normal group - edit_groups_menuitem.set_no_show_all(False) - assign_openpgp_key_menuitem.set_no_show_all(False) - edit_groups_menuitem.connect('activate', self.on_edit_groups, [( - contact,account)]) - - if gajim.connections[account].gpg: - assign_openpgp_key_menuitem.connect('activate', - self.on_assign_pgp_key, contact, account) - else: - assign_openpgp_key_menuitem.set_sensitive(False) - - else: # contact is in group 'Not in Roster' - edit_groups_menuitem.set_sensitive(False) - edit_groups_menuitem.set_no_show_all(True) - assign_openpgp_key_menuitem.set_sensitive(False) - - # Remove many items when it's self contact row - if our_jid: - for menuitem in (rename_menuitem, edit_groups_menuitem, - above_information_separator): - menuitem.set_no_show_all(True) - menuitem.hide() - - # Unsensitive many items when account is offline - if gajim.connections[account].connected < 2: - for widget in (start_chat_menuitem, rename_menuitem, - edit_groups_menuitem, send_file_menuitem): - widget.set_sensitive(False) - - event_button = gtkgui_helpers.get_possible_button_event(event) - - zeroconf_contact_context_menu.attach_to_widget(self.tree, None) - zeroconf_contact_context_menu.connect('selection-done', - gtkgui_helpers.destroy_widget) - zeroconf_contact_context_menu.show_all() - zeroconf_contact_context_menu.popup(None, None, None, event_button, - event.time) - return - - # normal account - xml = gtkgui_helpers.get_glade('roster_contact_context_menu.glade') - roster_contact_context_menu = xml.get_widget( - 'roster_contact_context_menu') - - start_chat_menuitem = xml.get_widget('start_chat_menuitem') - send_custom_status_menuitem = xml.get_widget( - 'send_custom_status_menuitem') - send_single_message_menuitem = xml.get_widget( - 'send_single_message_menuitem') - invite_menuitem = xml.get_widget('invite_menuitem') - block_menuitem = xml.get_widget('block_menuitem') - unblock_menuitem = xml.get_widget('unblock_menuitem') - ignore_menuitem = xml.get_widget('ignore_menuitem') - unignore_menuitem = xml.get_widget('unignore_menuitem') - rename_menuitem = xml.get_widget('rename_menuitem') - edit_groups_menuitem = xml.get_widget('edit_groups_menuitem') - send_file_menuitem = xml.get_widget('send_file_menuitem') - assign_openpgp_key_menuitem = xml.get_widget( - 'assign_openpgp_key_menuitem') - set_custom_avatar_menuitem = xml.get_widget('set_custom_avatar_menuitem') - add_special_notification_menuitem = xml.get_widget( - 'add_special_notification_menuitem') - execute_command_menuitem = xml.get_widget( - 'execute_command_menuitem') - - # add a special img for send file menuitem - path_to_upload_img = os.path.join(gajim.DATA_DIR, 'pixmaps', 'upload.png') - img = gtk.Image() - img.set_from_file(path_to_upload_img) - send_file_menuitem.set_image(img) - - # send custom status icon - blocked = False - if helpers.jid_is_blocked(account, jid): - blocked = True - else: - for group in contact.get_shown_groups(): - if helpers.group_is_blocked(account, group): - blocked = True - break - if gajim.get_transport_name_from_jid(jid, use_config_setting=False): - # Transport contact, send custom status unavailable - send_custom_status_menuitem.set_sensitive(False) - elif blocked: - send_custom_status_menuitem.set_image( \ - gtkgui_helpers.load_icon('offline')) - send_custom_status_menuitem.set_sensitive(False) - elif account in gajim.interface.status_sent_to_users and \ - jid in gajim.interface.status_sent_to_users[account]: - send_custom_status_menuitem.set_image( - gtkgui_helpers.load_icon( \ - gajim.interface.status_sent_to_users[account][jid])) - else: - icon = gtk.image_new_from_stock(gtk.STOCK_NETWORK, gtk.ICON_SIZE_MENU) - send_custom_status_menuitem.set_image(icon) - - if not our_jid: - # add a special img for rename menuitem - path_to_kbd_input_img = os.path.join(gajim.DATA_DIR, 'pixmaps', - 'kbd_input.png') - img = gtk.Image() - img.set_from_file(path_to_kbd_input_img) - rename_menuitem.set_image(img) - - muc_icon = gtkgui_helpers.load_icon('muc_active') - if muc_icon: - invite_menuitem.set_image(muc_icon) - - self.build_invite_submenu(invite_menuitem, [(contact, account)]) - - # Subscription submenu - subscription_menuitem = xml.get_widget('subscription_menuitem') - send_auth_menuitem, ask_auth_menuitem, revoke_auth_menuitem =\ - subscription_menuitem.get_submenu().get_children() - add_to_roster_menuitem = xml.get_widget('add_to_roster_menuitem') - remove_from_roster_menuitem = xml.get_widget( - 'remove_from_roster_menuitem') - - information_menuitem = xml.get_widget('information_menuitem') - history_menuitem = xml.get_widget('history_menuitem') - - contacts = gajim.contacts.get_contacts(account, jid) - - # One or several resource, we do the same for send_custom_status - status_menuitems = gtk.Menu() - send_custom_status_menuitem.set_submenu(status_menuitems) - iconset = gajim.config.get('iconset') - path = os.path.join(helpers.get_iconset_path(iconset), '16x16') - for s in ('online', 'chat', 'away', 'xa', 'dnd', 'offline'): - # icon MUST be different instance for every item - state_images = gtkgui_helpers.load_iconset(path) - status_menuitem = gtk.ImageMenuItem(helpers.get_uf_show(s)) - status_menuitem.connect('activate', self.on_send_custom_status, - [(contact, account)], s) - icon = state_images[s] - status_menuitem.set_image(icon) - status_menuitems.append(status_menuitem) - if len(contacts) > 1: # several resources - start_chat_menuitem.set_submenu(self.build_resources_submenu(contacts, - account, gajim.interface.on_open_chat_window)) - send_file_menuitem.set_submenu(self.build_resources_submenu(contacts, - account, self.on_send_file_menuitem_activate, - cap=NS_FILE)) - execute_command_menuitem.set_submenu(self.build_resources_submenu( - contacts, account, self.on_execute_command, - cap=NS_COMMANDS)) - - else: # one resource - start_chat_menuitem.connect('activate', - gajim.interface.on_open_chat_window, contact, account) - if contact.supports(NS_COMMANDS): - execute_command_menuitem.set_sensitive(True) - execute_command_menuitem.connect('activate', self.on_execute_command, - contact, account, contact.resource) - else: - execute_command_menuitem.set_sensitive(False) - - # This does nothing: - # our_jid_other_resource = None - # if our_jid: - # # It's another resource of us, be sure to send invite to her - # our_jid_other_resource = contact.resource - # Else this var is useless but harmless in next connect calls - - if contact.supports(NS_FILE): - send_file_menuitem.set_sensitive(True) - send_file_menuitem.connect('activate', - self.on_send_file_menuitem_activate, contact, account) - else: - send_file_menuitem.set_sensitive(False) - - send_single_message_menuitem.connect('activate', - self.on_send_single_message_menuitem_activate, account, contact) - - rename_menuitem.connect('activate', self.on_rename, 'contact', jid, - account) - remove_from_roster_menuitem.connect('activate', self.on_req_usub, - [(contact, account)]) - information_menuitem.connect('activate', self.on_info, contact, - account) - history_menuitem.connect('activate', self.on_history, contact, - account) - - if _('Not in Roster') not in contact.get_shown_groups(): - # contact is in normal group - add_to_roster_menuitem.hide() - add_to_roster_menuitem.set_no_show_all(True) - edit_groups_menuitem.connect('activate', self.on_edit_groups, [( - contact,account)]) - - if gajim.connections[account].gpg: - assign_openpgp_key_menuitem.connect('activate', - self.on_assign_pgp_key, contact, account) - else: - assign_openpgp_key_menuitem.set_sensitive(False) - - if contact.sub in ('from', 'both'): - send_auth_menuitem.set_sensitive(False) - else: - send_auth_menuitem.connect('activate', self.authorize, jid, account) - if contact.sub in ('to', 'both'): - ask_auth_menuitem.set_sensitive(False) - add_special_notification_menuitem.connect('activate', - self.on_add_special_notification_menuitem_activate, jid) - else: - ask_auth_menuitem.connect('activate', self.req_sub, jid, - _('I would like to add you to my roster'), account, - contact.groups, contact.name) - if contact.sub in ('to', 'none') or gajim.get_transport_name_from_jid( - jid, use_config_setting=False): - revoke_auth_menuitem.set_sensitive(False) - else: - revoke_auth_menuitem.connect('activate', self.revoke_auth, jid, - account) - - else: # contact is in group 'Not in Roster' - add_to_roster_menuitem.set_no_show_all(False) - edit_groups_menuitem.set_sensitive(False) - assign_openpgp_key_menuitem.set_sensitive(False) - subscription_menuitem.set_sensitive(False) - - add_to_roster_menuitem.connect('activate', - self.on_add_to_roster, contact, account) - - set_custom_avatar_menuitem.connect('activate', - self.on_set_custom_avatar_activate, contact, account) - # Hide items when it's self contact row - if our_jid: - menuitem = xml.get_widget('manage_contact') - menuitem.set_sensitive(False) - - # Unsensitive many items when account is offline - if gajim.connections[account].connected < 2: - for widget in (start_chat_menuitem, send_single_message_menuitem, - rename_menuitem, edit_groups_menuitem, send_file_menuitem, - subscription_menuitem, add_to_roster_menuitem, - remove_from_roster_menuitem, execute_command_menuitem, - send_custom_status_menuitem): - widget.set_sensitive(False) - - if gajim.connections[account] and gajim.connections[account].\ - privacy_rules_supported: - if helpers.jid_is_blocked(account, jid): - block_menuitem.set_no_show_all(True) - block_menuitem.hide() - if gajim.get_transport_name_from_jid(jid, use_config_setting=False): - unblock_menuitem.set_no_show_all(True) - unblock_menuitem.hide() - unignore_menuitem.set_no_show_all(False) - unignore_menuitem.connect('activate', self.on_unblock, [(contact, - account)]) - else: - unblock_menuitem.connect('activate', self.on_unblock, [(contact, - account)]) - else: - unblock_menuitem.set_no_show_all(True) - unblock_menuitem.hide() - if gajim.get_transport_name_from_jid(jid, use_config_setting=False): - block_menuitem.set_no_show_all(True) - block_menuitem.hide() - ignore_menuitem.set_no_show_all(False) - ignore_menuitem.connect('activate', self.on_block, [(contact, - account)]) - else: - block_menuitem.connect('activate', self.on_block, [(contact, - account)]) - else: - unblock_menuitem.set_no_show_all(True) - block_menuitem.set_sensitive(False) - unblock_menuitem.hide() - + menu = gui_menu_builder.get_contact_menu(contact, account) event_button = gtkgui_helpers.get_possible_button_event(event) - - roster_contact_context_menu.attach_to_widget(self.tree, None) - roster_contact_context_menu.connect('selection-done', - gtkgui_helpers.destroy_widget) - roster_contact_context_menu.show_all() - roster_contact_context_menu.popup(None, None, None, event_button, - event.time) + menu.attach_to_widget(self.tree, None) + menu.popup(None, None, None, event_button, event.time) def make_multiple_contact_menu(self, event, iters): '''Make group's popup menu''' @@ -5756,7 +5395,7 @@ class RosterWindow: if muc_icon: invite_item.set_image(muc_icon) - self.build_invite_submenu(invite_item, list_) + gui_menu_builder.build_invite_submenu(invite_item, list_) menu.append(invite_item) item = gtk.SeparatorMenuItem() # separator @@ -6001,119 +5640,6 @@ class RosterWindow: menu.show_all() menu.popup(None, None, None, event_button, event.time) - def build_resources_submenu(self, contacts, account, action, room_jid=None, - room_account=None, cap=None): - ''' Build a submenu with contact's resources. - room_jid and room_account are for action self.on_invite_to_room ''' - sub_menu = gtk.Menu() - - iconset = gajim.config.get('iconset') - if not iconset: - iconset = gajim.config.DEFAULT_ICONSET - path = os.path.join(helpers.get_iconset_path(iconset), '16x16') - for c in contacts: - # icon MUST be different instance for every item - state_images = gtkgui_helpers.load_iconset(path) - item = gtk.ImageMenuItem('%s (%s)' % (c.resource, str(c.priority))) - icon_name = helpers.get_icon_name_to_show(c, account) - icon = state_images[icon_name] - item.set_image(icon) - sub_menu.append(item) - if action == self.on_invite_to_room: - item.connect('activate', action, [(c, account)], - room_jid, room_account, c.resource) - elif action == self.on_invite_to_new_room: - item.connect('activate', action, [(c, account)], c.resource) - else: # start_chat, execute_command, send_file - item.connect('activate', action, c, account, c.resource) - if cap and not c.suppors(cap): - item.set_sensitive(False) - return sub_menu - - def build_invite_submenu(self, invite_menuitem, list_): - '''list_ in a list of (contact, account)''' - # used if we invite only one contact with several resources - contact_list = [] - if len(list_) == 1: - contact, account = list_[0] - contact_list = gajim.contacts.get_contacts(account, contact.jid) - contacts_transport = -1 - connected_accounts = [] - # -1 is at start, False when not from the same, None when jabber - for (contact, account) in list_: - if not account in connected_accounts: - connected_accounts.append(account) - transport = gajim.get_transport_name_from_jid(contact.jid) - if contacts_transport == -1: - contacts_transport = transport - elif contacts_transport != transport: - contacts_transport = False - - if contacts_transport == False: - # they are not all from the same transport - invite_menuitem.set_sensitive(False) - return - invite_to_submenu = gtk.Menu() - invite_menuitem.set_submenu(invite_to_submenu) - invite_to_new_room_menuitem = gtk.ImageMenuItem(_('_New Group Chat')) - icon = gtk.image_new_from_stock(gtk.STOCK_NEW, gtk.ICON_SIZE_MENU) - invite_to_new_room_menuitem.set_image(icon) - if len(contact_list) > 1: # several resources - invite_to_new_room_menuitem.set_submenu(self.build_resources_submenu( - contact_list, account, self.on_invite_to_new_room, cap=NS_MUC)) - elif len(list_) == 1 and contact.supports(NS_MUC): - invite_menuitem.set_sensitive(True) - # use resource if it's self contact - if contact.jid == gajim.get_jid_from_account(account): - resource = contact.resource - else: - resource = None - invite_to_new_room_menuitem.connect('activate', - self.on_invite_to_new_room, list_, resource) - else: - invite_menuitem.set_sensitive(False) - # transform None in 'jabber' - c_t = contacts_transport or 'jabber' - muc_jid = {} - for account in connected_accounts: - for t in gajim.connections[account].muc_jid: - muc_jid[t] = gajim.connections[account].muc_jid[t] - if c_t not in muc_jid: - invite_to_new_room_menuitem.set_sensitive(False) - rooms = [] # a list of (room_jid, account) tuple - invite_to_submenu.append(invite_to_new_room_menuitem) - rooms = [] # a list of (room_jid, account) tuple - minimized_controls = [] - for account in connected_accounts: - minimized_controls += \ - gajim.interface.minimized_controls[account].values() - for gc_control in gajim.interface.msg_win_mgr.get_controls( - message_control.TYPE_GC) + minimized_controls: - acct = gc_control.account - room_jid = gc_control.room_jid - if room_jid in gajim.gc_connected[acct] and \ - gajim.gc_connected[acct][room_jid] and \ - contacts_transport == gajim.get_transport_name_from_jid(room_jid): - rooms.append((room_jid, acct)) - if len(rooms): - item = gtk.SeparatorMenuItem() # separator - invite_to_submenu.append(item) - for (room_jid, account) in rooms: - menuitem = gtk.MenuItem(room_jid.split('@')[0]) - if len(contact_list) > 1: # several resources - menuitem.set_submenu(self.build_resources_submenu( - contact_list, account, self.on_invite_to_room, room_jid, - account)) - else: - # use resource if it's self contact - if contact.jid == gajim.get_jid_from_account(account): - resource = contact.resource - else: - resource = None - menuitem.connect('activate', self.on_invite_to_room, list_, - room_jid, account, resource) - invite_to_submenu.append(menuitem) - def get_and_connect_advanced_menuitem_menu(self, account): '''adds FOR ACCOUNT options''' xml = gtkgui_helpers.get_glade('advanced_menuitem_menu.glade') diff --git a/src/systray.py b/src/systray.py index 72d60b919..e2c09331b 100644 --- a/src/systray.py +++ b/src/systray.py @@ -399,7 +399,7 @@ class Systray: gajim.interface.roster.send_status(acct, show, message) gajim.interface.roster.send_pep(acct, pep_dict) dlg = dialogs.ChangeStatusMessageDialog(on_response, status) - dlg.window.present() + dlg.dialog.present() def show_tooltip(self, widget): position = widget.window.get_origin()