def get_contact_menu(contact, account, use_multiple_contacts=True, show_start_chat=True, show_encryption=False, show_buttonbar_items=True, control=None, gc_contact=None, is_anonymous=True): """ 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 == app.get_jid_from_account(account) roster = app.interface.roster xml = get_builder('contact_context_menu.ui') contact_context_menu = xml.get_object('contact_context_menu') start_chat_menuitem = xml.get_object('start_chat_menuitem') execute_command_menuitem = xml.get_object('execute_command_menuitem') rename_menuitem = xml.get_object('rename_menuitem') edit_groups_menuitem = xml.get_object('edit_groups_menuitem') send_file_menuitem = xml.get_object('send_file_menuitem') information_menuitem = xml.get_object('information_menuitem') history_menuitem = xml.get_object('history_menuitem') send_single_message_menuitem = xml.get_object('send_single_message_menuitem') invite_menuitem = xml.get_object('invite_menuitem') block_menuitem = xml.get_object('block_menuitem') unblock_menuitem = xml.get_object('unblock_menuitem') ignore_menuitem = xml.get_object('ignore_menuitem') unignore_menuitem = xml.get_object('unignore_menuitem') # Subscription submenu subscription_menuitem = xml.get_object('subscription_menuitem') send_auth_menuitem, ask_auth_menuitem, revoke_auth_menuitem = \ subscription_menuitem.get_submenu().get_children() add_to_roster_menuitem = xml.get_object('add_to_roster_menuitem') remove_from_roster_menuitem = xml.get_object( 'remove_from_roster_menuitem') manage_contact_menuitem = xml.get_object('manage_contact') convert_to_gc_menuitem = xml.get_object('convert_to_groupchat_menuitem') last_separator = xml.get_object('last_separator') items_to_hide = [] contacts = app.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, app.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', app.interface.on_open_chat_window, contact, account) if contact.supports(NS_FILE) or contact.supports(NS_JINGLE_FILE_TRANSFER_5): 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) if gc_contact and gc_contact.jid and not is_anonymous: execute_command_menuitem.connect('activate', roster.on_execute_command, gc_contact, account, gc_contact.resource) else: 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.set_action_name('app.browse-history') dict_ = {'jid': GLib.Variant('s', contact.jid), 'account': GLib.Variant('s', account)} variant = GLib.Variant('a{sv}', dict_) history_menuitem.set_action_target_value(variant) if control: convert_to_gc_menuitem.connect('activate', control._on_convert_to_gc_menuitem_activate) else: items_to_hide.append(convert_to_gc_menuitem) if _('Not in contact list') not in contact.get_shown_groups(): # contact is in normal group edit_groups_menuitem.connect('activate', roster.on_edit_groups, [(contact, account)]) else: # contact is in group 'Not in contact list' edit_groups_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 app.account_is_disconnected(account): for widget in (start_chat_menuitem, rename_menuitem, edit_groups_menuitem, send_file_menuitem, convert_to_gc_menuitem, information_menuitem): widget.set_sensitive(False) if not show_start_chat: items_to_hide.append(start_chat_menuitem) 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) # Hide items when it's a pm if gc_contact: items_to_hide += [rename_menuitem, edit_groups_menuitem, subscription_menuitem, remove_from_roster_menuitem] for item in items_to_hide: item.set_no_show_all(True) item.hide() # Zeroconf Account if app.config.get_per('accounts', account, 'is_zeroconf'): for item in (send_single_message_menuitem, invite_menuitem, block_menuitem, unblock_menuitem, ignore_menuitem, unignore_menuitem, subscription_menuitem, manage_contact_menuitem, convert_to_gc_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 if gc_contact: if not gc_contact.jid: # it's a pm and we don't know real JID invite_menuitem.set_sensitive(False) else: bookmarked = False c_ = app.contacts.get_contact(account, gc_contact.jid, gc_contact.resource) if c_ and c_.supports(NS_CONFERENCE): bookmarked = True build_invite_submenu(invite_menuitem, [(gc_contact, account)], show_bookmarked=bookmarked) else: force_resource = False if control and control.resource: force_resource = True build_invite_submenu(invite_menuitem, [(contact, account)], show_bookmarked=contact.supports(NS_CONFERENCE), force_resource=force_resource) if app.account_is_disconnected(account): invite_menuitem.set_sensitive(False) 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 contact list') 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) else: ask_auth_menuitem.connect('activate', roster.req_sub, jid, _('I would like to add you to my contact list'), account, contact.groups, contact.name) transport = app.get_transport_name_from_jid(jid, use_config_setting=False) if contact.sub in ('to', 'none') or transport not in ['jabber', None]: revoke_auth_menuitem.set_sensitive(False) else: revoke_auth_menuitem.connect('activate', roster.revoke_auth, jid, account) elif app.connections[account].roster_supported: # contact is in group 'Not in contact list' 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) else: add_to_roster_menuitem.hide() add_to_roster_menuitem.set_no_show_all(True) subscription_menuitem.set_sensitive(False) # Hide items when it's self contact row if our_jid: manage_contact_menuitem.set_sensitive(False) # Unsensitive items when account is offline if app.account_is_disconnected(account): for widget in (send_single_message_menuitem, subscription_menuitem, add_to_roster_menuitem, remove_from_roster_menuitem, execute_command_menuitem): widget.set_sensitive(False) con = app.connections[account] if con and (con.get_module('PrivacyLists').supported or con.get_module('Blocking').supported): transport = app.get_transport_name_from_jid(jid, use_config_setting=False) if helpers.jid_is_blocked(account, jid): block_menuitem.set_no_show_all(True) block_menuitem.hide() if transport != 'jabber': 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 transport != 'jabber': 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
def get_transport_menu(contact, account): roster = app.interface.roster jid = contact.jid menu = Gtk.Menu() # Send single message item = Gtk.MenuItem.new_with_mnemonic(_('Send Single _Message…')) item.connect('activate', roster.on_send_single_message_menuitem_activate, account, contact) menu.append(item) if app.account_is_disconnected(account): item.set_sensitive(False) blocked = False if helpers.jid_is_blocked(account, jid): blocked = True item = Gtk.SeparatorMenuItem.new() # separator menu.append(item) # Execute Command item = Gtk.MenuItem.new_with_mnemonic(_('E_xecute Command…')) menu.append(item) item.connect('activate', roster.on_execute_command, contact, account, contact.resource) if app.account_is_disconnected(account): item.set_sensitive(False) # Manage Transport submenu item = Gtk.MenuItem.new_with_mnemonic(_('_Manage Transport')) manage_transport_submenu = Gtk.Menu() item.set_submenu(manage_transport_submenu) menu.append(item) # Modify Transport item = Gtk.MenuItem.new_with_mnemonic(_('_Modify Transport')) manage_transport_submenu.append(item) item.connect('activate', roster.on_edit_agent, contact, account) if app.account_is_disconnected(account): item.set_sensitive(False) # Rename item = Gtk.MenuItem.new_with_mnemonic(_('_Rename…')) manage_transport_submenu.append(item) item.connect('activate', roster.on_rename, 'agent', jid, account) if app.account_is_disconnected(account): item.set_sensitive(False) item = Gtk.SeparatorMenuItem.new() # separator manage_transport_submenu.append(item) # Block if blocked: item = Gtk.MenuItem.new_with_mnemonic(_('_Unblock')) item.connect('activate', roster.on_unblock, [(contact, account)]) else: item = Gtk.MenuItem.new_with_mnemonic(_('_Block')) item.connect('activate', roster.on_block, [(contact, account)]) manage_transport_submenu.append(item) if app.account_is_disconnected(account): item.set_sensitive(False) # Remove item = Gtk.MenuItem.new_with_mnemonic(_('Remo_ve')) manage_transport_submenu.append(item) item.connect('activate', roster.on_remove_agent, [(contact, account)]) if app.account_is_disconnected(account): item.set_sensitive(False) item = Gtk.SeparatorMenuItem.new() # separator menu.append(item) # Information information_menuitem = Gtk.MenuItem.new_with_mnemonic(_('_Information')) menu.append(information_menuitem) information_menuitem.connect('activate', roster.on_info, contact, account) if app.account_is_disconnected(account): information_menuitem.set_sensitive(False) menu.connect('selection-done', gtkgui_helpers.destroy_widget) menu.show_all() return menu
def get_contact_menu(contact, account, use_multiple_contacts=True, show_start_chat=True, show_encryption=False, show_buttonbar_items=True, control=None, gc_contact=None, is_anonymous=True): """ 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 == app.get_jid_from_account(account) roster = app.interface.roster xml = gtkgui_helpers.get_gtk_builder('contact_context_menu.ui') contact_context_menu = xml.get_object('contact_context_menu') start_chat_menuitem = xml.get_object('start_chat_menuitem') execute_command_menuitem = xml.get_object('execute_command_menuitem') rename_menuitem = xml.get_object('rename_menuitem') edit_groups_menuitem = xml.get_object('edit_groups_menuitem') send_file_menuitem = xml.get_object('send_file_menuitem') assign_openpgp_key_menuitem = xml.get_object('assign_openpgp_key_menuitem') add_special_notification_menuitem = xml.get_object( 'add_special_notification_menuitem') information_menuitem = xml.get_object('information_menuitem') history_menuitem = xml.get_object('history_menuitem') send_custom_status_menuitem = xml.get_object('send_custom_status_menuitem') send_single_message_menuitem = xml.get_object( 'send_single_message_menuitem') invite_menuitem = xml.get_object('invite_menuitem') block_menuitem = xml.get_object('block_menuitem') unblock_menuitem = xml.get_object('unblock_menuitem') ignore_menuitem = xml.get_object('ignore_menuitem') unignore_menuitem = xml.get_object('unignore_menuitem') # Subscription submenu subscription_menuitem = xml.get_object('subscription_menuitem') send_auth_menuitem, ask_auth_menuitem, revoke_auth_menuitem = \ subscription_menuitem.get_submenu().get_children() add_to_roster_menuitem = xml.get_object('add_to_roster_menuitem') remove_from_roster_menuitem = xml.get_object('remove_from_roster_menuitem') manage_contact_menuitem = xml.get_object('manage_contact') convert_to_gc_menuitem = xml.get_object('convert_to_groupchat_menuitem') last_separator = xml.get_object('last_separator') items_to_hide = [] contacts = app.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, app.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', app.interface.on_open_chat_window, contact, account) if contact.supports(NS_FILE) or contact.supports( NS_JINGLE_FILE_TRANSFER_5): 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) if gc_contact and gc_contact.jid and not is_anonymous: execute_command_menuitem.connect('activate', roster.on_execute_command, gc_contact, account, gc_contact.resource) else: 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 control: convert_to_gc_menuitem.connect( 'activate', control._on_convert_to_gc_menuitem_activate) else: items_to_hide.append(convert_to_gc_menuitem) 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 app.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 app.account_is_disconnected(account): for widget in (start_chat_menuitem, rename_menuitem, edit_groups_menuitem, send_file_menuitem, convert_to_gc_menuitem, information_menuitem): widget.set_sensitive(False) if not show_start_chat: items_to_hide.append(start_chat_menuitem) 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) # Hide items when it's a pm if gc_contact: items_to_hide += [ rename_menuitem, edit_groups_menuitem, subscription_menuitem, remove_from_roster_menuitem ] for item in items_to_hide: item.set_no_show_all(True) item.hide() # Zeroconf Account if app.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, subscription_menuitem, manage_contact_menuitem, convert_to_gc_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 transport = app.get_transport_name_from_jid(jid, use_config_setting=False) if transport and transport != 'jabber': # Transport contact, send custom status unavailable send_custom_status_menuitem.set_sensitive(False) elif blocked: send_custom_status_menuitem.set_sensitive(False) if gc_contact: if not gc_contact.jid: # it's a pm and we don't know real JID invite_menuitem.set_sensitive(False) else: bookmarked = False c_ = app.contacts.get_contact(account, gc_contact.jid, gc_contact.resource) if c_ and c_.supports(NS_CONFERENCE): bookmarked = True build_invite_submenu(invite_menuitem, [(gc_contact, account)], show_bookmarked=bookmarked) else: force_resource = False if control and control.resource: force_resource = True build_invite_submenu(invite_menuitem, [(contact, account)], show_bookmarked=contact.supports(NS_CONFERENCE), force_resource=force_resource) if app.account_is_disconnected(account): invite_menuitem.set_sensitive(False) # One or several resource, we do the same for send_custom_status status_menuitems = Gtk.Menu() send_custom_status_menuitem.set_submenu(status_menuitems) for s in ('online', 'chat', 'away', 'xa', 'dnd', 'offline'): # icon MUST be different instance for every item status_menuitem = Gtk.MenuItem.new_with_label(helpers.get_uf_show(s)) status_menuitem.connect('activate', roster.on_send_custom_status, [(contact, account)], s) 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) transport = app.get_transport_name_from_jid(jid, use_config_setting=False) if contact.sub in ('to', 'none') or transport not in ['jabber', None]: revoke_auth_menuitem.set_sensitive(False) else: revoke_auth_menuitem.connect('activate', roster.revoke_auth, jid, account) elif app.connections[account].roster_supported: # 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) else: add_to_roster_menuitem.hide() add_to_roster_menuitem.set_no_show_all(True) subscription_menuitem.set_sensitive(False) # Hide items when it's self contact row if our_jid: manage_contact_menuitem.set_sensitive(False) # Unsensitive items when account is offline if app.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 app.connections[account] and (app.connections[account].\ privacy_rules_supported or app.connections[account].blocking_supported): if helpers.jid_is_blocked(account, jid): block_menuitem.set_no_show_all(True) block_menuitem.hide() if app.get_transport_name_from_jid(jid, use_config_setting=False)\ and transport != 'jabber': 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 app.get_transport_name_from_jid(jid, use_config_setting=False)\ and transport != 'jabber': 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