Esempio n. 1
0
def make_jabber_state_images():
    """
    Initialize jabber_state_images dictionary
    """
    iconset = gajim.config.get('iconset')
    if iconset:
        if helpers.get_iconset_path(iconset):
            path = os.path.join(helpers.get_iconset_path(iconset), '16x16')
            if not os.path.exists(path):
                iconset = gajim.config.DEFAULT_ICONSET
                gajim.config.set('iconset', iconset)
        else:
            iconset = gajim.config.DEFAULT_ICONSET
            gajim.config.set('iconset', iconset)
    else:
        iconset = gajim.config.DEFAULT_ICONSET
        gajim.config.set('iconset', iconset)

    path = os.path.join(helpers.get_iconset_path(iconset), '16x16')
    gajim.interface.jabber_state_images['16'] = load_iconset(path)

    pixo, pixc = load_icons_meta()
    gajim.interface.jabber_state_images['opened'] = load_iconset(path, pixo)
    gajim.interface.jabber_state_images['closed'] = load_iconset(path, pixc)

    path = os.path.join(helpers.get_iconset_path(iconset), '32x32')
    gajim.interface.jabber_state_images['32'] = load_iconset(path)

    path = os.path.join(helpers.get_iconset_path(iconset), '24x24')
    if (os.path.exists(path)):
        gajim.interface.jabber_state_images['24'] = load_iconset(path)
    else:
        # Resize 32x32 icons to 24x24
        for each in gajim.interface.jabber_state_images['32']:
            img = Gtk.Image()
            pix = gajim.interface.jabber_state_images['32'][each]
            pix_type = pix.get_storage_type()
            if pix_type == Gtk.ImageType.ANIMATION:
                animation = pix.get_animation()
                pixbuf = animation.get_static_image()
            elif pix_type == Gtk.ImageType.EMPTY:
                pix = gajim.interface.jabber_state_images['16'][each]
                pix_16_type = pix.get_storage_type()
                if pix_16_type == Gtk.ImageType.ANIMATION:
                    animation = pix.get_animation()
                    pixbuf = animation.get_static_image()
                else:
                    pixbuf = pix.get_pixbuf()
            else:
                pixbuf = pix.get_pixbuf()
            scaled_pix = pixbuf.scale_simple(24, 24,
                                             GdkPixbuf.InterpType.BILINEAR)
            img.set_from_pixbuf(scaled_pix)
            gajim.interface.jabber_state_images['24'][each] = img
Esempio n. 2
0
def make_jabber_state_images():
    """
    Initialize jabber_state_images dictionary
    """
    iconset = gajim.config.get('iconset')
    if iconset:
        if helpers.get_iconset_path(iconset):
            path = os.path.join(helpers.get_iconset_path(iconset), '16x16')
            if not os.path.exists(path):
                iconset = gajim.config.DEFAULT_ICONSET
                gajim.config.set('iconset', iconset)
        else:
            iconset = gajim.config.DEFAULT_ICONSET
            gajim.config.set('iconset', iconset)
    else:
        iconset = gajim.config.DEFAULT_ICONSET
        gajim.config.set('iconset', iconset)

    path = os.path.join(helpers.get_iconset_path(iconset), '16x16')
    gajim.interface.jabber_state_images['16'] = load_iconset(path)

    pixo, pixc = load_icons_meta()
    gajim.interface.jabber_state_images['opened'] = load_iconset(path, pixo)
    gajim.interface.jabber_state_images['closed'] = load_iconset(path, pixc)

    path = os.path.join(helpers.get_iconset_path(iconset), '32x32')
    gajim.interface.jabber_state_images['32'] = load_iconset(path)

    path = os.path.join(helpers.get_iconset_path(iconset), '24x24')
    if (os.path.exists(path)):
        gajim.interface.jabber_state_images['24'] = load_iconset(path)
    else:
        # Resize 32x32 icons to 24x24
        for each in gajim.interface.jabber_state_images['32']:
            img = Gtk.Image()
            pix = gajim.interface.jabber_state_images['32'][each]
            pix_type = pix.get_storage_type()
            if pix_type == Gtk.ImageType.ANIMATION:
                animation = pix.get_animation()
                pixbuf = animation.get_static_image()
            elif pix_type == Gtk.ImageType.EMPTY:
                pix = gajim.interface.jabber_state_images['16'][each]
                pix_16_type = pix.get_storage_type()
                if pix_16_type == Gtk.ImageType.ANIMATION:
                    animation = pix.get_animation()
                    pixbuf = animation.get_static_image()
                else:
                    pixbuf = pix.get_pixbuf()
            else:
                pixbuf = pix.get_pixbuf()
            scaled_pix = pixbuf.scale_simple(24, 24, GdkPixbuf.InterpType.BILINEAR)
            img.set_from_pixbuf(scaled_pix)
            gajim.interface.jabber_state_images['24'][each] = img
Esempio n. 3
0
	def fill_table_with_accounts(self, accounts):
		iconset = gajim.config.get('iconset')
		if not iconset:
			iconset = 'dcraven'
		file_path = os.path.join(helpers.get_iconset_path(iconset), '16x16')
		for acct in accounts:
			message = acct['message']
			# before reducing the chars we should assure we send unicode, else 
			# there are possible pango TBs on 'set_markup'
			if isinstance(message, str):
				message = unicode(message, encoding = 'utf-8')
			message = helpers.reduce_chars_newlines(message, 100, 1)
			message = gobject.markup_escape_text(message)
			if acct['name'] in gajim.con_types and \
				gajim.con_types[acct['name']] in ('tls', 'ssl'):
				show_lock = True
			else:
				show_lock = False
			if message:
				self.add_status_row(file_path, acct['show'], 
					gobject.markup_escape_text(acct['name']) + \
					' - ' + message, show_lock=show_lock, indent=False)
			else:
				self.add_status_row(file_path, acct['show'], 
					gobject.markup_escape_text(acct['name']) 
					, show_lock=show_lock, indent=False)
			for line in acct['event_lines']:
				self.add_text_row('  ' + line, 1)
Esempio n. 4
0
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
    """
    roster = gajim.interface.roster
    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:
        item = Gtk.MenuItem.new_with_label('%s (%s)' %
                                           (c.resource, str(c.priority)))
        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
Esempio n. 5
0
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
    """
    roster = gajim.interface.roster
    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
Esempio n. 6
0
 def fill_table_with_accounts(self, accounts):
     iconset = gajim.config.get('iconset')
     if not iconset:
         iconset = 'dcraven'
     file_path = os.path.join(helpers.get_iconset_path(iconset), '16x16')
     for acct in accounts:
         message = acct['message']
         # before reducing the chars we should assure we send unicode, else
         # there are possible pango TBs on 'set_markup'
         if isinstance(message, str):
             message = unicode(message, encoding='utf-8')
         message = helpers.reduce_chars_newlines(message, 100, 1)
         message = gobject.markup_escape_text(message)
         if acct['name'] in gajim.con_types and \
          gajim.con_types[acct['name']] in ('tls', 'ssl'):
             show_lock = True
         else:
             show_lock = False
         if message:
             self.add_status_row(file_path, acct['show'],
              gobject.markup_escape_text(acct['name']) + \
              ' - ' + message, show_lock=show_lock, indent=False)
         else:
             self.add_status_row(file_path,
                                 acct['show'],
                                 gobject.markup_escape_text(acct['name']),
                                 show_lock=show_lock,
                                 indent=False)
         for line in acct['event_lines']:
             self.add_text_row('  ' + line, 1)
Esempio n. 7
0
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
    """
    roster = gajim.interface.roster
    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:
        item = Gtk.MenuItem.new_with_label(
            '%s (%s)' % (c.resource, str(c.priority)))
        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
Esempio n. 8
0
def load_icon(icon_name):
    """
    Load an icon from the iconset in 16x16
    """
    iconset = gajim.config.get('iconset')
    path = os.path.join(helpers.get_iconset_path(iconset), '16x16', '')
    icon_list = _load_icon_list([icon_name], path)
    return icon_list[icon_name]
Esempio n. 9
0
def load_icon(icon_name):
    """
    Load an icon from the iconset in 16x16
    """
    iconset = gajim.config.get('iconset')
    path = os.path.join(helpers.get_iconset_path(iconset), '16x16', '')
    icon_list = _load_icon_list([icon_name], path)
    return icon_list[icon_name]
Esempio n. 10
0
def make_jabber_state_images():
    '''initialise jabber_state_images dict'''
    iconset = gajim.config.get('iconset')
    if iconset:
        path = os.path.join(helpers.get_iconset_path(iconset), '16x16')
        if not os.path.exists(path):
            iconset = gajim.config.DEFAULT_ICONSET
    else:
        iconset = gajim.config.DEFAULT_ICONSET

    path = os.path.join(helpers.get_iconset_path(iconset), '32x32')
    gajim.interface.jabber_state_images['32'] = load_iconset(path)

    path = os.path.join(helpers.get_iconset_path(iconset), '16x16')
    gajim.interface.jabber_state_images['16'] = load_iconset(path)

    pixo, pixc = load_icons_meta()
    gajim.interface.jabber_state_images['opened'] = load_iconset(path, pixo)
    gajim.interface.jabber_state_images['closed'] = load_iconset(path, pixc)
Esempio n. 11
0
def make_jabber_state_images():
	'''initialise jabber_state_images dict'''
	iconset = gajim.config.get('iconset')
	if iconset:
		path = os.path.join(helpers.get_iconset_path(iconset), '16x16')
		if not os.path.exists(path):
			iconset = gajim.config.DEFAULT_ICONSET
	else:
		iconset = gajim.config.DEFAULT_ICONSET

	path = os.path.join(helpers.get_iconset_path(iconset), '32x32')
	gajim.interface.jabber_state_images['32'] = load_iconset(path)

	path = os.path.join(helpers.get_iconset_path(iconset), '16x16')
	gajim.interface.jabber_state_images['16'] = load_iconset(path)

	pixo, pixc = load_icons_meta()
	gajim.interface.jabber_state_images['opened'] = load_iconset(path, pixo)
	gajim.interface.jabber_state_images['closed'] = load_iconset(path, pixc)
Esempio n. 12
0
def load_icons_meta():
    '''load and return  - AND + small icons to put on top left of an icon
	for meta contacts.'''
    iconset = gajim.config.get('iconset')
    path = os.path.join(helpers.get_iconset_path(iconset), '16x16')
    # try to find opened_meta.png file, else opened.png else nopixbuf merge
    path_opened = os.path.join(path, 'opened_meta.png')
    if not os.path.isfile(path_opened):
        path_opened = os.path.join(path, 'opened.png')
    if os.path.isfile(path_opened):
        pixo = gtk.gdk.pixbuf_new_from_file(path_opened)
    else:
        pixo = None
    # Same thing for closed
    path_closed = os.path.join(path, 'opened_meta.png')
    if not os.path.isfile(path_closed):
        path_closed = os.path.join(path, 'closed.png')
    if os.path.isfile(path_closed):
        pixc = gtk.gdk.pixbuf_new_from_file(path_closed)
    else:
        pixc = None
    return pixo, pixc
Esempio n. 13
0
def load_icons_meta():
	'''load and return  - AND + small icons to put on top left of an icon
	for meta contacts.'''
	iconset = gajim.config.get('iconset')
	path = os.path.join(helpers.get_iconset_path(iconset), '16x16')
	# try to find opened_meta.png file, else opened.png else nopixbuf merge
	path_opened = os.path.join(path, 'opened_meta.png')
	if not os.path.isfile(path_opened):
		path_opened = os.path.join(path, 'opened.png')
	if os.path.isfile(path_opened):
		pixo = gtk.gdk.pixbuf_new_from_file(path_opened)
	else:
		pixo = None
	# Same thing for closed
	path_closed = os.path.join(path, 'opened_meta.png')
	if not os.path.isfile(path_closed):
		path_closed = os.path.join(path, 'closed.png')
	if os.path.isfile(path_closed):
		pixc = gtk.gdk.pixbuf_new_from_file(path_closed)
	else:
		pixc = None
	return pixo, pixc
Esempio n. 14
0
 def fill_table_with_accounts(self, accounts):
     iconset = gajim.config.get('iconset')
     if not iconset:
         iconset = 'dcraven'
     file_path = os.path.join(helpers.get_iconset_path(iconset), '16x16')
     for acct in accounts:
         message = acct['message']
         message = helpers.reduce_chars_newlines(message, 100, 1)
         message = GLib.markup_escape_text(message)
         if acct['name'] in gajim.con_types and \
                 gajim.con_types[acct['name']] in ('tls', 'ssl'):
             show_lock = True
         else:
             show_lock = False
         if message:
             self.add_status_row(file_path, acct['show'],
                 GLib.markup_escape_text(acct['name']) + ' - ' + message,
                 show_lock=show_lock, indent=False)
         else:
             self.add_status_row(file_path, acct['show'],
                 GLib.markup_escape_text(acct['name']), show_lock=show_lock,
                 indent=False)
         for line in acct['event_lines']:
             self.add_text_row('  ' + line, 1)
Esempio n. 15
0
 def fill_table_with_accounts(self, accounts):
     iconset = gajim.config.get('iconset')
     if not iconset:
         iconset = 'dcraven'
     file_path = os.path.join(helpers.get_iconset_path(iconset), '16x16')
     for acct in accounts:
         message = acct['message']
         message = helpers.reduce_chars_newlines(message, 100, 1)
         message = GLib.markup_escape_text(message)
         if acct['name'] in gajim.con_types and \
                 gajim.con_types[acct['name']] in ('tls', 'ssl'):
             show_lock = True
         else:
             show_lock = False
         if message:
             self.add_status_row(file_path, acct['show'],
                 GLib.markup_escape_text(acct['name']) + ' - ' + message,
                 show_lock=show_lock, indent=False)
         else:
             self.add_status_row(file_path, acct['show'],
                 GLib.markup_escape_text(acct['name']), show_lock=show_lock,
                 indent=False)
         for line in acct['event_lines']:
             self.add_text_row('  ' + line, 1)
Esempio n. 16
0
    def populate(self, contacts):
        self.create_window()

        self.create_table()
        if not contacts or len(contacts) == 0:
            # Tooltip for merged accounts row
            accounts = helpers.get_notification_icon_tooltip_dict()
            self.table.resize(2, 1)
            self.spacer_label = ''
            self.fill_table_with_accounts(accounts)
            self.win.add(self.table)
            return

        # primary contact
        prim_contact = gajim.contacts.get_highest_prio_contact_from_contacts(
            contacts)

        puny_jid = helpers.sanitize_filename(prim_contact.jid)
        table_size = 3

        file = helpers.get_avatar_path(
            os.path.join(gajim.AVATAR_PATH, puny_jid))
        if file:
            self.avatar_image.set_from_file(file)
            pix = self.avatar_image.get_pixbuf()
            pix = gtkgui_helpers.get_scaled_pixbuf(pix, 'tooltip')
            self.avatar_image.set_from_pixbuf(pix)
            table_size = 4
        else:
            self.avatar_image.set_from_pixbuf(None)
        vcard_table = gtk.Table(table_size, 1)
        vcard_table.set_property('column-spacing', 2)
        vcard_table.set_homogeneous(False)
        vcard_current_row = 1
        properties = []

        name_markup = u'<span weight="bold">' + \
         gobject.markup_escape_text(prim_contact.get_shown_name())\
         + '</span>'
        if self.account and prim_contact.jid in gajim.connections[
                self.account].blocked_contacts:
            name_markup += _(' [blocked]')
        if self.account and \
        self.account in gajim.interface.minimized_controls and \
        prim_contact.jid in gajim.interface.minimized_controls[self.account]:
            name_markup += _(' [minimized]')
        properties.append((name_markup, None))

        num_resources = 0
        # put contacts in dict, where key is priority
        contacts_dict = {}
        for contact in contacts:
            if contact.resource:
                num_resources += 1
                if contact.priority in contacts_dict:
                    contacts_dict[contact.priority].append(contact)
                else:
                    contacts_dict[contact.priority] = [contact]

        if num_resources > 1:
            properties.append((_('Status: '), ' '))
            transport = gajim.get_transport_name_from_jid(prim_contact.jid)
            if transport:
                file_path = os.path.join(helpers.get_transport_path(transport),
                                         '16x16')
            else:
                iconset = gajim.config.get('iconset')
                if not iconset:
                    iconset = 'dcraven'
                file_path = os.path.join(helpers.get_iconset_path(iconset),
                                         '16x16')

            contact_keys = sorted(contacts_dict.keys())
            contact_keys.reverse()
            for priority in contact_keys:
                for contact in contacts_dict[priority]:
                    status_line = self.get_status_info(contact.resource,
                                                       contact.priority,
                                                       contact.show,
                                                       contact.status)

                    icon_name = self._get_icon_name_for_tooltip(contact)
                    self.add_status_row(file_path, icon_name, status_line,
                                        contact.last_status_time)
            properties.append((self.table, None))

        else:  # only one resource
            if contact.show:
                show = helpers.get_uf_show(contact.show)
                if contact.last_status_time:
                    vcard_current_row += 1
                    if contact.show == 'offline':
                        text = ' - ' + _('Last status: %s')
                    else:
                        text = _(' since %s')

                    if time.strftime('%j', time.localtime())== \
                      time.strftime('%j', contact.last_status_time):
                        # it's today, show only the locale hour representation
                        local_time = time.strftime('%X',
                                                   contact.last_status_time)
                    else:
                        # time.strftime returns locale encoded string
                        local_time = time.strftime('%c',
                                                   contact.last_status_time)
                    local_time = local_time.decode(
                        locale.getpreferredencoding())
                    text = text % local_time
                    show += text
                if self.account and \
                prim_contact.jid in gajim.gc_connected[self.account]:
                    if gajim.gc_connected[self.account][prim_contact.jid]:
                        show = _('Connected')
                    else:
                        show = _('Disconnected')
                show = '<i>' + show + '</i>'
                # we append show below

                if contact.status:
                    status = contact.status.strip()
                    if status:
                        # reduce long status
                        # (no more than 300 chars on line and no more than 5 lines)
                        # status is wrapped
                        status = helpers.reduce_chars_newlines(status, 300, 5)
                        # escape markup entities.
                        status = gobject.markup_escape_text(status)
                        properties.append(('<i>%s</i>' % status, None))
                properties.append((show, None))

        self._append_pep_info(contact, properties)

        properties.append((_('Jabber ID: '), prim_contact.jid))

        # contact has only one ressource
        if num_resources == 1 and contact.resource:
            properties.append((_('Resource: '),
             gobject.markup_escape_text(contact.resource) +\
             ' (' + unicode(contact.priority) + ')'))

        if self.account and prim_contact.sub and prim_contact.sub != 'both' and\
        prim_contact.jid not in gajim.gc_connected[self.account]:
            # ('both' is the normal sub so we don't show it)
            properties.append((_('Subscription: '),
                               gobject.markup_escape_text(
                                   helpers.get_uf_sub(prim_contact.sub))))

        if prim_contact.keyID:
            keyID = None
            if len(prim_contact.keyID) == 8:
                keyID = prim_contact.keyID
            elif len(prim_contact.keyID) == 16:
                keyID = prim_contact.keyID[8:]
            if keyID:
                properties.append(
                    (_('OpenPGP: '), gobject.markup_escape_text(keyID)))

        while properties:
            property = properties.pop(0)
            vcard_current_row += 1
            vertical_fill = gtk.FILL
            if not properties and table_size == 4:
                vertical_fill |= gtk.EXPAND
            label = gtk.Label()
            label.set_alignment(0, 0)
            if property[1]:
                label.set_markup(property[0])
                vcard_table.attach(label, 1, 2, vcard_current_row,
                                   vcard_current_row + 1, gtk.FILL,
                                   vertical_fill, 0, 0)
                label = gtk.Label()
                label.set_alignment(0, 0)
                label.set_markup(property[1])
                label.set_line_wrap(True)
                vcard_table.attach(label, 2, 3, vcard_current_row,
                                   vcard_current_row + 1,
                                   gtk.EXPAND | gtk.FILL, vertical_fill, 0, 0)
            else:
                if isinstance(property[0],
                              (unicode, str)):  #FIXME: rm unicode?
                    label.set_markup(property[0])
                    label.set_line_wrap(True)
                else:
                    label = property[0]
                vcard_table.attach(label, 1, 3, vcard_current_row,
                                   vcard_current_row + 1, gtk.FILL,
                                   vertical_fill, 0)
        self.avatar_image.set_alignment(0, 0)
        if table_size == 4:
            vcard_table.attach(self.avatar_image, 3, 4, 2,
                               vcard_current_row + 1, gtk.FILL,
                               gtk.FILL | gtk.EXPAND, 3, 3)
        self.win.add(vcard_table)
Esempio n. 17
0
def get_transport_menu(contact, account):
    roster = gajim.interface.roster
    jid = contact.jid

    menu = gtk.Menu()

    # Send single message
    item = gtk.ImageMenuItem(_('Send Single _Message...'))
    icon = gtk.image_new_from_stock(gtk.STOCK_NEW, gtk.ICON_SIZE_MENU)
    item.set_image(icon)
    item.connect('activate', roster.on_send_single_message_menuitem_activate,
        account, contact)
    menu.append(item)
    if gajim.account_is_disconnected(account):
        item.set_sensitive(False)

    blocked = False
    if helpers.jid_is_blocked(account, jid):
        blocked = True

    # Send Custom Status
    send_custom_status_menuitem = gtk.ImageMenuItem(_('Send Cus_tom Status'))
    # add a special img for this menuitem
    if blocked:
        send_custom_status_menuitem.set_image(gtkgui_helpers.load_icon(
            'offline'))
        send_custom_status_menuitem.set_sensitive(False)
    else:
        if 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)
        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)
    menu.append(send_custom_status_menuitem)
    if gajim.account_is_disconnected(account):
        send_custom_status_menuitem.set_sensitive(False)

    item = gtk.SeparatorMenuItem() # separator
    menu.append(item)

    # Execute Command
    item = gtk.ImageMenuItem(_('E_xecute Command...'))
    icon = gtk.image_new_from_stock(gtk.STOCK_EXECUTE, gtk.ICON_SIZE_MENU)
    item.set_image(icon)
    menu.append(item)
    item.connect('activate', roster.on_execute_command, contact, account,
        contact.resource)
    if gajim.account_is_disconnected(account):
        item.set_sensitive(False)

    # Manage Transport submenu
    item = gtk.ImageMenuItem(_('_Manage Transport'))
    icon = gtk.image_new_from_stock(gtk.STOCK_PROPERTIES, gtk.ICON_SIZE_MENU)
    item.set_image(icon)
    manage_transport_submenu = gtk.Menu()
    item.set_submenu(manage_transport_submenu)
    menu.append(item)

    # Modify Transport
    item = gtk.ImageMenuItem(_('_Modify Transport'))
    icon = gtk.image_new_from_stock(gtk.STOCK_PREFERENCES, gtk.ICON_SIZE_MENU)
    item.set_image(icon)
    manage_transport_submenu.append(item)
    item.connect('activate', roster.on_edit_agent, contact, account)
    if gajim.account_is_disconnected(account):
        item.set_sensitive(False)

    # Rename
    item = gtk.ImageMenuItem(_('_Rename...'))
    # add a special img for rename menuitem
    gtkgui_helpers.add_image_to_menuitem(item, 'gajim-kbd_input')
    manage_transport_submenu.append(item)
    item.connect('activate', roster.on_rename, 'agent', jid, account)
    if gajim.account_is_disconnected(account):
        item.set_sensitive(False)

    item = gtk.SeparatorMenuItem() # separator
    manage_transport_submenu.append(item)

    # Block
    if blocked:
        item = gtk.ImageMenuItem(_('_Unblock'))
        item.connect('activate', roster.on_unblock, [(contact, account)])
    else:
        item = gtk.ImageMenuItem(_('_Block'))
        item.connect('activate', roster.on_block, [(contact, account)])

    icon = gtk.image_new_from_stock(gtk.STOCK_STOP, gtk.ICON_SIZE_MENU)
    item.set_image(icon)
    manage_transport_submenu.append(item)
    if gajim.account_is_disconnected(account):
        item.set_sensitive(False)

    # Remove
    item = gtk.ImageMenuItem(_('Remo_ve'))
    icon = gtk.image_new_from_stock(gtk.STOCK_REMOVE, gtk.ICON_SIZE_MENU)
    item.set_image(icon)
    manage_transport_submenu.append(item)
    item.connect('activate', roster.on_remove_agent, [(contact, account)])
    if gajim.account_is_disconnected(account):
        item.set_sensitive(False)

    item = gtk.SeparatorMenuItem() # separator
    menu.append(item)

    # Information
    information_menuitem = gtk.ImageMenuItem(_('_Information'))
    icon = gtk.image_new_from_stock(gtk.STOCK_INFO, gtk.ICON_SIZE_MENU)
    information_menuitem.set_image(icon)
    menu.append(information_menuitem)
    information_menuitem.connect('activate', roster.on_info, contact, account)
    if gajim.account_is_disconnected(account):
        information_menuitem.set_sensitive(False)

    menu.connect('selection-done', gtkgui_helpers.destroy_widget)
    menu.show_all()
    return menu
Esempio n. 18
0
def notify(event, jid, account, parameters, advanced_notif_num=None):
    '''Check what type of notifications we want, depending on basic
	and the advanced configuration of notifications and do these notifications;
	advanced_notif_num holds the number of the first (top most) advanced
	notification'''
    # First, find what notifications we want
    do_popup = False
    do_sound = False
    do_cmd = False
    if event == 'status_change':
        new_show = parameters[0]
        status_message = parameters[1]
        # Default: No popup for status change
    elif event == 'contact_connected':
        status_message = parameters
        j = gajim.get_jid_without_resource(jid)
        server = gajim.get_server_from_jid(j)
        account_server = account + '/' + server
        block_transport = False
        if account_server in gajim.block_signed_in_notifications and \
        gajim.block_signed_in_notifications[account_server]:
            block_transport = True
        if helpers.allow_showing_notification(account, 'notify_on_signin') and \
        not gajim.block_signed_in_notifications[account] and not block_transport:
            do_popup = True
        if gajim.config.get_per('soundevents', 'contact_connected',
        'enabled') and not gajim.block_signed_in_notifications[account] and \
        not block_transport:
            do_sound = True
    elif event == 'contact_disconnected':
        status_message = parameters
        if helpers.allow_showing_notification(account, 'notify_on_signout'):
            do_popup = True
        if gajim.config.get_per('soundevents', 'contact_disconnected',
                                'enabled'):
            do_sound = True
    elif event == 'new_message':
        message_type = parameters[0]
        is_first_message = parameters[1]
        nickname = parameters[2]
        if gajim.config.get('notification_preview_message'):
            message = parameters[3]
            if message.startswith('/me ') or message.startswith('/me\n'):
                message = '* ' + nickname + message[3:]
        else:
            # We don't want message preview, do_preview = False
            message = ''
        focused = parameters[4]
        if helpers.allow_showing_notification(account, 'notify_on_new_message',
                                              advanced_notif_num,
                                              is_first_message):
            do_popup = True
        if is_first_message and helpers.allow_sound_notification(
                'first_message_received', advanced_notif_num):
            do_sound = True
        elif not is_first_message and focused and \
        helpers.allow_sound_notification('next_message_received_focused',
        advanced_notif_num):
            do_sound = True
        elif not is_first_message and not focused and \
        helpers.allow_sound_notification('next_message_received_unfocused',
        advanced_notif_num):
            do_sound = True
    else:
        print '*Event not implemeted yet*'

    if advanced_notif_num is not None and gajim.config.get_per(
            'notifications', str(advanced_notif_num), 'run_command'):
        do_cmd = True

    # Do the wanted notifications
    if do_popup:
        if event in ('contact_connected', 'contact_disconnected',
                     'status_change'
                     ):  # Common code for popup for these three events
            if event == 'contact_disconnected':
                show_image = 'offline.png'
                suffix = '_notif_size_bw'
            else:  #Status Change or Connected
                # FIXME: for status change,
                # we don't always 'online.png', but we
                # first need 48x48 for all status
                show_image = 'online.png'
                suffix = '_notif_size_colored'
            transport_name = gajim.get_transport_name_from_jid(jid)
            img = None
            if transport_name:
                img = os.path.join(helpers.get_transport_path(transport_name),
                                   '48x48', show_image)
            if not img or not os.path.isfile(img):
                iconset = gajim.config.get('iconset')
                img = os.path.join(helpers.get_iconset_path(iconset), '48x48',
                                   show_image)
            path = gtkgui_helpers.get_path_to_generic_or_avatar(img,
                                                                jid=jid,
                                                                suffix=suffix)
            if event == 'status_change':
                title = _('%(nick)s Changed Status') % \
                 {'nick': gajim.get_name_from_jid(account, jid)}
                text = _('%(nick)s is now %(status)s') % \
                 {'nick': gajim.get_name_from_jid(account, jid),\
                 'status': helpers.get_uf_show(gajim.SHOW_LIST[new_show])}
                if status_message:
                    text = text + " : " + status_message
                popup(_('Contact Changed Status'),
                      jid,
                      account,
                      path_to_image=path,
                      title=title,
                      text=text)
            elif event == 'contact_connected':
                title = _('%(nickname)s Signed In') % \
                 {'nickname': gajim.get_name_from_jid(account, jid)}
                text = ''
                if status_message:
                    text = status_message
                popup(_('Contact Signed In'),
                      jid,
                      account,
                      path_to_image=path,
                      title=title,
                      text=text)
            elif event == 'contact_disconnected':
                title = _('%(nickname)s Signed Out') % \
                 {'nickname': gajim.get_name_from_jid(account, jid)}
                text = ''
                if status_message:
                    text = status_message
                popup(_('Contact Signed Out'),
                      jid,
                      account,
                      path_to_image=path,
                      title=title,
                      text=text)
        elif event == 'new_message':
            if message_type == 'normal':  # single message
                event_type = _('New Single Message')
                img = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events',
                                   'single_msg_recv.png')
                title = _('New Single Message from %(nickname)s') % \
                 {'nickname': nickname}
                text = message
            elif message_type == 'pm':  # private message
                event_type = _('New Private Message')
                room_name = gajim.get_nick_from_jid(jid)
                img = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events',
                                   'priv_msg_recv.png')
                title = _('New Private Message from group chat %s') % room_name
                if message:
                    text = _('%(nickname)s: %(message)s') % {
                        'nickname': nickname,
                        'message': message
                    }
                else:
                    text = _('Messaged by %(nickname)s') % {
                        'nickname': nickname
                    }

            else:  # chat message
                event_type = _('New Message')
                img = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events',
                                   'chat_msg_recv.png')
                title = _('New Message from %(nickname)s') % \
                 {'nickname': nickname}
                text = message
            path = gtkgui_helpers.get_path_to_generic_or_avatar(img)
            popup(event_type,
                  jid,
                  account,
                  message_type,
                  path_to_image=path,
                  title=title,
                  text=text)

    if do_sound:
        snd_file = None
        snd_event = None  # If not snd_file, play the event
        if event == 'new_message':
            if advanced_notif_num is not None and gajim.config.get_per(
                    'notifications', str(advanced_notif_num),
                    'sound') == 'yes':
                snd_file = gajim.config.get_per('notifications',
                                                str(advanced_notif_num),
                                                'sound_file')
            elif advanced_notif_num is not None and gajim.config.get_per(
                    'notifications', str(advanced_notif_num), 'sound') == 'no':
                pass  # do not set snd_event
            elif is_first_message:
                snd_event = 'first_message_received'
            elif focused:
                snd_event = 'next_message_received_focused'
            else:
                snd_event = 'next_message_received_unfocused'
        elif event in ('contact_connected', 'contact_disconnected'):
            snd_event = event
        if snd_file:
            helpers.play_sound_file(snd_file)
        if snd_event:
            helpers.play_sound(snd_event)

    if do_cmd:
        command = gajim.config.get_per('notifications',
                                       str(advanced_notif_num), 'command')
        try:
            helpers.exec_command(command)
        except Exception:
            pass
Esempio n. 19
0
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 == gajim.get_jid_from_account(account)
    roster = gajim.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')
    set_custom_avatar_menuitem = xml.get_object('set_custom_avatar_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')
    encryption_separator = xml.get_object('encryption_separator')
    toggle_gpg_menuitem = xml.get_object('toggle_gpg_menuitem')
    toggle_e2e_menuitem = xml.get_object('toggle_e2e_menuitem')
    last_separator = xml.get_object('last_separator')

    items_to_hide = []

    # add a special img for send file menuitem
    pixbuf = gtkgui_helpers.get_icon_pixmap('document-send', quiet=True)
    img = gtk.image_new_from_pixbuf(pixbuf)
    send_file_menuitem.set_image(img)

    if not our_jid:
        # add a special img for rename menuitem
        gtkgui_helpers.add_image_to_menuitem(rename_menuitem, 'gajim-kbd_input')

    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) or contact.supports(NS_JINGLE_FILE_TRANSFER):
            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 gtkgui_helpers.gtk_icon_theme.has_icon('document-open-recent'):
        img = gtk.Image()
        img.set_from_icon_name('document-open-recent', gtk.ICON_SIZE_MENU)
        history_menuitem.set_image(img)

    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 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, 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_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)
            toggle_gpg_menuitem.connect('activate',
                    control._on_toggle_gpg_menuitem_activate)

        # 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)
            toggle_e2e_menuitem.connect('activate',
                    control._on_toggle_e2e_menuitem_activate)

    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 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, 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 = gajim.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_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)

    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_ = gajim.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 gajim.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)
    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)
        transport = gajim.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 gajim.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)

    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 or gajim.connections[account].blocking_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)\
            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 gajim.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
Esempio n. 20
0
    def populate(self, contacts, account, typ):
        """
        Populate the Tooltip Grid with data of from the contact
        """
        self.current_row = 0
        self.account = account
        if self.last_widget:
            self.last_widget.set_vexpand(False)

        self.clear_tooltip()

        if account == 'all':
            # Tooltip for merged accounts row
            accounts = helpers.get_notification_icon_tooltip_dict()
            self.spacer_label = ''
            self.fill_table_with_accounts(accounts)
            self.tooltip_grid.attach(self.table, 0, 3, 2, 1)
            self.table.show_all()
            return

        if typ == 'account':
            jid = gajim.get_jid_from_account(account)
            contacts = []
            connection = gajim.connections[account]
            # get our current contact info

            nbr_on, nbr_total = gajim.\
                contacts.get_nb_online_total_contacts(
                accounts=[account])
            account_name = account
            if gajim.account_is_connected(account):
                account_name += ' (%s/%s)' % (repr(nbr_on),
                    repr(nbr_total))
            contact = gajim.contacts.create_self_contact(jid=jid,
                account=account, name=account_name,
                show=connection.get_status(), status=connection.status,
                resource=connection.server_resource,
                priority=connection.priority)
            if gajim.connections[account].gpg:
                contact.keyID = gajim.config.get_per('accounts',
                    connection.name, 'keyid')
            contacts.append(contact)
            # if we're online ...
            if connection.connection:
                roster = connection.connection.getRoster()
                # in threadless connection when no roster stanza is sent
                # 'roster' is None
                if roster and roster.getItem(jid):
                    resources = roster.getResources(jid)
                    # ...get the contact info for our other online
                    # resources
                    for resource in resources:
                        # Check if we already have this resource
                        found = False
                        for contact_ in contacts:
                            if contact_.resource == resource:
                                found = True
                                break
                        if found:
                            continue
                        show = roster.getShow(jid + '/' + resource)
                        if not show:
                            show = 'online'
                        contact = gajim.contacts.create_self_contact(
                            jid=jid, account=account, show=show,
                            status=roster.getStatus(
                            jid + '/' + resource),
                            priority=roster.getPriority(
                            jid + '/' + resource), resource=resource)
                        contacts.append(contact)

        # Username/Account/Groupchat
        self.prim_contact = gajim.contacts.get_highest_prio_contact_from_contacts(
            contacts)
        self.contact_jid = self.prim_contact.jid
        name = GLib.markup_escape_text(self.prim_contact.get_shown_name())
        name_markup = '<b>{}</b>'.format(name)
        if gajim.config.get('mergeaccounts'):
            color = gajim.config.get('tooltip_account_name_color')
            account_name = GLib.markup_escape_text(self.prim_contact.account.name)
            name_markup += " <span foreground='{}'>({})</span>".format(
                color, account_name)

        if account and helpers.jid_is_blocked(account, self.prim_contact.jid):
            name_markup += _(' [blocked]')

        try:
            if self.prim_contact.jid in gajim.interface.minimized_controls[account]:
                name_markup += _(' [minimized]')
        except KeyError:
            pass

        self.name.set_markup(name_markup)
        self.name.show()

        self.num_resources = 0
        # put contacts in dict, where key is priority
        contacts_dict = {}
        for contact in contacts:
            if contact.resource:
                self.num_resources += 1
                priority = int(contact.priority)
                if priority in contacts_dict:
                    contacts_dict[priority].append(contact)
                else:
                    contacts_dict[priority] = [contact]
        if self.num_resources > 1:
            self.status_label.show()
            transport = gajim.get_transport_name_from_jid(self.prim_contact.jid)
            if transport:
                file_path = os.path.join(helpers.get_transport_path(transport),
                    '16x16')
            else:
                iconset = gajim.config.get('iconset')
                if not iconset:
                    iconset = 'dcraven'
                file_path = os.path.join(helpers.get_iconset_path(iconset),
                    '16x16')

            contact_keys = sorted(contacts_dict.keys())
            contact_keys.reverse()
            for priority in contact_keys:
                for acontact in contacts_dict[priority]:
                    icon_name = self._get_icon_name_for_tooltip(acontact)
                    if acontact.status and len(acontact.status) > 25:
                        status = ''
                        add_text = True
                    else:
                        status = acontact.status
                        add_text = False

                    status_line = self.get_status_info(acontact.resource,
                    acontact.priority, acontact.show, status)
                    self.add_status_row(file_path, icon_name, status_line,
                        acontact.last_status_time)
                    if add_text:
                        self.add_text_row(acontact.status, 2)

            self.tooltip_grid.attach(self.table, 0, 3, 2, 1)
            self.table.show_all()

        else:  # only one resource
            if contact.show:
                request_time = False
                try:
                    last_time = self.check_last_time[contact]
                    if isinstance(last_time, float) and last_time < time.time() - 60:
                        request_time = True
                except KeyError:
                    request_time = True

                if request_time:
                    if contact.show == 'offline':
                        gajim.connections[account].\
                            request_last_status_time(contact.jid, '')
                    elif contact.resource:
                        gajim.connections[account].\
                            request_last_status_time(
                            contact.jid, contact.resource)
                    self.check_last_time[contact] = time.time()

                if contact.status:
                    status = contact.status.strip()
                    if status:
                        self.status.set_text(status)
                        self.status.show()
                        self.status_label.show()

        # PEP Info
        self._append_pep_info(contact)

        # JID
        self.jid.set_text(self.prim_contact.jid)
        self.jid.show()
        self.jid_label.show()

        # contact has only one ressource
        if self.num_resources == 1 and contact.resource:
            res = GLib.markup_escape_text(contact.resource)
            prio = str(contact.priority)
            self.resource.set_text("{} ({})".format(res, prio))
            self.resource.show()
            self.resource_label.show()

        if self.prim_contact.jid not in gajim.gc_connected[account]:
            if (account and
                self.prim_contact.sub and
                    self.prim_contact.sub != 'both'):
                # ('both' is the normal sub so we don't show it)
                self.sub.set_text(helpers.get_uf_sub(self.prim_contact.sub))
                self.sub.show()
                self.sub_label.show()

        if self.prim_contact.keyID:
            keyID = None
            if len(self.prim_contact.keyID) == 8:
                keyID = self.prim_contact.keyID
            elif len(self.prim_contact.keyID) == 16:
                keyID = self.prim_contact.keyID[8:]
            if keyID:
                self.pgp.set_text(keyID)
                self.pgp.show()
                self.pgp_label.show()

        self._set_idle_time(contact)

        # Avatar
        puny_jid = helpers.sanitize_filename(self.prim_contact.jid)
        file_ = helpers.get_avatar_path(os.path.join(gajim.AVATAR_PATH,
            puny_jid))
        if file_:
            with open(file_, 'rb') as file_data:
                pix = gtkgui_helpers.get_pixbuf_from_data(file_data.read())
            pix = gtkgui_helpers.get_scaled_pixbuf(pix, 'tooltip')
            self.avatar.set_from_pixbuf(pix)
            self.avatar.show()

            # Sets the Widget that is at the bottom to expand.
            # This is needed in case the Picture takes more Space then the Labels
            i = 1
            while i < 15:
                if self.tooltip_grid.get_child_at(0, i):
                    if self.tooltip_grid.get_child_at(0, i).get_visible():
                        self.last_widget = self.tooltip_grid.get_child_at(0, i)
                i += 1
            self.last_widget.set_vexpand(True)
Esempio n. 21
0
	def populate(self, contacts):
		self.create_window()

		self.create_table()
		if not contacts or len(contacts) == 0:
			# Tooltip for merged accounts row
			accounts = helpers.get_notification_icon_tooltip_dict()
			self.table.resize(2, 1)
			self.spacer_label = ''
			self.fill_table_with_accounts(accounts)
			self.win.add(self.table)
			return
		
		# primary contact
		prim_contact = gajim.contacts.get_highest_prio_contact_from_contacts(
			contacts)
		
		puny_jid = helpers.sanitize_filename(prim_contact.jid)
		table_size = 3

		file = helpers.get_avatar_path(os.path.join(gajim.AVATAR_PATH, puny_jid))
		if file:
			self.avatar_image.set_from_file(file)
			pix = self.avatar_image.get_pixbuf()
			pix = gtkgui_helpers.get_scaled_pixbuf(pix, 'tooltip')
			self.avatar_image.set_from_pixbuf(pix)
			table_size = 4
		else:
			self.avatar_image.set_from_pixbuf(None)
		vcard_table = gtk.Table(table_size, 1)
		vcard_table.set_property('column-spacing', 2)
		vcard_table.set_homogeneous(False)
		vcard_current_row = 1
		properties = []

		name_markup = u'<span weight="bold">' + \
			gobject.markup_escape_text(prim_contact.get_shown_name())\
			+ '</span>'
		if self.account and prim_contact.jid in gajim.connections[
		self.account].blocked_contacts:
			name_markup += _(' [blocked]')
		if self.account and \
		self.account in gajim.interface.minimized_controls and \
		prim_contact.jid in gajim.interface.minimized_controls[self.account]:
			name_markup += _(' [minimized]')
		properties.append((name_markup, None))

		num_resources = 0
		# put contacts in dict, where key is priority
		contacts_dict = {}
		for contact in contacts:
			if contact.resource:
				num_resources += 1
				if contact.priority in contacts_dict:
					contacts_dict[contact.priority].append(contact)
				else:
					contacts_dict[contact.priority] = [contact]

		if num_resources > 1:
			properties.append((_('Status: '),	' '))
			transport = gajim.get_transport_name_from_jid(
				prim_contact.jid)
			if transport:
				file_path = os.path.join(helpers.get_transport_path(transport),
					'16x16')
			else:
				iconset = gajim.config.get('iconset')
				if not iconset:
					iconset = 'dcraven'
				file_path = os.path.join(helpers.get_iconset_path(iconset), '16x16')

			contact_keys = sorted(contacts_dict.keys())
			contact_keys.reverse()
			for priority in contact_keys:
				for contact in contacts_dict[priority]:
					status_line = self.get_status_info(contact.resource,
						contact.priority, contact.show, contact.status)
					
					icon_name = self._get_icon_name_for_tooltip(contact)
					self.add_status_row(file_path, icon_name, status_line,
						contact.last_status_time)
			properties.append((self.table,	None))

		else: # only one resource
			if contact.show:
				show = helpers.get_uf_show(contact.show) 
				if contact.last_status_time:
					vcard_current_row += 1
					if contact.show == 'offline':
						text = ' - ' + _('Last status: %s')
					else:
						text = _(' since %s')
					
					if time.strftime('%j', time.localtime())== \
							time.strftime('%j', contact.last_status_time):
					# it's today, show only the locale hour representation
						local_time = time.strftime('%X',
							contact.last_status_time)
					else:
						# time.strftime returns locale encoded string
						local_time = time.strftime('%c',
							contact.last_status_time)
					local_time = local_time.decode(
						locale.getpreferredencoding())
					text = text % local_time 
					show += text
				if self.account and \
				prim_contact.jid in gajim.gc_connected[self.account]:
					if gajim.gc_connected[self.account][prim_contact.jid]:
						show = _('Connected')
					else:
						show = _('Disconnected')
				show = '<i>' + show + '</i>'
				# we append show below
				
				if contact.status:
					status = contact.status.strip()
					if status:
						# reduce long status
						# (no more than 300 chars on line and no more than 5 lines)
						# status is wrapped
						status = helpers.reduce_chars_newlines(status, 300, 5)
						# escape markup entities. 
						status = gobject.markup_escape_text(status)
						properties.append(('<i>%s</i>' % status, None))
				properties.append((show, None))
				
		self._append_pep_info(contact, properties)
		
		properties.append((_('Jabber ID: '), prim_contact.jid ))

		# contact has only one ressource
		if num_resources == 1 and contact.resource:
			properties.append((_('Resource: '),
				gobject.markup_escape_text(contact.resource) +\
				' (' + unicode(contact.priority) + ')'))
		
		if self.account and prim_contact.sub and prim_contact.sub != 'both' and\
		prim_contact.jid not in gajim.gc_connected[self.account]:
			# ('both' is the normal sub so we don't show it)
			properties.append(( _('Subscription: '), 
				gobject.markup_escape_text(helpers.get_uf_sub(prim_contact.sub))))
	
		if prim_contact.keyID:
			keyID = None
			if len(prim_contact.keyID) == 8:
				keyID = prim_contact.keyID
			elif len(prim_contact.keyID) == 16:
				keyID = prim_contact.keyID[8:]
			if keyID:
				properties.append((_('OpenPGP: '),
					gobject.markup_escape_text(keyID)))
		
		while properties:
			property = properties.pop(0)
			vcard_current_row += 1
			vertical_fill = gtk.FILL
			if not properties and table_size == 4:
				vertical_fill |= gtk.EXPAND
			label = gtk.Label()
			label.set_alignment(0, 0)
			if property[1]:
				label.set_markup(property[0])
				vcard_table.attach(label, 1, 2, vcard_current_row,
					vcard_current_row + 1, gtk.FILL, vertical_fill, 0, 0)
				label = gtk.Label()
				label.set_alignment(0, 0)
				label.set_markup(property[1])
				label.set_line_wrap(True)
				vcard_table.attach(label, 2, 3, vcard_current_row,
					vcard_current_row + 1, gtk.EXPAND | gtk.FILL,
						vertical_fill, 0, 0)
			else:
				if isinstance(property[0], (unicode, str)): #FIXME: rm unicode?
					label.set_markup(property[0]) 
					label.set_line_wrap(True)
				else:
					label = property[0]
				vcard_table.attach(label, 1, 3, vcard_current_row,
					vcard_current_row + 1, gtk.FILL, vertical_fill, 0)
		self.avatar_image.set_alignment(0, 0)
		if table_size == 4:
			vcard_table.attach(self.avatar_image, 3, 4, 2,
				vcard_current_row + 1, gtk.FILL, gtk.FILL | gtk.EXPAND, 3, 3)
		self.win.add(vcard_table)
Esempio n. 22
0
    def make_menu(self, event_button, event_time):
        """
        Create chat with and new message (sub) menus/menuitems
        """
        for m in self.popup_menus:
            m.destroy()

        chat_with_menuitem = self.xml.get_object('chat_with_menuitem')
        single_message_menuitem = self.xml.get_object(
                'single_message_menuitem')
        status_menuitem = self.xml.get_object('status_menu')
        join_gc_menuitem = self.xml.get_object('join_gc_menuitem')
        sounds_mute_menuitem = self.xml.get_object('sounds_mute_menuitem')
        show_roster_menuitem = self.xml.get_object('show_roster_menuitem')

        if self.single_message_handler_id:
            single_message_menuitem.handler_disconnect(
                    self.single_message_handler_id)
            self.single_message_handler_id = None
        if self.new_chat_handler_id:
            chat_with_menuitem.disconnect(self.new_chat_handler_id)
            self.new_chat_handler_id = None

        sub_menu = gtk.Menu()
        self.popup_menus.append(sub_menu)
        status_menuitem.set_submenu(sub_menu)

        gc_sub_menu = gtk.Menu() # gc is always a submenu
        join_gc_menuitem.set_submenu(gc_sub_menu)

        # We need our own set of status icons, let's make 'em!
        iconset = gajim.config.get('iconset')
        path = os.path.join(helpers.get_iconset_path(iconset), '16x16')
        state_images = gtkgui_helpers.load_iconset(path)

        if 'muc_active' in state_images:
            join_gc_menuitem.set_image(state_images['muc_active'])

        for show in ('online', 'chat', 'away', 'xa', 'dnd', 'invisible'):
            uf_show = helpers.get_uf_show(show, use_mnemonic = True)
            item = gtk.ImageMenuItem(uf_show)
            item.set_image(state_images[show])
            sub_menu.append(item)
            item.connect('activate', self.on_show_menuitem_activate, show)

        item = gtk.SeparatorMenuItem()
        sub_menu.append(item)

        item = gtk.ImageMenuItem(_('_Change Status Message...'))
        gtkgui_helpers.add_image_to_menuitem(item, 'gajim-kbd_input')
        sub_menu.append(item)
        item.connect('activate', self.on_change_status_message_activate)

        connected_accounts = gajim.get_number_of_connected_accounts()
        if connected_accounts < 1:
            item.set_sensitive(False)

        connected_accounts_with_private_storage = 0

        item = gtk.SeparatorMenuItem()
        sub_menu.append(item)

        uf_show = helpers.get_uf_show('offline', use_mnemonic = True)
        item = gtk.ImageMenuItem(uf_show)
        item.set_image(state_images['offline'])
        sub_menu.append(item)
        item.connect('activate', self.on_show_menuitem_activate, 'offline')

        iskey = connected_accounts > 0 and not (connected_accounts == 1 and
            gajim.zeroconf_is_connected())
        chat_with_menuitem.set_sensitive(iskey)
        single_message_menuitem.set_sensitive(iskey)
        join_gc_menuitem.set_sensitive(iskey)

        accounts_list = sorted(gajim.contacts.get_accounts())
        # items that get shown whether an account is zeroconf or not
        if connected_accounts > 1: # 2 or more connections? make submenus
            account_menu_for_chat_with = gtk.Menu()
            chat_with_menuitem.set_submenu(account_menu_for_chat_with)
            self.popup_menus.append(account_menu_for_chat_with)

            for account in accounts_list:
                if gajim.account_is_connected(account):
                    # for chat_with
                    item = gtk.MenuItem(_('using account %s') % account)
                    account_menu_for_chat_with.append(item)
                    item.connect('activate', self.on_new_chat, account)

        elif connected_accounts == 1: # one account
            # one account connected, no need to show 'as jid'
            for account in gajim.connections:
                if gajim.connections[account].connected > 1:
                    # for start chat
                    self.new_chat_handler_id = chat_with_menuitem.connect(
                            'activate', self.on_new_chat, account)
                    break # No other connected account

        # menu items that don't apply to zeroconf connections
        if connected_accounts == 1 or (connected_accounts == 2 and \
        gajim.zeroconf_is_connected()):
            # only one 'real' (non-zeroconf) account is connected, don't need
            # submenus
            for account in gajim.connections:
                if gajim.account_is_connected(account) and \
                not gajim.config.get_per('accounts', account, 'is_zeroconf'):
                    if gajim.connections[account].private_storage_supported:
                        connected_accounts_with_private_storage += 1

                    # for single message
                    single_message_menuitem.remove_submenu()
                    self.single_message_handler_id = single_message_menuitem.\
                            connect('activate',
                            self.on_single_message_menuitem_activate, account)
                    # join gc
                    gajim.interface.roster.add_bookmarks_list(gc_sub_menu,
                            account)
                    break # No other account connected
        else:
            # 2 or more 'real' accounts are connected, make submenus
            account_menu_for_single_message = gtk.Menu()
            single_message_menuitem.set_submenu(
                    account_menu_for_single_message)
            self.popup_menus.append(account_menu_for_single_message)

            for account in accounts_list:
                if gajim.connections[account].is_zeroconf or \
                not gajim.account_is_connected(account):
                    continue
                if gajim.connections[account].private_storage_supported:
                    connected_accounts_with_private_storage += 1
                # for single message
                item = gtk.MenuItem(_('using account %s') % account)
                item.connect('activate',
                        self.on_single_message_menuitem_activate, account)
                account_menu_for_single_message.append(item)

                # join gc
                gc_item = gtk.MenuItem(_('using account %s') % account, False)
                gc_sub_menu.append(gc_item)
                gc_menuitem_menu = gtk.Menu()
                gajim.interface.roster.add_bookmarks_list(gc_menuitem_menu,
                        account)
                gc_item.set_submenu(gc_menuitem_menu)
                gc_sub_menu.show_all()

        newitem = gtk.SeparatorMenuItem() # separator
        gc_sub_menu.append(newitem)
        newitem = gtk.ImageMenuItem(_('_Manage Bookmarks...'))
        img = gtk.image_new_from_stock(gtk.STOCK_PREFERENCES, gtk.ICON_SIZE_MENU)
        newitem.set_image(img)
        newitem.connect('activate',
                gajim.interface.roster.on_manage_bookmarks_menuitem_activate)
        gc_sub_menu.append(newitem)
        if connected_accounts_with_private_storage == 0:
            newitem.set_sensitive(False)

        sounds_mute_menuitem.set_active(not gajim.config.get('sounds_on'))

        win = gajim.interface.roster.window
        if self.show_roster_handler_id:
            show_roster_menuitem.handler_disconnect(self.show_roster_handler_id)
        if win.get_property('has-toplevel-focus'):
            show_roster_menuitem.get_children()[0].set_label(_('Hide _Roster'))
            self.show_roster_handler_id = show_roster_menuitem.connect(
                'activate', self.on_hide_roster_menuitem_activate)
        else:
            show_roster_menuitem.get_children()[0].set_label(_('Show _Roster'))
            self.show_roster_handler_id = show_roster_menuitem.connect(
                'activate', self.on_show_roster_menuitem_activate)

        if os.name == 'nt':
            if self.added_hide_menuitem is False:
                self.systray_context_menu.prepend(gtk.SeparatorMenuItem())
                item = gtk.MenuItem(_('Hide this menu'))
                self.systray_context_menu.prepend(item)
                self.added_hide_menuitem = True

        self.systray_context_menu.show_all()
        self.systray_context_menu.popup(None, None, None, 0,
                event_time)
Esempio n. 23
0
    def make_menu(self, event_button, event_time):
        '''create chat with and new message (sub) menus/menuitems'''
        for m in self.popup_menus:
            m.destroy()

        chat_with_menuitem = self.xml.get_widget('chat_with_menuitem')
        single_message_menuitem = self.xml.get_widget(
            'single_message_menuitem')
        status_menuitem = self.xml.get_widget('status_menu')
        join_gc_menuitem = self.xml.get_widget('join_gc_menuitem')
        sounds_mute_menuitem = self.xml.get_widget('sounds_mute_menuitem')

        if self.single_message_handler_id:
            single_message_menuitem.handler_disconnect(
                self.single_message_handler_id)
            self.single_message_handler_id = None
        if self.new_chat_handler_id:
            chat_with_menuitem.disconnect(self.new_chat_handler_id)
            self.new_chat_handler_id = None

        sub_menu = gtk.Menu()
        self.popup_menus.append(sub_menu)
        status_menuitem.set_submenu(sub_menu)

        gc_sub_menu = gtk.Menu()  # gc is always a submenu
        join_gc_menuitem.set_submenu(gc_sub_menu)

        # We need our own set of status icons, let's make 'em!
        iconset = gajim.config.get('iconset')
        path = os.path.join(helpers.get_iconset_path(iconset), '16x16')
        state_images = gtkgui_helpers.load_iconset(path)

        if 'muc_active' in state_images:
            join_gc_menuitem.set_image(state_images['muc_active'])

        for show in ('online', 'chat', 'away', 'xa', 'dnd', 'invisible'):
            uf_show = helpers.get_uf_show(show, use_mnemonic=True)
            item = gtk.ImageMenuItem(uf_show)
            item.set_image(state_images[show])
            sub_menu.append(item)
            if os.name == 'nt':
                #FIXME: bug in pygtk, activate is not called.
                # see http://trac.gajim.org/ticket/4310
                item.connect('button_press_event',
                             self.on_show_menuitem_activate2, show)
            else:
                item.connect('activate', self.on_show_menuitem_activate, show)

        item = gtk.SeparatorMenuItem()
        sub_menu.append(item)

        item = gtk.ImageMenuItem(_('_Change Status Message...'))
        path = os.path.join(gajim.DATA_DIR, 'pixmaps', 'kbd_input.png')
        img = gtk.Image()
        img.set_from_file(path)
        item.set_image(img)
        sub_menu.append(item)
        if os.name == 'nt':
            #FIXME: bug in pygtk, activate is not called.
            # see http://trac.gajim.org/ticket/4310
            item.connect('button_press_event',
                         self.on_change_status_message_activate2)
        else:
            item.connect('activate', self.on_change_status_message_activate)

        connected_accounts = gajim.get_number_of_connected_accounts()
        if connected_accounts < 1:
            item.set_sensitive(False)

        item = gtk.SeparatorMenuItem()
        sub_menu.append(item)

        uf_show = helpers.get_uf_show('offline', use_mnemonic=True)
        item = gtk.ImageMenuItem(uf_show)
        item.set_image(state_images['offline'])
        sub_menu.append(item)
        if os.name == 'nt':
            #FIXME: bug in pygtk, activate is not called.
            # see http://trac.gajim.org/ticket/4310
            item.connect('button_press_event', self.on_show_menuitem_activate2,
                         'offline')
        else:
            item.connect('activate', self.on_show_menuitem_activate, 'offline')

        iskey = connected_accounts > 0 and not (
            connected_accounts == 1
            and gajim.connections[gajim.connections.keys()[0]].is_zeroconf)
        chat_with_menuitem.set_sensitive(iskey)
        single_message_menuitem.set_sensitive(iskey)
        join_gc_menuitem.set_sensitive(iskey)

        if connected_accounts >= 2:  # 2 or more connections? make submenus
            account_menu_for_chat_with = gtk.Menu()
            chat_with_menuitem.set_submenu(account_menu_for_chat_with)
            self.popup_menus.append(account_menu_for_chat_with)

            account_menu_for_single_message = gtk.Menu()
            single_message_menuitem.set_submenu(
                account_menu_for_single_message)
            self.popup_menus.append(account_menu_for_single_message)

            accounts_list = sorted(gajim.contacts.get_accounts())
            for account in accounts_list:
                if gajim.connections[account].is_zeroconf:
                    continue
                if gajim.connections[account].connected > 1:
                    # for chat_with
                    item = gtk.MenuItem(_('using account %s') % account)
                    account_menu_for_chat_with.append(item)
                    if os.name == 'nt':
                        #FIXME: bug in pygtk, activate is not called.
                        # see http://trac.gajim.org/ticket/4310
                        item.connect('button_press_event', self.on_new_chat2,
                                     account)
                    else:
                        item.connect('activate', self.on_new_chat, account)

                    # for single message
                    item = gtk.MenuItem(_('using account %s') % account)
                    if os.name == 'nt':
                        #FIXME: bug in pygtk, activate is not called.
                        # see http://trac.gajim.org/ticket/4310
                        item.connect('button_press_event',
                                     self.on_single_message_menuitem_activate2,
                                     account)
                    else:
                        item.connect('activate',
                                     self.on_single_message_menuitem_activate,
                                     account)
                    account_menu_for_single_message.append(item)

                    # join gc
                    gc_item = gtk.MenuItem(
                        _('using account %s') % account, False)
                    gc_sub_menu.append(gc_item)
                    gc_menuitem_menu = gtk.Menu()
                    if os.name == 'nt':
                        #FIXME: bug in pygtk, activate is not called.
                        # see http://trac.gajim.org/ticket/4310
                        self.add_bookmarks_list2(gc_menuitem_menu, account)
                    else:
                        gajim.interface.roster.add_bookmarks_list(
                            gc_menuitem_menu, account)
                    gc_item.set_submenu(gc_menuitem_menu)
                    gc_sub_menu.show_all()

        elif connected_accounts == 1:  # one account
            # one account connected, no need to show 'as jid'
            for account in gajim.connections:
                if gajim.connections[account].connected > 1:
                    self.new_chat_handler_id = chat_with_menuitem.connect(
                        'activate', self.on_new_chat, account)
                    # for single message
                    single_message_menuitem.remove_submenu()
                    self.single_message_handler_id = single_message_menuitem.\
                     connect('activate',
                     self.on_single_message_menuitem_activate, account)

                    # join gc
                    if os.name == 'nt':
                        #FIXME: bug in pygtk, activate is not called.
                        # see http://trac.gajim.org/ticket/4310
                        self.add_bookmarks_list2(gc_sub_menu, account)
                    else:
                        gajim.interface.roster.add_bookmarks_list(
                            gc_sub_menu, account)
                    break  # No other connected account

        newitem = gtk.SeparatorMenuItem()  # separator
        gc_sub_menu.append(newitem)
        newitem = gtk.ImageMenuItem(_('_Manage Bookmarks...'))
        img = gtk.image_new_from_stock(gtk.STOCK_PREFERENCES,
                                       gtk.ICON_SIZE_MENU)
        newitem.set_image(img)
        if os.name == 'nt':
            #FIXME: bug in pygtk, activate is not called.
            # see http://trac.gajim.org/ticket/4310
            newitem.connect('button_press_event',
                            self.on_manage_bookmarks_menuitem_activate2)
        else:
            newitem.connect(
                'activate',
                gajim.interface.roster.on_manage_bookmarks_menuitem_activate)
        gc_sub_menu.append(newitem)

        sounds_mute_menuitem.set_active(not gajim.config.get('sounds_on'))

        if os.name == 'nt':
            if gtk.pygtk_version >= (2, 10, 0) and gtk.gtk_version >= (2, 10,
                                                                       0):
                if self.added_hide_menuitem is False:
                    self.systray_context_menu.prepend(gtk.SeparatorMenuItem())
                    item = gtk.MenuItem(_('Hide this menu'))
                    self.systray_context_menu.prepend(item)
                    self.added_hide_menuitem = True

        self.systray_context_menu.show_all()
        self.systray_context_menu.popup(None, None, None, event_button,
                                        event_time)
Esempio n. 24
0
    def populate(self, contacts):
        self.create_window()

        self.create_table()
        if not contacts or len(contacts) == 0:
            # Tooltip for merged accounts row
            accounts = helpers.get_notification_icon_tooltip_dict()
            self.spacer_label = ''
            self.fill_table_with_accounts(accounts)
            self.win.add(self.table)
            return

        # primary contact
        prim_contact = gajim.contacts.get_highest_prio_contact_from_contacts(
            contacts)

        puny_jid = helpers.sanitize_filename(prim_contact.jid)
        table_size = 3

        file_ = helpers.get_avatar_path(os.path.join(gajim.AVATAR_PATH,
            puny_jid))
        if file_:
            with open(file_, 'rb') as file_data:
                pix = gtkgui_helpers.get_pixbuf_from_data(file_data.read())
            pix = gtkgui_helpers.get_scaled_pixbuf(pix, 'tooltip')
            self.avatar_image.set_from_pixbuf(pix)
            table_size = 4
        else:
            self.avatar_image.set_from_pixbuf(None)
        vcard_table = Gtk.Grid()
        vcard_table.insert_row(0)
        for i in range(0, table_size):
            vcard_table.insert_column(0)
        vcard_table.set_property('column-spacing', 2)
        vcard_current_row = 1
        properties = []

        name_markup = '<span weight="bold">' + GLib.markup_escape_text(
            prim_contact.get_shown_name()) + '</span>'
        if gajim.config.get('mergeaccounts'):
            name_markup += " <span foreground='%s'>(%s)</span>" % (
                gajim.config.get('tooltip_account_name_color'),
                GLib.markup_escape_text(prim_contact.account.name))

        if self.account and helpers.jid_is_blocked(self.account,
        prim_contact.jid):
            name_markup += _(' [blocked]')
        if self.account and \
        self.account in gajim.interface.minimized_controls and \
        prim_contact.jid in gajim.interface.minimized_controls[self.account]:
            name_markup += _(' [minimized]')
        properties.append((name_markup, None))

        num_resources = 0
        # put contacts in dict, where key is priority
        contacts_dict = {}
        for contact in contacts:
            if contact.resource:
                num_resources += 1
                if contact.priority in contacts_dict:
                    contacts_dict[int(contact.priority)].append(contact)
                else:
                    contacts_dict[int(contact.priority)] = [contact]

        if num_resources > 1:
            properties.append((_('Status: '),       ' '))
            transport = gajim.get_transport_name_from_jid(prim_contact.jid)
            if transport:
                file_path = os.path.join(helpers.get_transport_path(transport),
                    '16x16')
            else:
                iconset = gajim.config.get('iconset')
                if not iconset:
                    iconset = 'dcraven'
                file_path = os.path.join(helpers.get_iconset_path(iconset),
                    '16x16')

            contact_keys = sorted(contacts_dict.keys())
            contact_keys.reverse()
            for priority in contact_keys:
                for acontact in contacts_dict[priority]:
                    status_line = self.get_status_info(acontact.resource,
                        acontact.priority, acontact.show, acontact.status)

                    icon_name = self._get_icon_name_for_tooltip(acontact)
                    self.add_status_row(file_path, icon_name, status_line,
                        acontact.last_status_time)
            properties.append((self.table,  None))

        else: # only one resource
            if contact.show:
                show = helpers.get_uf_show(contact.show)
                if not self.check_last_time and self.account:
                    if contact.show == 'offline':
                        if not contact.last_status_time:
                            gajim.connections[self.account].\
                                request_last_status_time(contact.jid, '')
                        else:
                            self.check_last_time = contact.last_status_time
                    elif contact.resource:
                        gajim.connections[self.account].\
                            request_last_status_time(
                            contact.jid, contact.resource)
                        if contact.last_activity_time:
                            self.check_last_time = contact.last_activity_time
                else:
                    self.check_last_time = None
                if contact.last_status_time:
                    vcard_current_row += 1
                    if contact.show == 'offline':
                        text = ' - ' + _('Last status: %s')
                    else:
                        text = _(' since %s')

                    if time.strftime('%j', time.localtime()) == \
                        time.strftime('%j', contact.last_status_time):
                        # it's today, show only the locale hour representation
                        local_time = time.strftime('%X',
                            contact.last_status_time)
                    else:
                        # time.strftime returns locale encoded string
                        local_time = time.strftime('%c',
                            contact.last_status_time)

                    text = text % local_time
                    show += text
                if self.account and \
                prim_contact.jid in gajim.gc_connected[self.account]:
                    if gajim.gc_connected[self.account][prim_contact.jid]:
                        show = _('Connected')
                    else:
                        show = _('Disconnected')
                show = self.colorize_status(show)

                if contact.status:
                    status = contact.status.strip()
                    if status:
                        # reduce long status
                        # (no more than 300 chars on line and no more than
                        # 5 lines)
                        # status is wrapped
                        status = helpers.reduce_chars_newlines(status, 300, 5)
                        # escape markup entities.
                        status = GLib.markup_escape_text(status)
                        properties.append(('<i>%s</i>' % status, None))
                properties.append((show, None))

        self._append_pep_info(contact, properties)

        properties.append((_('Jabber ID: '), '\u200E' + "<b>%s</b>" % \
            prim_contact.jid))

        # contact has only one ressource
        if num_resources == 1 and contact.resource:
            properties.append((_('Resource: '), GLib.markup_escape_text(
                contact.resource) + ' (' + str(contact.priority) + ')'))

        if self.account and prim_contact.sub and prim_contact.sub != 'both' and\
        prim_contact.jid not in gajim.gc_connected[self.account]:
            # ('both' is the normal sub so we don't show it)
            properties.append(( _('Subscription: '), GLib.markup_escape_text(
                helpers.get_uf_sub(prim_contact.sub))))

        if prim_contact.keyID:
            keyID = None
            if len(prim_contact.keyID) == 8:
                keyID = prim_contact.keyID
            elif len(prim_contact.keyID) == 16:
                keyID = prim_contact.keyID[8:]
            if keyID:
                properties.append((_('OpenPGP: '), GLib.markup_escape_text(
                    keyID)))

        if contact.last_activity_time:
            last_active = datetime(*contact.last_activity_time[:6])
            current = datetime.now()

            diff = current - last_active
            diff = timedelta(diff.days, diff.seconds)

            if last_active.date() == current.date():
                formatted = last_active.strftime("%X")
            else:
                formatted = last_active.strftime("%c")

            # Do not show the "Idle since" and "Idle for" items if there
            # is no meaningful difference between last activity time and
            # current time.
            if diff.days > 0 or diff.seconds > 0:
                cs = "<span foreground='%s'>" % gajim.config.get(
                    'tooltip_idle_color')
                cs += '%s</span>'
                properties.append((str(), None))
                idle_since = cs % _("Idle since %s")
                properties.append((idle_since % formatted, None))
                idle_for = cs % _("Idle for %s")
                properties.append((idle_for % str(diff), None))

        while properties:
            property_ = properties.pop(0)
            vcard_current_row += 1
            label = Gtk.Label()
            if not properties and table_size == 4:
                label.set_vexpand(True)
            label.set_alignment(0, 0)
            if property_[1]:
                label.set_markup(property_[0])
                vcard_table.attach(label, 1, vcard_current_row, 1, 1)
                label = Gtk.Label()
                if not properties and table_size == 4:
                    label.set_vexpand(True)
                label.set_alignment(0, 0)
                label.set_markup(property_[1])
                label.set_line_wrap(True)
                vcard_table.attach(label, 2, vcard_current_row, 1, 1)
            else:
                if isinstance(property_[0], str):
                    label.set_markup(property_[0])
                    label.set_line_wrap(True)
                else:
                    label = property_[0]
                vcard_table.attach(label, 1, vcard_current_row, 2, 1)
        self.avatar_image.set_alignment(0, 0)
        if table_size == 4:
            vcard_table.attach(self.avatar_image, 3, 2, 1, vcard_current_row - 1)

        gajim.plugin_manager.gui_extension_point('roster_tooltip_populate',
            self, contacts, vcard_table)
        self.win.add(vcard_table)
Esempio n. 25
0
    def make_menu(self, event_button, event_time):
        """
        Create chat with and new message (sub) menus/menuitems
        """
        for m in self.popup_menus:
            m.destroy()

        chat_with_menuitem = self.xml.get_object('chat_with_menuitem')
        single_message_menuitem = self.xml.get_object(
                'single_message_menuitem')
        status_menuitem = self.xml.get_object('status_menu')
        join_gc_menuitem = self.xml.get_object('join_gc_menuitem')
        sounds_mute_menuitem = self.xml.get_object('sounds_mute_menuitem')
        show_roster_menuitem = self.xml.get_object('show_roster_menuitem')

        if self.single_message_handler_id:
            single_message_menuitem.handler_disconnect(
                    self.single_message_handler_id)
            self.single_message_handler_id = None
        if self.new_chat_handler_id:
            chat_with_menuitem.disconnect(self.new_chat_handler_id)
            self.new_chat_handler_id = None

        sub_menu = Gtk.Menu()
        self.popup_menus.append(sub_menu)
        status_menuitem.set_submenu(sub_menu)

        gc_sub_menu = Gtk.Menu() # gc is always a submenu
        join_gc_menuitem.set_submenu(gc_sub_menu)

        # We need our own set of status icons, let's make 'em!
        iconset = gajim.config.get('iconset')
        path = os.path.join(helpers.get_iconset_path(iconset), '16x16')

        for show in ('online', 'chat', 'away', 'xa', 'dnd', 'invisible'):
            uf_show = helpers.get_uf_show(show, use_mnemonic=True)
            item = Gtk.MenuItem.new_with_mnemonic(uf_show)
            sub_menu.append(item)
            item.connect('activate', self.on_show_menuitem_activate, show)

        item = Gtk.SeparatorMenuItem.new()
        sub_menu.append(item)

        item = Gtk.MenuItem.new_with_mnemonic(_('_Change Status Message…'))
        sub_menu.append(item)
        item.connect('activate', self.on_change_status_message_activate)

        connected_accounts = gajim.get_number_of_connected_accounts()
        if connected_accounts < 1:
            item.set_sensitive(False)

        connected_accounts_with_private_storage = 0

        item = Gtk.SeparatorMenuItem.new()
        sub_menu.append(item)

        uf_show = helpers.get_uf_show('offline', use_mnemonic=True)
        item = Gtk.MenuItem.new_with_mnemonic(uf_show)
        sub_menu.append(item)
        item.connect('activate', self.on_show_menuitem_activate, 'offline')

        iskey = connected_accounts > 0 and not (connected_accounts == 1 and
            gajim.zeroconf_is_connected())
        chat_with_menuitem.set_sensitive(iskey)
        single_message_menuitem.set_sensitive(iskey)
        join_gc_menuitem.set_sensitive(iskey)

        accounts_list = sorted(gajim.contacts.get_accounts())
        # items that get shown whether an account is zeroconf or not
        if connected_accounts > 1: # 2 or more connections? make submenus
            account_menu_for_chat_with = Gtk.Menu()
            chat_with_menuitem.set_submenu(account_menu_for_chat_with)
            self.popup_menus.append(account_menu_for_chat_with)

            for account in accounts_list:
                if gajim.account_is_connected(account):
                    # for chat_with
                    item = Gtk.MenuItem.new_with_label(
                        _('using account %s') % account)
                    account_menu_for_chat_with.append(item)
                    item.connect('activate', self.on_new_chat, account)

        elif connected_accounts == 1: # one account
            # one account connected, no need to show 'as jid'
            for account in gajim.connections:
                if gajim.connections[account].connected > 1:
                    # for start chat
                    self.new_chat_handler_id = chat_with_menuitem.connect(
                            'activate', self.on_new_chat, account)
                    break # No other connected account

        # menu items that don't apply to zeroconf connections
        if connected_accounts == 1 or (connected_accounts == 2 and \
        gajim.zeroconf_is_connected()):
            # only one 'real' (non-zeroconf) account is connected, don't need
            # submenus
            for account in gajim.connections:
                if gajim.account_is_connected(account) and \
                not gajim.config.get_per('accounts', account, 'is_zeroconf'):
                    if gajim.connections[account].private_storage_supported:
                        connected_accounts_with_private_storage += 1

                    # for single message
                    single_message_menuitem.set_submenu(None)
                    self.single_message_handler_id = single_message_menuitem.\
                            connect('activate',
                            self.on_single_message_menuitem_activate, account)
                    # join gc
                    gajim.interface.roster.add_bookmarks_list(gc_sub_menu,
                            account)
                    break # No other account connected
        else:
            # 2 or more 'real' accounts are connected, make submenus
            account_menu_for_single_message = Gtk.Menu()
            single_message_menuitem.set_submenu(
                    account_menu_for_single_message)
            self.popup_menus.append(account_menu_for_single_message)

            for account in accounts_list:
                if gajim.connections[account].is_zeroconf or \
                not gajim.account_is_connected(account):
                    continue
                if gajim.connections[account].private_storage_supported:
                    connected_accounts_with_private_storage += 1
                # for single message
                item = Gtk.MenuItem.new_with_label(
                    _('using account %s') % account)
                item.connect('activate',
                        self.on_single_message_menuitem_activate, account)
                account_menu_for_single_message.append(item)

                # join gc
                gc_item = Gtk.MenuItem.new_with_label(
                    _('using account %s') % account)
                gc_sub_menu.append(gc_item)
                gc_menuitem_menu = Gtk.Menu()
                gajim.interface.roster.add_bookmarks_list(gc_menuitem_menu,
                        account)
                gc_item.set_submenu(gc_menuitem_menu)
                gc_sub_menu.show_all()

        newitem = Gtk.SeparatorMenuItem.new() # separator
        gc_sub_menu.append(newitem)
        newitem = Gtk.MenuItem.new_with_mnemonic(_('_Manage Bookmarks…'))
        newitem.connect('activate',
            gajim.interface.roster.on_manage_bookmarks_menuitem_activate)
        gc_sub_menu.append(newitem)
        if connected_accounts_with_private_storage == 0:
            newitem.set_sensitive(False)

        sounds_mute_menuitem.set_active(not gajim.config.get('sounds_on'))

        win = gajim.interface.roster.window
        if self.show_roster_handler_id:
            show_roster_menuitem.handler_disconnect(self.show_roster_handler_id)
        if win.get_property('has-toplevel-focus'):
            show_roster_menuitem.get_children()[0].set_label(_('Hide _Roster'))
            self.show_roster_handler_id = show_roster_menuitem.connect(
                'activate', self.on_hide_roster_menuitem_activate)
        else:
            show_roster_menuitem.get_children()[0].set_label(_('Show _Roster'))
            self.show_roster_handler_id = show_roster_menuitem.connect(
                'activate', self.on_show_roster_menuitem_activate)

        if os.name == 'nt':
            if self.added_hide_menuitem is False:
                self.systray_context_menu.prepend(Gtk.SeparatorMenuItem.new())
                item = Gtk.MenuItem.new_with_label(
                    _('Hide this menu'))
                self.systray_context_menu.prepend(item)
                self.added_hide_menuitem = True

        self.systray_context_menu.show_all()
        self.systray_context_menu.popup(None, None, None, None, 0, event_time)
Esempio n. 26
0
def notify(event, jid, account, parameters, advanced_notif_num=None):
	'''Check what type of notifications we want, depending on basic
	and the advanced configuration of notifications and do these notifications;
	advanced_notif_num holds the number of the first (top most) advanced
	notification'''
	# First, find what notifications we want
	do_popup = False
	do_sound = False
	do_cmd = False
	if event == 'status_change':
		new_show = parameters[0]
		status_message = parameters[1]
		# Default: No popup for status change
	elif event == 'contact_connected':
		status_message = parameters
		j = gajim.get_jid_without_resource(jid)
		server = gajim.get_server_from_jid(j)
		account_server = account + '/' + server
		block_transport = False
		if account_server in gajim.block_signed_in_notifications and \
		gajim.block_signed_in_notifications[account_server]:
			block_transport = True
		if helpers.allow_showing_notification(account, 'notify_on_signin') and \
		not gajim.block_signed_in_notifications[account] and not block_transport:
			do_popup = True
		if gajim.config.get_per('soundevents', 'contact_connected',
		'enabled') and not gajim.block_signed_in_notifications[account] and \
		not block_transport:
			do_sound = True
	elif event == 'contact_disconnected':
		status_message = parameters
		if helpers.allow_showing_notification(account, 'notify_on_signout'):
			do_popup = True
		if gajim.config.get_per('soundevents', 'contact_disconnected',
			'enabled'):
			do_sound = True
	elif event == 'new_message':
		message_type = parameters[0]
		is_first_message = parameters[1]
		nickname = parameters[2]
		if gajim.config.get('notification_preview_message'):
			message = parameters[3]
			if message.startswith('/me ') or message.startswith('/me\n'):
				message = '* ' + nickname + message[3:]
		else:
			# We don't want message preview, do_preview = False
			message = ''
		focused = parameters[4]
		if helpers.allow_showing_notification(account, 'notify_on_new_message',
		advanced_notif_num, is_first_message):
			do_popup = True
		if is_first_message and helpers.allow_sound_notification(
		'first_message_received', advanced_notif_num):
			do_sound = True
		elif not is_first_message and focused and \
		helpers.allow_sound_notification('next_message_received_focused',
		advanced_notif_num):
			do_sound = True
		elif not is_first_message and not focused and \
		helpers.allow_sound_notification('next_message_received_unfocused',
		advanced_notif_num):
			do_sound = True
	else:
		print '*Event not implemeted yet*'

	if advanced_notif_num is not None and gajim.config.get_per('notifications',
	str(advanced_notif_num), 'run_command'):
		do_cmd = True

	# Do the wanted notifications
	if do_popup:
		if event in ('contact_connected', 'contact_disconnected',
		'status_change'): # Common code for popup for these three events
			if event == 'contact_disconnected':
				show_image = 'offline.png'
				suffix = '_notif_size_bw'
			else: #Status Change or Connected
				# FIXME: for status change,
				# we don't always 'online.png', but we
				# first need 48x48 for all status
				show_image = 'online.png'
				suffix = '_notif_size_colored'
			transport_name = gajim.get_transport_name_from_jid(jid)
			img = None
			if transport_name:
				img = os.path.join(helpers.get_transport_path(transport_name),
					'48x48', show_image)
			if not img or not os.path.isfile(img):
				iconset = gajim.config.get('iconset')
				img = os.path.join(helpers.get_iconset_path(iconset), '48x48',
					show_image)
			path = gtkgui_helpers.get_path_to_generic_or_avatar(img,
				jid = jid, suffix = suffix)
			if event == 'status_change':
				title = _('%(nick)s Changed Status') % \
					{'nick': gajim.get_name_from_jid(account, jid)}
				text = _('%(nick)s is now %(status)s') % \
					{'nick': gajim.get_name_from_jid(account, jid),\
					'status': helpers.get_uf_show(gajim.SHOW_LIST[new_show])}
				if status_message:
					text = text + " : " + status_message
				popup(_('Contact Changed Status'), jid, account,
					path_to_image=path, title=title, text=text)
			elif event == 'contact_connected':
				title = _('%(nickname)s Signed In') % \
					{'nickname': gajim.get_name_from_jid(account, jid)}
				text = ''
				if status_message:
					text = status_message
				popup(_('Contact Signed In'), jid, account,
					path_to_image=path, title=title, text=text)
			elif event == 'contact_disconnected':
				title = _('%(nickname)s Signed Out') % \
					{'nickname': gajim.get_name_from_jid(account, jid)}
				text = ''
				if status_message:
					text = status_message
				popup(_('Contact Signed Out'), jid, account,
					path_to_image=path, title=title, text=text)
		elif event == 'new_message':
			if message_type == 'normal': # single message
				event_type = _('New Single Message')
				img = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events',
					'single_msg_recv.png')
				title = _('New Single Message from %(nickname)s') % \
					{'nickname': nickname}
				text = message
			elif message_type == 'pm': # private message
				event_type = _('New Private Message')
				room_name = gajim.get_nick_from_jid(jid)
				img = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events',
					'priv_msg_recv.png')
				title = _('New Private Message from group chat %s') % room_name
				if message:
					text = _('%(nickname)s: %(message)s') % {'nickname': nickname,
						'message': message}
				else:
					text = _('Messaged by %(nickname)s') % {'nickname': nickname}

			else: # chat message
				event_type = _('New Message')
				img = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events',
					'chat_msg_recv.png')
				title = _('New Message from %(nickname)s') % \
					{'nickname': nickname}
				text = message
			path = gtkgui_helpers.get_path_to_generic_or_avatar(img)
			popup(event_type, jid, account, message_type,
				path_to_image=path, title=title, text=text)

	if do_sound:
		snd_file = None
		snd_event = None # If not snd_file, play the event
		if event == 'new_message':
			if advanced_notif_num is not None and gajim.config.get_per(
			'notifications', str(advanced_notif_num), 'sound') == 'yes':
				snd_file = gajim.config.get_per('notifications',
					str(advanced_notif_num), 'sound_file')
			elif advanced_notif_num is not None and gajim.config.get_per(
			'notifications', str(advanced_notif_num), 'sound') == 'no':
				pass # do not set snd_event
			elif is_first_message:
				snd_event = 'first_message_received'
			elif focused:
				snd_event = 'next_message_received_focused'
			else:
				snd_event = 'next_message_received_unfocused'
		elif event in ('contact_connected', 'contact_disconnected'):
			snd_event = event
		if snd_file:
			helpers.play_sound_file(snd_file)
		if snd_event:
			helpers.play_sound(snd_event)

	if do_cmd:
		command = gajim.config.get_per('notifications', str(advanced_notif_num),
			'command')
		try:
			helpers.exec_command(command)
		except Exception:
			pass
Esempio n. 27
0
    def populate(self, contacts):
        self.create_window()

        self.create_table()
        if not contacts or len(contacts) == 0:
            # Tooltip for merged accounts row
            accounts = helpers.get_notification_icon_tooltip_dict()
            self.spacer_label = ''
            self.fill_table_with_accounts(accounts)
            self.win.add(self.table)
            return

        # primary contact
        prim_contact = gajim.contacts.get_highest_prio_contact_from_contacts(
            contacts)

        puny_jid = helpers.sanitize_filename(prim_contact.jid)
        table_size = 3

        file_ = helpers.get_avatar_path(os.path.join(gajim.AVATAR_PATH,
            puny_jid))
        if file_:
            with open(file_, 'rb') as file_data:
                pix = gtkgui_helpers.get_pixbuf_from_data(file_data.read())
            pix = gtkgui_helpers.get_scaled_pixbuf(pix, 'tooltip')
            self.avatar_image.set_from_pixbuf(pix)
            table_size = 4
        else:
            self.avatar_image.set_from_pixbuf(None)
        vcard_table = Gtk.Grid()
        vcard_table.insert_row(0)
        for i in range(0, table_size):
            vcard_table.insert_column(0)
        vcard_table.set_property('column-spacing', 2)
        vcard_current_row = 1
        properties = []

        name_markup = '<span weight="bold">' + GLib.markup_escape_text(
            prim_contact.get_shown_name()) + '</span>'
        if gajim.config.get('mergeaccounts'):
            name_markup += " <span foreground='%s'>(%s)</span>" % (
                gajim.config.get('tooltip_account_name_color'),
                GLib.markup_escape_text(prim_contact.account.name))

        if self.account and helpers.jid_is_blocked(self.account,
        prim_contact.jid):
            name_markup += _(' [blocked]')
        if self.account and \
        self.account in gajim.interface.minimized_controls and \
        prim_contact.jid in gajim.interface.minimized_controls[self.account]:
            name_markup += _(' [minimized]')
        properties.append((name_markup, None))

        num_resources = 0
        # put contacts in dict, where key is priority
        contacts_dict = {}
        for contact in contacts:
            if contact.resource:
                num_resources += 1
                if contact.priority in contacts_dict:
                    contacts_dict[int(contact.priority)].append(contact)
                else:
                    contacts_dict[int(contact.priority)] = [contact]

        if num_resources > 1:
            properties.append((_('Status: '),       ' '))
            transport = gajim.get_transport_name_from_jid(prim_contact.jid)
            if transport:
                file_path = os.path.join(helpers.get_transport_path(transport),
                    '16x16')
            else:
                iconset = gajim.config.get('iconset')
                if not iconset:
                    iconset = 'dcraven'
                file_path = os.path.join(helpers.get_iconset_path(iconset),
                    '16x16')

            contact_keys = sorted(contacts_dict.keys())
            contact_keys.reverse()
            for priority in contact_keys:
                for acontact in contacts_dict[priority]:
                    status_line = self.get_status_info(acontact.resource,
                        acontact.priority, acontact.show, acontact.status)

                    icon_name = self._get_icon_name_for_tooltip(acontact)
                    self.add_status_row(file_path, icon_name, status_line,
                        acontact.last_status_time)
            properties.append((self.table,  None))

        else: # only one resource
            if contact.show:
                show = helpers.get_uf_show(contact.show)
                if not self.check_last_time and self.account:
                    if contact.show == 'offline':
                        if not contact.last_status_time:
                            gajim.connections[self.account].\
                                request_last_status_time(contact.jid, '')
                        else:
                            self.check_last_time = contact.last_status_time
                    elif contact.resource:
                        gajim.connections[self.account].\
                            request_last_status_time(
                            contact.jid, contact.resource)
                        if contact.last_activity_time:
                            self.check_last_time = contact.last_activity_time
                else:
                    self.check_last_time = None
                if contact.last_status_time:
                    vcard_current_row += 1
                    if contact.show == 'offline':
                        text = ' - ' + _('Last status: %s')
                    else:
                        text = _(' since %s')

                    if time.strftime('%j', time.localtime()) == \
                        time.strftime('%j', contact.last_status_time):
                        # it's today, show only the locale hour representation
                        local_time = time.strftime('%X',
                            contact.last_status_time)
                    else:
                        # time.strftime returns locale encoded string
                        local_time = time.strftime('%c',
                            contact.last_status_time)

                    text = text % local_time
                    show += text
                if self.account and \
                prim_contact.jid in gajim.gc_connected[self.account]:
                    if gajim.gc_connected[self.account][prim_contact.jid]:
                        show = _('Connected')
                    else:
                        show = _('Disconnected')
                show = self.colorize_status(show)

                if contact.status:
                    status = contact.status.strip()
                    if status:
                        # reduce long status
                        # (no more than 300 chars on line and no more than
                        # 5 lines)
                        # status is wrapped
                        status = helpers.reduce_chars_newlines(status, 300, 5)
                        # escape markup entities.
                        status = GLib.markup_escape_text(status)
                        properties.append(('<i>%s</i>' % status, None))
                properties.append((show, None))

        self._append_pep_info(contact, properties)

        properties.append((_('Jabber ID: '), '\u200E' + "<b>%s</b>" % \
            prim_contact.jid))

        # contact has only one ressource
        if num_resources == 1 and contact.resource:
            properties.append((_('Resource: '), GLib.markup_escape_text(
                contact.resource) + ' (' + str(contact.priority) + ')'))

        if self.account and prim_contact.sub and prim_contact.sub != 'both' and\
        prim_contact.jid not in gajim.gc_connected[self.account]:
            # ('both' is the normal sub so we don't show it)
            properties.append(( _('Subscription: '), GLib.markup_escape_text(
                helpers.get_uf_sub(prim_contact.sub))))

        if prim_contact.keyID:
            keyID = None
            if len(prim_contact.keyID) == 8:
                keyID = prim_contact.keyID
            elif len(prim_contact.keyID) == 16:
                keyID = prim_contact.keyID[8:]
            if keyID:
                properties.append((_('OpenPGP: '), GLib.markup_escape_text(
                    keyID)))

        if contact.last_activity_time:
            last_active = datetime(*contact.last_activity_time[:6])
            current = datetime.now()

            diff = current - last_active
            diff = timedelta(diff.days, diff.seconds)

            if last_active.date() == current.date():
                formatted = last_active.strftime("%X")
            else:
                formatted = last_active.strftime("%c")

            # Do not show the "Idle since" and "Idle for" items if there
            # is no meaningful difference between last activity time and
            # current time.
            if diff.days > 0 or diff.seconds > 0:
                cs = "<span foreground='%s'>" % gajim.config.get(
                    'tooltip_idle_color')
                cs += '%s</span>'
                properties.append((str(), None))
                idle_since = cs % _("Idle since %s")
                properties.append((idle_since % formatted, None))
                idle_for = cs % _("Idle for %s")
                properties.append((idle_for % str(diff), None))

        while properties:
            property_ = properties.pop(0)
            vcard_current_row += 1
            label = Gtk.Label()
            if not properties and table_size == 4:
                label.set_vexpand(True)
            label.set_halign(Gtk.Align.START)
            label.set_valign(Gtk.Align.START)
            if property_[1]:
                label.set_markup(property_[0])
                vcard_table.attach(label, 1, vcard_current_row, 1, 1)
                label = Gtk.Label()
                if not properties and table_size == 4:
                    label.set_vexpand(True)
                label.set_halign(Gtk.Align.START)
                label.set_valign(Gtk.Align.START)
                label.set_markup(property_[1])
                label.set_line_wrap(True)
                vcard_table.attach(label, 2, vcard_current_row, 1, 1)
            else:
                if isinstance(property_[0], str):
                    label.set_markup(property_[0])
                    label.set_line_wrap(True)
                else:
                    label = property_[0]
                vcard_table.attach(label, 1, vcard_current_row, 2, 1)
        self.avatar_image.set_halign(Gtk.Align.START)
        self.avatar_image.set_valign(Gtk.Align.START)
        if table_size == 4:
            vcard_table.attach(self.avatar_image, 3, 2, 1, vcard_current_row - 1)

        gajim.plugin_manager.gui_extension_point('roster_tooltip_populate',
            self, contacts, vcard_table)
        self.win.add(vcard_table)
Esempio n. 28
0
	def make_menu(self, event_button, event_time):
		'''create chat with and new message (sub) menus/menuitems'''
		for m in self.popup_menus:
			m.destroy()

		chat_with_menuitem = self.xml.get_widget('chat_with_menuitem')
		single_message_menuitem = self.xml.get_widget(
			'single_message_menuitem')
		status_menuitem = self.xml.get_widget('status_menu')
		join_gc_menuitem = self.xml.get_widget('join_gc_menuitem')
		sounds_mute_menuitem = self.xml.get_widget('sounds_mute_menuitem')

		if self.single_message_handler_id:
			single_message_menuitem.handler_disconnect(
				self.single_message_handler_id)
			self.single_message_handler_id = None
		if self.new_chat_handler_id:
			chat_with_menuitem.disconnect(self.new_chat_handler_id)
			self.new_chat_handler_id = None

		sub_menu = gtk.Menu()
		self.popup_menus.append(sub_menu)
		status_menuitem.set_submenu(sub_menu)

		gc_sub_menu = gtk.Menu() # gc is always a submenu
		join_gc_menuitem.set_submenu(gc_sub_menu)

		# We need our own set of status icons, let's make 'em!
		iconset = gajim.config.get('iconset')
		path = os.path.join(helpers.get_iconset_path(iconset), '16x16')
		state_images = gtkgui_helpers.load_iconset(path)

		if 'muc_active' in state_images:
			join_gc_menuitem.set_image(state_images['muc_active'])

		for show in ('online', 'chat', 'away', 'xa', 'dnd', 'invisible'):
			uf_show = helpers.get_uf_show(show, use_mnemonic = True)
			item = gtk.ImageMenuItem(uf_show)
			item.set_image(state_images[show])
			sub_menu.append(item)
			if os.name == 'nt':
				#FIXME: bug in pygtk, activate is not called.
				# see http://trac.gajim.org/ticket/4310
				item.connect('button_press_event',
					self.on_show_menuitem_activate2, show)
			else:
				item.connect('activate', self.on_show_menuitem_activate, show)

		item = gtk.SeparatorMenuItem()
		sub_menu.append(item)

		item = gtk.ImageMenuItem(_('_Change Status Message...'))
		path = os.path.join(gajim.DATA_DIR, 'pixmaps', 'kbd_input.png')
		img = gtk.Image()
		img.set_from_file(path)
		item.set_image(img)
		sub_menu.append(item)
		if os.name == 'nt':
			#FIXME: bug in pygtk, activate is not called.
			# see http://trac.gajim.org/ticket/4310
			item.connect('button_press_event',
				self.on_change_status_message_activate2)
		else:
			item.connect('activate', self.on_change_status_message_activate)

		connected_accounts = gajim.get_number_of_connected_accounts()
		if connected_accounts < 1:
			item.set_sensitive(False)

		item = gtk.SeparatorMenuItem()
		sub_menu.append(item)

		uf_show = helpers.get_uf_show('offline', use_mnemonic = True)
		item = gtk.ImageMenuItem(uf_show)
		item.set_image(state_images['offline'])
		sub_menu.append(item)
		if os.name == 'nt':
			#FIXME: bug in pygtk, activate is not called.
			# see http://trac.gajim.org/ticket/4310
			item.connect('button_press_event',
				self.on_show_menuitem_activate2, 'offline')
		else:
			item.connect('activate', self.on_show_menuitem_activate, 'offline')

		iskey = connected_accounts > 0 and not (connected_accounts == 1 and
				gajim.connections[gajim.connections.keys()[0]].is_zeroconf)
		chat_with_menuitem.set_sensitive(iskey)
		single_message_menuitem.set_sensitive(iskey)
		join_gc_menuitem.set_sensitive(iskey)

		if connected_accounts >= 2: # 2 or more connections? make submenus
			account_menu_for_chat_with = gtk.Menu()
			chat_with_menuitem.set_submenu(account_menu_for_chat_with)
			self.popup_menus.append(account_menu_for_chat_with)

			account_menu_for_single_message = gtk.Menu()
			single_message_menuitem.set_submenu(
				account_menu_for_single_message)
			self.popup_menus.append(account_menu_for_single_message)

			accounts_list = sorted(gajim.contacts.get_accounts())
			for account in accounts_list:
				if gajim.connections[account].is_zeroconf:
					continue
				if gajim.connections[account].connected > 1:
					# for chat_with
					item = gtk.MenuItem(_('using account %s') % account)
					account_menu_for_chat_with.append(item)
					if os.name == 'nt':
						#FIXME: bug in pygtk, activate is not called.
						# see http://trac.gajim.org/ticket/4310
						item.connect('button_press_event',
							self.on_new_chat2, account)
					else:
						item.connect('activate', self.on_new_chat, account)

					# for single message
					item = gtk.MenuItem(_('using account %s') % account)
					if os.name == 'nt':
						#FIXME: bug in pygtk, activate is not called.
						# see http://trac.gajim.org/ticket/4310
						item.connect('button_press_event',
							self.on_single_message_menuitem_activate2, account)
					else:
						item.connect('activate',
							self.on_single_message_menuitem_activate, account)
					account_menu_for_single_message.append(item)

					# join gc 
					gc_item = gtk.MenuItem(_('using account %s') % account, False)
					gc_sub_menu.append(gc_item)
					gc_menuitem_menu = gtk.Menu()
					if os.name == 'nt':
						#FIXME: bug in pygtk, activate is not called.
						# see http://trac.gajim.org/ticket/4310
						self.add_bookmarks_list2(gc_menuitem_menu, account)
					else:
						gajim.interface.roster.add_bookmarks_list(gc_menuitem_menu,
							account)
					gc_item.set_submenu(gc_menuitem_menu)
					gc_sub_menu.show_all()

		elif connected_accounts == 1: # one account
			# one account connected, no need to show 'as jid'
			for account in gajim.connections:
				if gajim.connections[account].connected > 1:
					self.new_chat_handler_id = chat_with_menuitem.connect(
							'activate', self.on_new_chat, account)
					# for single message
					single_message_menuitem.remove_submenu()
					self.single_message_handler_id = single_message_menuitem.\
						connect('activate',
						self.on_single_message_menuitem_activate, account)

					# join gc
					if os.name == 'nt':
						#FIXME: bug in pygtk, activate is not called.
						# see http://trac.gajim.org/ticket/4310
						self.add_bookmarks_list2(gc_sub_menu, account)
					else:
						gajim.interface.roster.add_bookmarks_list(gc_sub_menu,
							account)
					break # No other connected account

		newitem = gtk.SeparatorMenuItem() # separator
		gc_sub_menu.append(newitem)
		newitem = gtk.ImageMenuItem(_('_Manage Bookmarks...'))
		img = gtk.image_new_from_stock(gtk.STOCK_PREFERENCES, gtk.ICON_SIZE_MENU)
		newitem.set_image(img)
		if os.name == 'nt':
			#FIXME: bug in pygtk, activate is not called.
			# see http://trac.gajim.org/ticket/4310
			newitem.connect('button_press_event',
				self.on_manage_bookmarks_menuitem_activate2)
		else:
			newitem.connect('activate',
				gajim.interface.roster.on_manage_bookmarks_menuitem_activate)
		gc_sub_menu.append(newitem)

		sounds_mute_menuitem.set_active(not gajim.config.get('sounds_on'))

		if os.name == 'nt':
			if gtk.pygtk_version >= (2, 10, 0) and gtk.gtk_version >= (2, 10, 0):
				if self.added_hide_menuitem is False:
					self.systray_context_menu.prepend(gtk.SeparatorMenuItem())
					item = gtk.MenuItem(_('Hide this menu'))
					self.systray_context_menu.prepend(item)
					self.added_hide_menuitem = True

		self.systray_context_menu.show_all()
		self.systray_context_menu.popup(None, None, None, event_button,
			event_time)