Example #1
0
    def fill_status_label(self):
        if self.xml.get_object('information_notebook').get_n_pages() < 2:
            return
        contact_list = gajim.contacts.get_contacts(self.account, self.contact.jid)
        # stats holds show and status message
        stats = ''
        one = True # Are we adding the first line ?
        if contact_list:
            for c in contact_list:
                if not one:
                    stats += '\n'
                stats += helpers.get_uf_show(c.show)
                if c.status:
                    stats += ': ' + c.status
                if c.last_status_time:
                    stats += '\n' + _('since %s') % time.strftime('%c',
                            c.last_status_time).decode(locale.getpreferredencoding())
                one = False
        else: # Maybe gc_vcard ?
            stats = helpers.get_uf_show(self.contact.show)
            if self.contact.status:
                stats += ': ' + self.contact.status
        status_label = self.xml.get_object('status_label')
        status_label.set_max_width_chars(15)
        status_label.set_text(stats)

        status_label_eventbox = self.xml.get_object('status_label_eventbox')
        status_label_eventbox.set_tooltip_text(stats)
Example #2
0
    def fill_status_label(self):
        if self.xml.get_object('information_notebook').get_n_pages() < 2:
            return
        contact_list = gajim.contacts.get_contacts(self.account,
                                                   self.contact.jid)
        # stats holds show and status message
        stats = ''
        one = True  # Are we adding the first line ?
        if contact_list:
            for c in contact_list:
                if not one:
                    stats += '\n'
                stats += helpers.get_uf_show(c.show)
                if c.status:
                    stats += ': ' + c.status
                if c.last_status_time:
                    stats += '\n' + _('since %s') % time.strftime(
                        '%c', c.last_status_time).decode(
                            locale.getpreferredencoding())
                one = False
        else:  # Maybe gc_vcard ?
            stats = helpers.get_uf_show(self.contact.show)
            if self.contact.status:
                stats += ': ' + self.contact.status
        status_label = self.xml.get_object('status_label')
        status_label.set_max_width_chars(15)
        status_label.set_text(stats)

        status_label_eventbox = self.xml.get_object('status_label_eventbox')
        status_label_eventbox.set_tooltip_text(stats)
Example #3
0
    def populate(self, contact):
        if not contact:
            return
        self.create_window()
        hbox = gtk.HBox()

        if contact.jid.strip() != "":
            info = '<span size="large" weight="bold">' + contact.jid + "</span>"
        else:
            info = '<span size="large" weight="bold">' + contact.name + "</span>"

        info += '\n<span weight="bold">' + _("Role: ") + "</span>" + helpers.get_uf_role(contact.role)

        info += '\n<span weight="bold">' + _("Affiliation: ") + "</span>" + contact.affiliation.capitalize()

        info += '\n<span weight="bold">' + _("Status: ") + "</span>" + helpers.get_uf_show(contact.show)

        if contact.status:
            status = contact.status.strip()
            if status != "":
                # escape markup entities
                info += " - " + gtkgui_helpers.escape_for_pango_markup(status)

        if contact.resource.strip() != "":
            info += (
                '\n<span weight="bold">'
                + _("Resource: ")
                + "</span>"
                + gtkgui_helpers.escape_for_pango_markup(contact.resource)
            )

        self.text_label.set_markup(info)
        hbox.add(self.text_label)
        self.win.add(hbox)
Example #4
0
	def __init__(self, show = None):
		self.show = show
		self.xml = gtk.glade.XML(GTKGUI_GLADE, 'change_status_message_dialog', APP)
		self.window = self.xml.get_widget('change_status_message_dialog')
		if show:
			uf_show = helpers.get_uf_show(show)
			title_text = _('%s Status Message') % uf_show
		else:
			title_text = _('Status Message')
		self.window.set_title(title_text)
		
		message_textview = self.xml.get_widget('message_textview')
		self.message_buffer = message_textview.get_buffer()
		msg = None
		if show:
			msg = gajim.config.get('last_status_msg_' + show)
		if not msg:
			msg = ''
		msg = helpers.from_one_line(msg)
		self.message_buffer.set_text(msg)
		self.values = {'':''} # have an empty string selectable, so user can clear msg
		for msg in gajim.config.get_per('statusmsg'):
			val = gajim.config.get_per('statusmsg', msg, 'message')
			val = helpers.from_one_line(val)
			self.values[msg] = val
		sorted_keys_list = helpers.get_sorted_keys(self.values)
		liststore = gtk.ListStore(str, str)
		message_comboboxentry = self.xml.get_widget('message_comboboxentry')
		message_comboboxentry.set_model(liststore)
		message_comboboxentry.set_text_column(0)
		message_comboboxentry.child.set_property('editable', False)
		for val in sorted_keys_list:
			message_comboboxentry.append_text(val)
		self.xml.signal_autoconnect(self)
		self.window.show_all()
Example #5
0
	def _fill_logs_listview(self, jid):
		'''fill the listview with all messages that user sent to or
		received from JID'''
		# no need to lower jid in this context as jid is already lowered
		# as we use those jids from db
		jid_id = self._get_jid_id(jid)
		self.cur.execute('''
			SELECT log_line_id, jid_id, time, kind, message, subject, contact_name, show
			FROM logs
			WHERE jid_id = ?
			ORDER BY time
			''', (jid_id,))

		results = self.cur.fetchall()
		
		if self._jid_is_room_type(jid): # is it room?
			self.nickname_col_for_logs.set_visible(True)
			self.subject_col_for_logs.set_visible(False)
		else:
			self.nickname_col_for_logs.set_visible(False)
			self.subject_col_for_logs.set_visible(True)

		for row in results:
			# exposed in UI (TreeViewColumns) are only
			# time, message, subject, nickname
			# but store in liststore
			# log_line_id, jid_id, time, message, subject, nickname
			log_line_id, jid_id, time_, kind, message, subject, nickname, show = row
			try:
				time_ = time.strftime('%x', time.localtime(float(time_))).decode(
					locale.getpreferredencoding())
			except ValueError:
				pass
			else:
				color = None
				if kind in (constants.KIND_SINGLE_MSG_RECV,
				constants.KIND_CHAT_MSG_RECV, constants.KIND_GC_MSG):
					# it is the other side
					color = gajim.config.get('inmsgcolor') # so incoming color
				elif kind in (constants.KIND_SINGLE_MSG_SENT,
				constants.KIND_CHAT_MSG_SENT): # it is us
					color = gajim.config.get('outmsgcolor') # so outgoing color
				elif kind in (constants.KIND_STATUS,
				constants.KIND_GCSTATUS): # is is statuses
					color = gajim.config.get('statusmsgcolor') # so status color
					# include status into (status) message
					if message is None:
						message = ''
					else:
						message = ' : ' + message 
					message = helpers.get_uf_show(gajim.SHOW_LIST[show]) + message

				message_ = '<span'
				if color:
					message_ += ' foreground="%s"' % color
				message_ += '>%s</span>' % \
					gobject.markup_escape_text(message)
				self.logs_liststore.append((log_line_id, jid_id, time_, message_,
					subject, nickname))
Example #6
0
    def fill_status_label(self):
        if self.xml.get_widget('information_notebook').get_n_pages() < 5:
            return
        contact_list = gajim.contacts.get_contacts(self.account,
                                                   self.contact.jid)
        connected_contact_list = []
        for c in contact_list:
            if c.show not in ('offline', 'error'):
                connected_contact_list.append(c)
        if not connected_contact_list:
            # no connected contact, get the offline one
            connected_contact_list = contact_list
        # stats holds show and status message
        stats = ''
        if connected_contact_list:
            # Start with self.contact, as with resources
            stats = helpers.get_uf_show(self.contact.show)
            if self.contact.status:
                stats += ': ' + self.contact.status
            if self.contact.last_status_time:
                stats += '\n' + _('since %s') % time.strftime(
                    '%c', self.contact.last_status_time).decode(
                        locale.getpreferredencoding())
            for c in connected_contact_list:
                if c.resource != self.contact.resource:
                    stats += '\n'
                    stats += helpers.get_uf_show(c.show)
                    if c.status:
                        stats += ': ' + c.status
                    if c.last_status_time:
                        stats += '\n' + _('since %s') % time.strftime(
                            '%c', c.last_status_time).decode(
                                locale.getpreferredencoding())
        else:  # Maybe gc_vcard ?
            stats = helpers.get_uf_show(self.contact.show)
            if self.contact.status:
                stats += ': ' + self.contact.status
        status_label = self.xml.get_widget('status_label')
        status_label.set_max_width_chars(15)
        status_label.set_text(stats)

        tip = gtk.Tooltips()
        status_label_eventbox = self.xml.get_widget('status_label_eventbox')
        tip.set_tip(status_label_eventbox, stats)
Example #7
0
    def _set_idle_time(self, contact):
        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:
                idle_color = gajim.config.get('tooltip_idle_color')
                idle_markup = "<span foreground='{}'>{}</span>".format(idle_color, formatted)
                self.idle_since.set_markup(idle_markup)
                self.idle_since.show()
                self.idle_since_label.show()
                idle_markup = "<span foreground='{}'>{}</span>".format(idle_color, str(diff))
                self.idle_for.set_markup(idle_markup)
                self.idle_for_label.show()
                self.idle_for.show()

        if contact.show and self.num_resources < 2:
            show = helpers.get_uf_show(contact.show)
            if contact.last_status_time:
                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

            # Contact is Groupchat
            if (self.account and
                    self.prim_contact.jid in gajim.gc_connected[self.account]):
                if gajim.gc_connected[self.account][self.prim_contact.jid]:
                    show = _('Connected')
                else:
                    show = _('Disconnected')

            self.user_show.set_markup(colorize_status(show))
            self.user_show.show()
Example #8
0
	def fill_status_label(self):
		if self.xml.get_widget('information_notebook').get_n_pages() < 5:
			return
		contact_list = gajim.contacts.get_contacts(self.account, self.contact.jid)
		connected_contact_list = []
		for c in contact_list:
			if c.show not in ('offline', 'error'):
				connected_contact_list.append(c)
		if not connected_contact_list:
			# no connected contact, get the offline one
			connected_contact_list = contact_list
		# stats holds show and status message
		stats = ''
		if connected_contact_list:
			# Start with self.contact, as with resources
			stats = helpers.get_uf_show(self.contact.show)
			if self.contact.status:
				stats += ': ' + self.contact.status
			if self.contact.last_status_time:
				stats += '\n' + _('since %s') % time.strftime('%c',
					self.contact.last_status_time).decode(
					locale.getpreferredencoding())
			for c in connected_contact_list:
				if c.resource != self.contact.resource:
					stats += '\n'
					stats += helpers.get_uf_show(c.show)
					if c.status:
						stats += ': ' + c.status
					if c.last_status_time:
						stats += '\n' + _('since %s') % time.strftime('%c',
							c.last_status_time).decode(locale.getpreferredencoding())
		else: # Maybe gc_vcard ?
			stats = helpers.get_uf_show(self.contact.show)
			if self.contact.status:
				stats += ': ' + self.contact.status
		status_label = self.xml.get_widget('status_label')
		status_label.set_max_width_chars(15)
		status_label.set_text(stats)

		tip = gtk.Tooltips()
		status_label_eventbox = self.xml.get_widget('status_label_eventbox')
		tip.set_tip(status_label_eventbox, stats)
Example #9
0
    def populate(self, contact):
        """
        Populate the Tooltip Grid with data of from the contact
        """
        self.clear_tooltip()

        self.nick.set_text(contact.get_shown_name())
        self.nick.show()

        # Status Message
        if contact.status:
            status = contact.status.strip()
            if status != '':
                self.status.set_text(status)
                self.status.show()

        # Status
        show = helpers.get_uf_show(contact.show)
        self.user_show.set_markup(colorize_status(show))
        self.user_show.show()

        # JID
        if contact.jid.strip():
            self.jid.set_text(contact.jid)
            self.jid.show()
            self.jid_label.show()
        # Resource
        if hasattr(contact, 'resource') and contact.resource.strip():
            self.resource.set_text(contact.resource)
            self.resource.show()
            self.resource_label.show()

        # Affiliation
        if contact.affiliation != 'none':
            uf_affiliation = helpers.get_uf_affiliation(contact.affiliation)
            uf_affiliation = \
                _('%(owner_or_admin_or_member)s of this group chat') \
                % {'owner_or_admin_or_member': uf_affiliation}
            uf_affiliation = self.colorize_affiliation(uf_affiliation)
            self.affiliation.set_markup(uf_affiliation)
            self.affiliation.show()

        # Avatar
        puny_name = helpers.sanitize_filename(contact.name)
        puny_room = helpers.sanitize_filename(contact.room_jid)
        file_ = helpers.get_avatar_path(os.path.join(gajim.AVATAR_PATH,
            puny_room, puny_name))
        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()
            self.fillelement.show()
Example #10
0
 def get_accounts_info(self):
     accounts = []
     if gajim.contacts:
         for account in gajim.contacts.keys():
             status_idx = gajim.connections[account].connected
             # uncomment the following to hide offline accounts
             # if status_idx == 0: continue
             status = gajim.SHOW_LIST[status_idx]
             message = gajim.connections[account].status
             single_line = helpers.get_uf_show(status)
             if message is None:
                 message = ""
             else:
                 message = message.strip()
             if message != "":
                 single_line += ": " + message
                 # the other solution is to hide offline accounts
             elif status == "offline":
                 message = helpers.get_uf_show(status)
             accounts.append({"name": account, "status_line": single_line, "show": status, "message": message})
     return accounts
Example #11
0
File: vcard.py Project: gajim/gajim
    def fill_status_label(self):
        if self.xml.get_object("information_notebook").get_n_pages() < 5:
            return
        contact_list = gajim.contacts.get_contacts(self.account, self.contact.jid)
        connected_contact_list = []
        for c in contact_list:
            if c.show not in ("offline", "error"):
                connected_contact_list.append(c)
        if not connected_contact_list:
            # no connected contact, get the offline one
            connected_contact_list = contact_list
        # stats holds show and status message
        stats = ""
        if connected_contact_list:
            # Start with self.contact, as with resources
            stats = helpers.get_uf_show(self.contact.show)
            if self.contact.status:
                stats += ": " + self.contact.status
            if self.contact.last_status_time:
                stats += "\n" + _("since %s") % time.strftime("%c", self.contact.last_status_time)
            for c in connected_contact_list:
                if c.resource != self.contact.resource:
                    stats += "\n"
                    stats += helpers.get_uf_show(c.show)
                    if c.status:
                        stats += ": " + c.status
                    if c.last_status_time:
                        stats += "\n" + _("since %s") % time.strftime("%c", c.last_status_time)
        else:  # Maybe gc_vcard ?
            stats = helpers.get_uf_show(self.contact.show)
            if self.contact.status:
                stats += ": " + self.contact.status
        status_label = self.xml.get_object("status_label")
        status_label.set_max_width_chars(15)
        status_label.set_text(stats)

        status_label_eventbox = self.xml.get_object("status_label_eventbox")
        status_label_eventbox.set_tooltip_text(stats)
Example #12
0
 def set_treeview_string(self):
     (model, iter_) = self.conditions_treeview.get_selection().get_selected()
     if not iter_:
         return
     event = self.event_combobox.get_active_text()
     recipient_type = self.recipient_type_combobox.get_active_text()
     recipient = ""
     if recipient_type != "everybody":
         recipient = self.recipient_list_entry.get_text()
     if self.all_status_rb.get_active():
         status = ""
     else:
         status = _("when I am ")
         for st in ("online", "away", "xa", "dnd", "invisible"):
             if self.__dict__[st + "_cb"].get_active():
                 status += helpers.get_uf_show(st) + " "
     model[iter_][1] = "When %s for %s %s %s" % (event, recipient_type, recipient, status)
Example #13
0
 def set_treeview_string(self):
     (model,
      iter_) = self.conditions_treeview.get_selection().get_selected()
     if not iter_:
         return
     event = self.event_combobox.get_active_text()
     recipient_type = self.recipient_type_combobox.get_active_text()
     recipient = ''
     if recipient_type != 'everybody':
         recipient = self.recipient_list_entry.get_text()
     if self.all_status_rb.get_active():
         status = ''
     else:
         status = _('when I am ')
         for st in ('online', 'away', 'xa', 'dnd', 'invisible'):
             if self.__dict__[st + '_cb'].get_active():
                 status += helpers.get_uf_show(st) + ' '
     model[iter_][1] = "When %s for %s %s %s" % (event, recipient_type,
                                                 recipient, status)
Example #14
0
    def populate(self, contact):
        if not contact:
            return
        self.create_window()
        vcard_table = Gtk.Grid()
        vcard_table.insert_row(0)
        vcard_table.insert_row(0)
        vcard_table.insert_row(0)
        vcard_table.insert_column(0)
        vcard_table.set_property('column-spacing', 2)
        vcard_current_row = 1
        properties = []

        nick_markup = '<b>' + GLib.markup_escape_text(contact.get_shown_name())\
            + '</b>'
        properties.append((nick_markup, None))

        if contact.status: # status message
            status = contact.status.strip()
            if status != '':
                # escape markup entities
                status = helpers.reduce_chars_newlines(status, 300, 5)
                status = '<i>' + GLib.markup_escape_text(status) + '</i>'
                properties.append((status, None))

        show = helpers.get_uf_show(contact.show)
        show = self.colorize_status(show)
        properties.append((show, None))

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

        if hasattr(contact, 'resource') and contact.resource.strip():
            properties.append((_('Resource: '), GLib.markup_escape_text(
                contact.resource)))

        if contact.affiliation != 'none':
            uf_affiliation = helpers.get_uf_affiliation(contact.affiliation)
            uf_affiliation = \
                _('%(owner_or_admin_or_member)s of this group chat') % \
                {'owner_or_admin_or_member': uf_affiliation}
            uf_affiliation = self.colorize_affiliation(uf_affiliation)
            properties.append((uf_affiliation, None))

        # Add avatar
        puny_name = helpers.sanitize_filename(contact.name)
        puny_room = helpers.sanitize_filename(contact.room_jid)
        file_ = helpers.get_avatar_path(os.path.join(gajim.AVATAR_PATH,
            puny_room, puny_name))
        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)
        else:
            self.avatar_image.set_from_pixbuf(None)
        while properties:
            property_ = properties.pop(0)
            vcard_current_row += 1
            label = Gtk.Label()
            if not properties:
                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:
                    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:
                label.set_markup(property_[0])
                label.set_line_wrap(True)
                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)
        vcard_table.attach(self.avatar_image, 3, 2, 1, vcard_current_row - 1)
        gajim.plugin_manager.gui_extension_point('gc_tooltip_populate',
            self, contact, vcard_table)
        self.win.add(vcard_table)
Example #15
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
Example #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)
Example #17
0
def get_transport_menu(contact, account):
    roster = gajim.interface.roster
    jid = contact.jid

    menu = Gtk.Menu()

    # Send single message
    item = Gtk.MenuItem.new_with_mnemonic(_('Send Single _Message...'))
    item.connect('activate', roster.on_send_single_message_menuitem_activate,
                 account, contact)
    menu.append(item)
    if 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.MenuItem.new_with_mnemonic(
        _('Send Cus_tom Status'))
    if blocked:
        send_custom_status_menuitem.set_sensitive(False)
    else:
        status_menuitems = Gtk.Menu()
        send_custom_status_menuitem.set_submenu(status_menuitems)
        for s in ('online', 'chat', 'away', 'xa', 'dnd', 'offline'):
            status_menuitem = Gtk.MenuItem.new_with_label(
                helpers.get_uf_show(s))
            status_menuitem.connect('activate', roster.on_send_custom_status,
                                    [(contact, account)], s)
            status_menuitems.append(status_menuitem)
    menu.append(send_custom_status_menuitem)
    if gajim.account_is_disconnected(account):
        send_custom_status_menuitem.set_sensitive(False)

    item = Gtk.SeparatorMenuItem.new()  # separator
    menu.append(item)

    # Execute Command
    item = Gtk.MenuItem.new_with_mnemonic(_('E_xecute Command...'))
    menu.append(item)
    item.connect('activate', roster.on_execute_command, contact, account,
                 contact.resource)
    if gajim.account_is_disconnected(account):
        item.set_sensitive(False)

    # Manage Transport submenu
    item = Gtk.MenuItem.new_with_mnemonic(_('_Manage Transport'))
    manage_transport_submenu = Gtk.Menu()
    item.set_submenu(manage_transport_submenu)
    menu.append(item)

    # Modify Transport
    item = Gtk.MenuItem.new_with_mnemonic(_('_Modify Transport'))
    manage_transport_submenu.append(item)
    item.connect('activate', roster.on_edit_agent, contact, account)
    if gajim.account_is_disconnected(account):
        item.set_sensitive(False)

    # Rename
    item = Gtk.MenuItem.new_with_mnemonic(_('_Rename...'))
    manage_transport_submenu.append(item)
    item.connect('activate', roster.on_rename, 'agent', jid, account)
    if gajim.account_is_disconnected(account):
        item.set_sensitive(False)

    item = Gtk.SeparatorMenuItem.new()  # separator
    manage_transport_submenu.append(item)

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

    manage_transport_submenu.append(item)
    if gajim.account_is_disconnected(account):
        item.set_sensitive(False)

    # Remove
    item = Gtk.MenuItem.new_with_mnemonic(_('Remo_ve'))
    manage_transport_submenu.append(item)
    item.connect('activate', roster.on_remove_agent, [(contact, account)])
    if gajim.account_is_disconnected(account):
        item.set_sensitive(False)

    item = Gtk.SeparatorMenuItem.new()  # separator
    menu.append(item)

    # Information
    information_menuitem = Gtk.MenuItem.new_with_mnemonic(_('_Information'))
    menu.append(information_menuitem)
    information_menuitem.connect('activate', roster.on_info, contact, account)
    if gajim.account_is_disconnected(account):
        information_menuitem.set_sensitive(False)

    menu.connect('selection-done', gtkgui_helpers.destroy_widget)
    menu.show_all()
    return menu
Example #18
0
    def _fill_logs_listview(self, jid):
        '''fill the listview with all messages that user sent to or
		received from JID'''
        # no need to lower jid in this context as jid is already lowered
        # as we use those jids from db
        jid_id = self._get_jid_id(jid)
        self.cur.execute(
            '''
			SELECT log_line_id, jid_id, time, kind, message, subject, contact_name, show
			FROM logs
			WHERE jid_id = ?
			ORDER BY time
			''', (jid_id, ))

        results = self.cur.fetchall()

        if self._jid_is_room_type(jid):  # is it room?
            self.nickname_col_for_logs.set_visible(True)
            self.subject_col_for_logs.set_visible(False)
        else:
            self.nickname_col_for_logs.set_visible(False)
            self.subject_col_for_logs.set_visible(True)

        for row in results:
            # exposed in UI (TreeViewColumns) are only
            # time, message, subject, nickname
            # but store in liststore
            # log_line_id, jid_id, time, message, subject, nickname
            log_line_id, jid_id, time_, kind, message, subject, nickname, show = row
            try:
                time_ = time.strftime('%x', time.localtime(
                    float(time_))).decode(locale.getpreferredencoding())
            except ValueError:
                pass
            else:
                color = None
                if kind in (constants.KIND_SINGLE_MSG_RECV,
                            constants.KIND_CHAT_MSG_RECV,
                            constants.KIND_GC_MSG):
                    # it is the other side
                    color = gajim.config.get('inmsgcolor')  # so incoming color
                elif kind in (constants.KIND_SINGLE_MSG_SENT,
                              constants.KIND_CHAT_MSG_SENT):  # it is us
                    color = gajim.config.get(
                        'outmsgcolor')  # so outgoing color
                elif kind in (constants.KIND_STATUS,
                              constants.KIND_GCSTATUS):  # is is statuses
                    color = gajim.config.get(
                        'statusmsgcolor')  # so status color
                    # include status into (status) message
                    if message is None:
                        message = ''
                    else:
                        message = ' : ' + message
                    message = helpers.get_uf_show(
                        gajim.SHOW_LIST[show]) + message

                message_ = '<span'
                if color:
                    message_ += ' foreground="%s"' % color
                message_ += '>%s</span>' % \
                 gobject.markup_escape_text(message)
                self.logs_liststore.append(
                    (log_line_id, jid_id, time_, message_, subject, nickname))
Example #19
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)
Example #20
0
	def add_new_line(self, contact_name, tim, kind, show, message):
		'''add a new line in textbuffer'''
		if not message: # None or ''
			return
		buf = self.history_buffer
		end_iter = buf.get_end_iter()
		
		if gajim.config.get('print_time') == 'always':
			before_str = gajim.config.get('before_time')
			after_str = gajim.config.get('after_time')
			format = before_str + '%X' + after_str + ' '
			tim = time.strftime(format, time.localtime(float(tim)))
			buf.insert(end_iter, tim) # add time
		elif gajim.config.get('print_time') == 'sometimes':
			every_foo_seconds = 60 * gajim.config.get(
				'print_ichat_every_foo_minutes')
			seconds_passed = tim - self.last_time_printout
			if seconds_passed > every_foo_seconds:
				self.last_time_printout = tim
				tim = time.strftime('%X ', time.localtime(float(tim)))
				buf.insert_with_tags_by_name(end_iter, tim + '\n',
					'time_sometimes')				

		tag_name = ''
		tag_msg = ''
		
		show = self.get_string_show_from_constant_int(show)
		
		if kind == constants.KIND_GC_MSG:
			tag_name = 'incoming'
		elif kind in (constants.KIND_SINGLE_MSG_RECV, constants.KIND_CHAT_MSG_RECV):
			try:
				# is he in our roster? if yes use the name
				contact_name = gajim.contacts[self.account][self.jid][0].name
			except:
				room_jid, nick = gajim.get_room_and_nick_from_fjid(self.jid)
				# do we have him as gc_contact?
				if nick and gajim.gc_contacts[self.account].has_key(room_jid) and\
					gajim.gc_contacts[self.account][room_jid].has_key(nick):
					# so yes, it's pm!
					contact_name = nick
				else:
					contact_name = self.jid.split('@')[0]
			tag_name = 'incoming'
		elif kind in (constants.KIND_SINGLE_MSG_SENT, constants.KIND_CHAT_MSG_SENT):
			contact_name = gajim.nicks[self.account]
			tag_name = 'outgoing'
		elif kind == constants.KIND_GCSTATUS:
			# message here (if not None) is status message
			if message:
				message = _('%(nick)s is now %(status)s: %(status_msg)s') %\
					{'nick': contact_name, 'status': helpers.get_uf_show(show),
					'status_msg': message }
			else:
				message = _('%(nick)s is now %(status)s') % {'nick': contact_name,
					'status': helpers.get_uf_show(show) }
			tag_msg = 'status'
		else: # 'status'
			# message here (if not None) is status message
			if message:
				message = _('Status is now: %(status)s: %(status_msg)s') % \
					{'status': helpers.get_uf_show(show), 'status_msg': message}
			else:
				message = _('Status is now: %(status)s') % { 'status':
					helpers.get_uf_show(show) }
			tag_msg = 'status'

		# do not do this if gcstats, avoid dupping contact_name
		# eg. nkour: nkour is now Offline
		if contact_name and kind != constants.KIND_GCSTATUS:
			# add stuff before and after contact name
			before_str = gajim.config.get('before_nickname')
			after_str = gajim.config.get('after_nickname')
			format = before_str + contact_name + after_str + ' '
			buf.insert_with_tags_by_name(end_iter, format, tag_name)

		message = message + '\n'
		if tag_msg:
			self.history_textview.print_real_text(message, [tag_msg])
		else:
			self.history_textview.print_real_text(message)
Example #21
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 = []

    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 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_sensitive(False)

    if gc_contact:
        if not gc_contact.jid:
            # it's a pm and we don't know real JID
            invite_menuitem.set_sensitive(False)
        else:
            bookmarked = False
            c_ = 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)
    for s in ('online', 'chat', 'away', 'xa', 'dnd', 'offline'):
        # icon MUST be different instance for every item
        status_menuitem = Gtk.MenuItem.new_with_label(helpers.get_uf_show(s))
        status_menuitem.connect('activate', roster.on_send_custom_status,
                                [(contact, account)], s)
        status_menuitems.append(status_menuitem)

    send_single_message_menuitem.connect('activate',
        roster.on_send_single_message_menuitem_activate, account, contact)

    remove_from_roster_menuitem.connect('activate', roster.on_req_usub,
        [(contact, account)])
    information_menuitem.connect('activate', roster.on_info, contact, account)

    if _('Not in Roster') not in contact.get_shown_groups():
        # contact is in normal group
        add_to_roster_menuitem.hide()
        add_to_roster_menuitem.set_no_show_all(True)

        if contact.sub in ('from', 'both'):
            send_auth_menuitem.set_sensitive(False)
        else:
            send_auth_menuitem.connect('activate', roster.authorize, jid, account)
        if contact.sub in ('to', 'both'):
            ask_auth_menuitem.set_sensitive(False)
            add_special_notification_menuitem.connect('activate',
                    roster.on_add_special_notification_menuitem_activate, jid)
        else:
            ask_auth_menuitem.connect('activate', roster.req_sub, jid,
                    _('I would like to add you to my roster'), account,
                    contact.groups, contact.name)
        transport = 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
Example #22
0
    def _add_new_line(self, contact_name, tim, kind, show, message, subject,
                      additional_data):
        """
        Add a new line in textbuffer
        """
        if not message and kind not in (KindConstant.STATUS,
                                        KindConstant.GCSTATUS):
            return
        buf = self.history_buffer
        end_iter = buf.get_end_iter()

        if gajim.config.get('print_time') == 'always':
            timestamp_str = gajim.config.get('time_stamp')
            timestamp_str = helpers.from_one_line(timestamp_str)
            tim = time.strftime(timestamp_str, time.localtime(float(tim)))
            buf.insert(end_iter, tim)  # add time
        elif gajim.config.get('print_time') == 'sometimes':
            every_foo_seconds = 60 * gajim.config.get(
                'print_ichat_every_foo_minutes')
            seconds_passed = tim - self.last_time_printout
            if seconds_passed > every_foo_seconds:
                self.last_time_printout = tim
                tim = time.strftime('%X ', time.localtime(float(tim)))
                buf.insert_with_tags_by_name(end_iter, tim + '\n',
                                             'time_sometimes')
        else:  # don't print time. So we print it as invisible to be able to
            # search for it
            timestamp_str = gajim.config.get('time_stamp')
            timestamp_str = helpers.from_one_line(timestamp_str)
            tim = time.strftime(timestamp_str, time.localtime(float(tim)))
            buf.insert_with_tags_by_name(end_iter, tim, 'invisible')

        tag_name = ''
        tag_msg = ''

        show = self._get_string_show_from_constant_int(show)

        if kind == KindConstant.GC_MSG:
            tag_name = 'incoming'
        elif kind in (KindConstant.SINGLE_MSG_RECV,
                      KindConstant.CHAT_MSG_RECV):
            contact_name = self.completion_dict[self.jid][InfoColumn.NAME]
            tag_name = 'incoming'
            tag_msg = 'incomingtxt'
        elif kind in (KindConstant.SINGLE_MSG_SENT,
                      KindConstant.CHAT_MSG_SENT):
            if self.account:
                contact_name = gajim.nicks[self.account]
            else:
                # we don't have roster, we don't know our own nick, use first
                # account one (urk!)
                account = list(gajim.contacts.get_accounts())[0]
                contact_name = gajim.nicks[account]
            tag_name = 'outgoing'
            tag_msg = 'outgoingtxt'
        elif kind == KindConstant.GCSTATUS:
            # message here (if not None) is status message
            if message:
                message = _('%(nick)s is now %(status)s: %(status_msg)s') %\
                        {'nick': contact_name, 'status': helpers.get_uf_show(show),
                        'status_msg': message }
            else:
                message = _('%(nick)s is now %(status)s') % {
                    'nick': contact_name,
                    'status': helpers.get_uf_show(show)
                }
            tag_msg = 'status'
        else:  # 'status'
            # message here (if not None) is status message
            if show is None:  # it means error
                if message:
                    message = _('Error: %s') % message
                else:
                    message = _('Error')
            elif message:
                message = _('Status is now: %(status)s: %(status_msg)s') % \
                        {'status': helpers.get_uf_show(show), 'status_msg': message}
            else:
                message = _('Status is now: %(status)s') % {
                    'status': helpers.get_uf_show(show)
                }
            tag_msg = 'status'

        if message.startswith('/me ') or message.startswith('/me\n'):
            tag_msg = tag_name
        else:
            # do not do this if gcstats, avoid dupping contact_name
            # eg. nkour: nkour is now Offline
            if contact_name and kind != KindConstant.GCSTATUS:
                # add stuff before and after contact name
                before_str = gajim.config.get('before_nickname')
                before_str = helpers.from_one_line(before_str)
                after_str = gajim.config.get('after_nickname')
                after_str = helpers.from_one_line(after_str)
                format = before_str + contact_name + after_str + ' '
                if tag_name:
                    buf.insert_with_tags_by_name(end_iter, format, tag_name)
                else:
                    buf.insert(end_iter, format)
        if subject:
            message = _('Subject: %s\n') % subject + message
        xhtml = None
        if message.startswith('<body '):
            xhtml = message

        if tag_msg:
            self.history_textview.print_real_text(
                message, [tag_msg],
                name=contact_name,
                xhtml=xhtml,
                additional_data=additional_data)
        else:
            self.history_textview.print_real_text(
                message,
                name=contact_name,
                xhtml=xhtml,
                additional_data=additional_data)
        buffer_ = self.history_textview.tv.get_buffer()
        eob = buffer_.get_end_iter()
        buffer_.insert_with_tags_by_name(eob, '\n', 'eol')
Example #23
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)
Example #24
0
    def populate(self, contact):
        if not contact:
            return
        self.create_window()
        vcard_table = Gtk.Grid()
        vcard_table.insert_row(0)
        vcard_table.insert_row(0)
        vcard_table.insert_row(0)
        vcard_table.insert_column(0)
        vcard_table.set_property('column-spacing', 2)
        vcard_current_row = 1
        properties = []

        nick_markup = '<b>' + GLib.markup_escape_text(contact.get_shown_name())\
            + '</b>'
        properties.append((nick_markup, None))

        if contact.status: # status message
            status = contact.status.strip()
            if status != '':
                # escape markup entities
                status = helpers.reduce_chars_newlines(status, 300, 5)
                status = '<i>' + GLib.markup_escape_text(status) + '</i>'
                properties.append((status, None))

        show = helpers.get_uf_show(contact.show)
        show = self.colorize_status(show)
        properties.append((show, None))

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

        if hasattr(contact, 'resource') and contact.resource.strip():
            properties.append((_('Resource: '), GLib.markup_escape_text(
                contact.resource)))

        if contact.affiliation != 'none':
            uf_affiliation = helpers.get_uf_affiliation(contact.affiliation)
            uf_affiliation = \
                _('%(owner_or_admin_or_member)s of this group chat') % \
                {'owner_or_admin_or_member': uf_affiliation}
            uf_affiliation = self.colorize_affiliation(uf_affiliation)
            properties.append((uf_affiliation, None))

        # Add avatar
        puny_name = helpers.sanitize_filename(contact.name)
        puny_room = helpers.sanitize_filename(contact.room_jid)
        file_ = helpers.get_avatar_path(os.path.join(gajim.AVATAR_PATH,
            puny_room, puny_name))
        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)
        else:
            self.avatar_image.set_from_pixbuf(None)
        while properties:
            property_ = properties.pop(0)
            vcard_current_row += 1
            label = Gtk.Label()
            if not properties:
                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:
                    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:
                label.set_markup(property_[0])
                label.set_line_wrap(True)
                vcard_table.attach(label, 1, vcard_current_row, 2, 1)

        self.avatar_image.set_alignment(0, 0)
        vcard_table.attach(self.avatar_image, 3, 2, 1, vcard_current_row - 1)
        gajim.plugin_manager.gui_extension_point('gc_tooltip_populate',
            self, contact, vcard_table)
        self.win.add(vcard_table)
Example #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_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)
Example #26
0
    def populate(self, contact):
        if not contact:
            return
        self.create_window()
        vcard_table = gtk.Table(3, 1)
        vcard_table.set_property('column-spacing', 2)
        vcard_table.set_homogeneous(False)
        vcard_current_row = 1
        properties = []

        nick_markup = '<b>' + \
         gobject.markup_escape_text(contact.get_shown_name()) \
         + '</b>'
        properties.append((nick_markup, None))

        if contact.status:  # status message
            status = contact.status.strip()
            if status != '':
                # escape markup entities
                status = helpers.reduce_chars_newlines(status, 300, 5)
                status = '<i>' +\
                 gobject.markup_escape_text(status) + '</i>'
                properties.append((status, None))
        else:  # no status message, show SHOW instead
            show = helpers.get_uf_show(contact.show)
            show = '<i>' + show + '</i>'
            properties.append((show, None))

        if contact.jid.strip() != '':
            properties.append((_('Jabber ID: '), contact.jid))

        if hasattr(contact, 'resource') and contact.resource.strip() != '':
            properties.append((_('Resource: '),
                               gobject.markup_escape_text(contact.resource)))
        if contact.affiliation != 'none':
            uf_affiliation = helpers.get_uf_affiliation(contact.affiliation)
            affiliation_str = \
             _('%(owner_or_admin_or_member)s of this group chat') %\
             {'owner_or_admin_or_member': uf_affiliation}
            properties.append((affiliation_str, None))

        # Add avatar
        puny_name = helpers.sanitize_filename(contact.name)
        puny_room = helpers.sanitize_filename(contact.room_jid)
        file = helpers.get_avatar_path(
            os.path.join(gajim.AVATAR_PATH, puny_room, puny_name))
        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)
        else:
            self.avatar_image.set_from_pixbuf(None)
        while properties:
            property = properties.pop(0)
            vcard_current_row += 1
            vertical_fill = gtk.FILL
            if not properties:
                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:
                label.set_markup(property[0])
                label.set_line_wrap(True)
                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)
        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)
Example #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)
Example #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_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)
Example #29
0
	def _add_new_line(self, contact_name, tim, kind, show, message):
		'''add a new line in textbuffer'''
		if not message and kind not in (constants.KIND_STATUS,
			constants.KIND_GCSTATUS):
			return
		buf = self.history_buffer
		end_iter = buf.get_end_iter()
		
		if gajim.config.get('print_time') == 'always':
			timestamp_str = gajim.config.get('time_stamp')
			timestamp_str = helpers.from_one_line(timestamp_str)
			tim = time.strftime(timestamp_str, time.localtime(float(tim)))
			buf.insert(end_iter, tim) # add time
		elif gajim.config.get('print_time') == 'sometimes':
			every_foo_seconds = 60 * gajim.config.get(
				'print_ichat_every_foo_minutes')
			seconds_passed = tim - self.last_time_printout
			if seconds_passed > every_foo_seconds:
				self.last_time_printout = tim
				tim = time.strftime('%X ', time.localtime(float(tim)))
				buf.insert_with_tags_by_name(end_iter, tim + '\n',
					'time_sometimes')

		tag_name = ''
		tag_msg = ''
		
		show = self._get_string_show_from_constant_int(show)
		
		if kind == constants.KIND_GC_MSG:
			tag_name = 'incoming'
		elif kind in (constants.KIND_SINGLE_MSG_RECV,
		constants.KIND_CHAT_MSG_RECV):
			contact_name = self.completion_dict[self.jid][C_INFO_NAME]
			tag_name = 'incoming'
		elif kind in (constants.KIND_SINGLE_MSG_SENT,
		constants.KIND_CHAT_MSG_SENT):
			if self.account:
				contact_name = gajim.nicks[self.account]
			else: 
				# we don't have roster, we don't know our own nick, use first
				# account one (urk!)
				account = gajim.contacts.get_accounts()[0] 
				contact_name = gajim.nicks[account]
			tag_name = 'outgoing'
		elif kind == constants.KIND_GCSTATUS:
			# message here (if not None) is status message
			if message:
				message = _('%(nick)s is now %(status)s: %(status_msg)s') %\
					{'nick': contact_name, 'status': helpers.get_uf_show(show),
					'status_msg': message }
			else:
				message = _('%(nick)s is now %(status)s') % {'nick': contact_name,
					'status': helpers.get_uf_show(show) }
			tag_msg = 'status'
		else: # 'status'
			# message here (if not None) is status message
			if message:
				message = _('Status is now: %(status)s: %(status_msg)s') % \
					{'status': helpers.get_uf_show(show), 'status_msg': message}
			else:
				message = _('Status is now: %(status)s') % { 'status':
					helpers.get_uf_show(show) }
			tag_msg = 'status'

		# do not do this if gcstats, avoid dupping contact_name
		# eg. nkour: nkour is now Offline
		if contact_name and kind != constants.KIND_GCSTATUS:
			# add stuff before and after contact name
			before_str = gajim.config.get('before_nickname')
			before_str = helpers.from_one_line(before_str)
			after_str = gajim.config.get('after_nickname')
			after_str = helpers.from_one_line(after_str)
			format = before_str + contact_name + after_str + ' '
			buf.insert_with_tags_by_name(end_iter, format, tag_name)

		message = message + '\n'
		if tag_msg:
			self.history_textview.print_real_text(message, [tag_msg])
		else:
			self.history_textview.print_real_text(message)
Example #30
0
	def populate(self, contact):
		if not contact:
			return
		self.create_window()
		vcard_table = gtk.Table(3, 1)
		vcard_table.set_property('column-spacing', 2)
		vcard_table.set_homogeneous(False)
		vcard_current_row = 1
		properties = []

		nick_markup = '<b>' + \
			gobject.markup_escape_text(contact.get_shown_name()) \
			+ '</b>' 
		properties.append((nick_markup, None))

		if contact.status: # status message 
			status = contact.status.strip()
			if status != '':
				# escape markup entities
				status = helpers.reduce_chars_newlines(status, 300, 5)
				status = '<i>' +\
					gobject.markup_escape_text(status) + '</i>'
				properties.append((status, None))
		else: # no status message, show SHOW instead
			show = helpers.get_uf_show(contact.show)
			show = '<i>' + show + '</i>'
			properties.append((show, None))

		if contact.jid.strip() != '':
			properties.append((_('Jabber ID: '), contact.jid))

		if hasattr(contact, 'resource') and contact.resource.strip() != '':
			properties.append((_('Resource: '), 
				gobject.markup_escape_text(contact.resource) ))
		if contact.affiliation != 'none':
			uf_affiliation = helpers.get_uf_affiliation(contact.affiliation)
			affiliation_str = \
				_('%(owner_or_admin_or_member)s of this group chat') %\
				{'owner_or_admin_or_member': uf_affiliation}
			properties.append((affiliation_str, None))
		
		# Add avatar
		puny_name = helpers.sanitize_filename(contact.name)
		puny_room = helpers.sanitize_filename(contact.room_jid)
		file = helpers.get_avatar_path(os.path.join(gajim.AVATAR_PATH, puny_room,
			puny_name))
		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)
		else:
			self.avatar_image.set_from_pixbuf(None)
		while properties:
			property = properties.pop(0)
			vcard_current_row += 1
			vertical_fill = gtk.FILL
			if not properties:
				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:
				label.set_markup(property[0])
				label.set_line_wrap(True)
				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)
		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)
Example #31
0
	def make_menu(self, event = None):
		'''create chat with and new message (sub) menus/menuitems
		event is None when we're in Windows
		'''
		
		chat_with_menuitem = self.xml.get_widget('chat_with_menuitem')
		new_message_menuitem = self.xml.get_widget('new_message_menuitem')
		status_menuitem = self.xml.get_widget('status_menu')
		
		if self.new_message_handler_id:
			new_message_menuitem.handler_disconnect(
				self.new_message_handler_id)
			self.new_message_handler_id = None

		sub_menu = gtk.Menu()
		status_menuitem.set_submenu(sub_menu)

		# We need our own set of status icons, let's make 'em!
		iconset = gajim.config.get('iconset')
		if not iconset:
			iconset = 'dcraven'
		path = os.path.join(gajim.DATA_DIR, 'iconsets', iconset, '16x16')
		state_images = gajim.interface.roster.load_iconset(path)

		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...'))
		path = os.path.join(gajim.DATA_DIR, 'pixmaps', 'rename.png')
		img = gtk.Image()
		img.set_from_file(path)
		item.set_image(img)
		sub_menu.append(item)
		item.connect('activate', self.on_change_status_message_activate)
		if not helpers.one_account_connected():
			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)
		item.connect('activate', self.on_show_menuitem_activate, 'offline')

		iskey = len(gajim.connections) > 0
		chat_with_menuitem.set_sensitive(iskey)
		new_message_menuitem.set_sensitive(iskey)
		
		if len(gajim.connections) >= 2: # 2 or more connections? make submenus
			account_menu_for_chat_with = gtk.Menu()
			chat_with_menuitem.set_submenu(account_menu_for_chat_with)

			account_menu_for_new_message = gtk.Menu()
			new_message_menuitem.set_submenu(account_menu_for_new_message)

			for account in gajim.connections:
				#for chat_with
				item = gtk.MenuItem(_('using account ') + account)
				account_menu_for_chat_with.append(item)
				group_menu = self.make_groups_submenus_for_chat_with(account)
				item.set_submenu(group_menu)
				#for new_message
				item = gtk.MenuItem(_('using account ') + account)
				item.connect('activate',
					self.on_new_message_menuitem_activate, account)
				account_menu_for_new_message.append(item)
				
		elif len(gajim.connections) == 1: # one account
			# one account, no need to show 'as jid'
			# for chat_with
			account = gajim.connections.keys()[0]
			
			group_menu = self.make_groups_submenus_for_chat_with(account)
			chat_with_menuitem.set_submenu(group_menu)
					
			# for new message
			self.new_message_handler_id = new_message_menuitem.connect(
				'activate', self.on_new_message_menuitem_activate, account)

		if event is None:
			# None means windows (we explicitly popup in systraywin32.py)
			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
			
		else: # GNU and Unices
			self.systray_context_menu.popup(None, None, None, event.button, event.time)
		self.systray_context_menu.show_all()
Example #32
0
    def populate(self, data):
        self.create_window()
        self.create_table()
        self.hbox = gtk.HBox()
        self.table.set_property("column-spacing", 1)
        text, single_line = "", ""

        unread_chat = gajim.interface.roster.nb_unread
        unread_single_chat = 0
        unread_gc = 0
        unread_pm = 0

        accounts = self.get_accounts_info()

        for acct in gajim.connections:
            # we count unread chat/pm messages
            chat_wins = gajim.interface.instances[acct]["chats"]
            for jid in chat_wins:
                if jid != "tabbed":
                    if gajim.contacts[acct].has_key(jid):
                        unread_chat += chat_wins[jid].nb_unread[jid]
                    else:
                        unread_pm += chat_wins[jid].nb_unread[jid]
                        # we count unread gc/pm messages
            gc_wins = gajim.interface.instances[acct]["gc"]
            for jid in gc_wins:
                if jid != "tabbed":
                    pm_msgs = gc_wins[jid].get_specific_unread(jid)
                    unread_gc += gc_wins[jid].nb_unread[jid]
                    unread_gc -= pm_msgs
                    unread_pm += pm_msgs

        if unread_chat or unread_single_chat or unread_gc or unread_pm:
            text = ""
            if unread_chat:
                text += i18n.ngettext(
                    "Gajim - %d unread message", "Gajim - %d unread messages", unread_chat, unread_chat, unread_chat
                )
                text += "\n"
            if unread_single_chat:
                text += i18n.ngettext(
                    "Gajim - %d unread single message",
                    "Gajim - %d unread single messages",
                    unread_single_chat,
                    unread_single_chat,
                    unread_single_chat,
                )
                text += "\n"
            if unread_gc:
                text += i18n.ngettext(
                    "Gajim - %d unread group chat message",
                    "Gajim - %d unread group chat messages",
                    unread_gc,
                    unread_gc,
                    unread_gc,
                )
                text += "\n"
            if unread_pm:
                text += i18n.ngettext(
                    "Gajim - %d unread private message",
                    "Gajim - %d unread private messages",
                    unread_pm,
                    unread_pm,
                    unread_pm,
                )
                text += "\n"
            text = text[:-1]  # remove latest \n
        elif len(accounts) > 1:
            text = _("Gajim")
            self.current_row = 1
            self.table.resize(2, 1)
            self.fill_table_with_accounts(accounts)

        elif len(accounts) == 1:
            message = accounts[0]["status_line"]
            message = gtkgui_helpers.reduce_chars_newlines(message, 50, 1)
            message = gtkgui_helpers.escape_for_pango_markup(message)
            text = _("Gajim - %s") % message
        else:
            text = _("Gajim - %s") % helpers.get_uf_show("offline")
        self.text_label.set_markup(text)
        self.hbox.add(self.table)
        self.win.add(self.hbox)
Example #33
0
    def populate(self, contacts):
        self.create_window()
        self.hbox = gtk.HBox()
        self.hbox.set_homogeneous(False)
        self.hbox.set_spacing(0)
        self.create_table()
        if not contacts or len(contacts) == 0:
            # Tooltip for merged accounts row
            accounts = self.get_accounts_info()
            self.current_row = 0
            self.table.resize(2, 1)
            self.spacer_label = ""
            self.fill_table_with_accounts(accounts)
            self.hbox.add(self.table)
            self.win.add(self.hbox)
            return
            # primary contact
        prim_contact = gajim.get_highest_prio_contact_from_contacts(contacts)

        # try to find the image for the contact status
        icon_name = helpers.get_icon_name_to_show(prim_contact)
        state_file = icon_name.replace(" ", "_")
        transport = gajim.get_transport_name_from_jid(prim_contact.jid)
        if transport:
            file_path = os.path.join(gajim.DATA_DIR, "iconsets", "transports", transport, "16x16")
        else:
            iconset = gajim.config.get("iconset")
            if not iconset:
                iconset = "dcraven"
            file_path = os.path.join(gajim.DATA_DIR, "iconsets", iconset, "16x16")

        files = []
        file_full_path = os.path.join(file_path, state_file)
        files.append(file_full_path + ".png")
        files.append(file_full_path + ".gif")
        self.image.set_from_pixbuf(None)
        for file in files:
            if os.path.exists(file):
                self.image.set_from_file(file)
                break

        info = '<span size="large" weight="bold">' + prim_contact.jid + "</span>"
        info += (
            '\n<span weight="bold">'
            + _("Name: ")
            + "</span>"
            + gtkgui_helpers.escape_for_pango_markup(prim_contact.name)
        )
        if prim_contact.sub:
            info += (
                '\n<span weight="bold">'
                + _("Subscription: ")
                + "</span>"
                + gtkgui_helpers.escape_for_pango_markup(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:
                info += (
                    '\n<span weight="bold">'
                    + _("OpenPGP: ")
                    + "</span>"
                    + gtkgui_helpers.escape_for_pango_markup(keyID)
                )

        num_resources = 0
        for contact in contacts:
            if contact.resource:
                num_resources += 1
        if num_resources > 1:
            self.current_row = 1
            self.table.resize(2, 1)
            info += '\n<span weight="bold">' + _("Status: ") + "</span>"
            for contact in contacts:
                if contact.resource:
                    status_line = self.get_status_info(contact.resource, contact.priority, contact.show, contact.status)
                    icon_name = helpers.get_icon_name_to_show(contact)
                    self.add_status_row(file_path, icon_name, status_line)

        else:  # only one resource
            if contact.resource:
                info += (
                    '\n<span weight="bold">'
                    + _("Resource: ")
                    + "</span>"
                    + gtkgui_helpers.escape_for_pango_markup(contact.resource)
                    + " ("
                    + unicode(contact.priority)
                    + ")"
                )
            if contact.show:
                info += '\n<span weight="bold">' + _("Status: ") + "</span>" + helpers.get_uf_show(contact.show)
                if contact.status:
                    status = contact.status.strip()
                    if status != "":
                        # reduce long status
                        # (no more than 130 chars on line and no more than 5 lines)
                        status = gtkgui_helpers.reduce_chars_newlines(status, 130, 5)
                        # escape markup entities.
                        info += " - " + gtkgui_helpers.escape_for_pango_markup(status)

        self.text_label.set_markup(info)
        self.hbox.pack_start(self.image, False, False)
        self.hbox.pack_start(self.table, True, True)
        self.win.add(self.hbox)
Example #34
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 = []

    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 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_sensitive(False)

    if gc_contact:
        if not gc_contact.jid:
            # it's a pm and we don't know real JID
            invite_menuitem.set_sensitive(False)
        else:
            bookmarked = False
            c_ = 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)
    for s in ('online', 'chat', 'away', 'xa', 'dnd', 'offline'):
        # icon MUST be different instance for every item
        status_menuitem = Gtk.MenuItem.new_with_label(helpers.get_uf_show(s))
        status_menuitem.connect('activate', roster.on_send_custom_status,
                                [(contact, account)], s)
        status_menuitems.append(status_menuitem)

    send_single_message_menuitem.connect(
        'activate', roster.on_send_single_message_menuitem_activate, account,
        contact)

    remove_from_roster_menuitem.connect('activate', roster.on_req_usub,
                                        [(contact, account)])
    information_menuitem.connect('activate', roster.on_info, contact, account)

    if _('Not in Roster') not in contact.get_shown_groups():
        # contact is in normal group
        add_to_roster_menuitem.hide()
        add_to_roster_menuitem.set_no_show_all(True)

        if contact.sub in ('from', 'both'):
            send_auth_menuitem.set_sensitive(False)
        else:
            send_auth_menuitem.connect('activate', roster.authorize, jid,
                                       account)
        if contact.sub in ('to', 'both'):
            ask_auth_menuitem.set_sensitive(False)
            add_special_notification_menuitem.connect(
                'activate',
                roster.on_add_special_notification_menuitem_activate, jid)
        else:
            ask_auth_menuitem.connect(
                'activate', roster.req_sub, jid,
                _('I would like to add you to my roster'), account,
                contact.groups, contact.name)
        transport = 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
Example #35
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)
Example #36
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
Example #37
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
Example #38
0
	def fill_jabber_page(self):
		tooltips = gtk.Tooltips()
		self.xml.get_widget('nickname_label').set_text(self.contact.name)
		self.xml.get_widget('jid_label').set_text(self.contact.jid)
		uf_sub = helpers.get_uf_sub(self.contact.sub)
		self.xml.get_widget('subscription_label').set_text(uf_sub)
		eb = self.xml.get_widget('subscription_label_eventbox')
		if self.contact.sub == 'from':
			tt_text = _("This contact is interested in your presence information, but you are not interested in his/her presence")
		elif self.contact.sub == 'to':
			tt_text = _("You are interested in the contact's presence information, but he/she is not interested in yours")
		elif self.contact.sub == 'both':
			tt_text = _("You and the contact are interested in each other's presence information")
		else: # None
			tt_text = _("You are not interested in the contact's presence, and neither he/she is interested in yours")
		tooltips.set_tip(eb, tt_text)

		label = self.xml.get_widget('ask_label')
		uf_ask = helpers.get_uf_ask(self.contact.ask)
		label.set_text(uf_ask)
		eb = self.xml.get_widget('ask_label_eventbox')
		if self.contact.ask == 'subscribe':
			tooltips.set_tip(eb,
			_("You are waiting contact's answer about your subscription request"))
		self.xml.get_widget('nickname_entry').set_text(self.contact.name)
		log = True
		if self.contact.jid in gajim.config.get_per('accounts', self.account,
			'no_log_for').split(' '):
			log = False
		checkbutton = self.xml.get_widget('log_history_checkbutton')
		checkbutton.set_active(log)
		checkbutton.connect('toggled', self.on_log_history_checkbutton_toggled)
		
		resources = '%s (%s)' % (self.contact.resource, unicode(
			self.contact.priority))
		uf_resources = self.contact.resource + _(' resource with priority ')\
			+ unicode(self.contact.priority)
		if not self.contact.status:
			self.contact.status = ''
		
		# stats holds show and status message
		stats = helpers.get_uf_show(self.contact.show)
		if self.contact.status:
			stats += ': ' + self.contact.status
		gajim.connections[self.account].request_os_info(self.contact.jid,
			self.contact.resource)
		self.os_info = {0: {'resource': self.contact.resource, 'client': '',
			'os': ''}}
		i = 1
		if gajim.contacts[self.account].has_key(self.contact.jid):
			for c in gajim.contacts[self.account][self.contact.jid]:
				if c.resource != self.contact.resource:
					resources += '\n%s (%s)' % (c.resource,
						unicode(c.priority))
					uf_resources += '\n' + c.resource + _(' resource with priority ')\
						+ unicode(c.priority)
					if not c.status:
						c.status = ''
					stats += '\n' + c.show + ': ' + c.status
					gajim.connections[self.account].request_os_info(self.contact.jid,
						c.resource)
					self.os_info[i] = {'resource': c.resource, 'client': '',
						'os': ''}
					i += 1
		self.xml.get_widget('resource_prio_label').set_text(resources)
		tip = gtk.Tooltips()
		resource_prio_label_eventbox = self.xml.get_widget(
			'resource_prio_label_eventbox')
		tip.set_tip(resource_prio_label_eventbox, uf_resources)
		
		tip = gtk.Tooltips()
		status_label_eventbox = self.xml.get_widget('status_label_eventbox')
		tip.set_tip(status_label_eventbox, stats)
		status_label = self.xml.get_widget('status_label')
		status_label.set_max_width_chars(15)
		status_label.set_text(stats)
		
		gajim.connections[self.account].request_vcard(self.contact.jid)
Example #39
0
    def _add_new_line(self, contact_name, tim, kind, show, message, subject, additional_data):
        """
        Add a new line in textbuffer
        """
        if not message and kind not in (constants.KIND_STATUS,
                constants.KIND_GCSTATUS):
            return
        buf = self.history_buffer
        end_iter = buf.get_end_iter()

        if gajim.config.get('print_time') == 'always':
            timestamp_str = gajim.config.get('time_stamp')
            timestamp_str = helpers.from_one_line(timestamp_str)
            tim = time.strftime(timestamp_str, time.localtime(float(tim)))
            buf.insert(end_iter, tim) # add time
        elif gajim.config.get('print_time') == 'sometimes':
            every_foo_seconds = 60 * gajim.config.get(
                    'print_ichat_every_foo_minutes')
            seconds_passed = tim - self.last_time_printout
            if seconds_passed > every_foo_seconds:
                self.last_time_printout = tim
                tim = time.strftime('%X ', time.localtime(float(tim)))
                buf.insert_with_tags_by_name(end_iter, tim + '\n',
                        'time_sometimes')
        else: # don't print time. So we print it as invisible to be able to
              # search for it
            timestamp_str = gajim.config.get('time_stamp')
            timestamp_str = helpers.from_one_line(timestamp_str)
            tim = time.strftime(timestamp_str, time.localtime(float(tim)))
            buf.insert_with_tags_by_name(end_iter, tim, 'invisible')

        tag_name = ''
        tag_msg = ''

        show = self._get_string_show_from_constant_int(show)

        if kind == constants.KIND_GC_MSG:
            tag_name = 'incoming'
        elif kind in (constants.KIND_SINGLE_MSG_RECV,
        constants.KIND_CHAT_MSG_RECV):
            contact_name = self.completion_dict[self.jid][C_INFO_NAME]
            tag_name = 'incoming'
            tag_msg = 'incomingtxt'
        elif kind in (constants.KIND_SINGLE_MSG_SENT,
        constants.KIND_CHAT_MSG_SENT):
            if self.account:
                contact_name = gajim.nicks[self.account]
            else:
                # we don't have roster, we don't know our own nick, use first
                # account one (urk!)
                account = list(gajim.contacts.get_accounts())[0]
                contact_name = gajim.nicks[account]
            tag_name = 'outgoing'
            tag_msg = 'outgoingtxt'
        elif kind == constants.KIND_GCSTATUS:
            # message here (if not None) is status message
            if message:
                message = _('%(nick)s is now %(status)s: %(status_msg)s') %\
                        {'nick': contact_name, 'status': helpers.get_uf_show(show),
                        'status_msg': message }
            else:
                message = _('%(nick)s is now %(status)s') % {'nick': contact_name,
                        'status': helpers.get_uf_show(show) }
            tag_msg = 'status'
        else: # 'status'
            # message here (if not None) is status message
            if show is None: # it means error
                if message:
                    message = _('Error: %s') % message
                else:
                    message = _('Error')
            elif message:
                message = _('Status is now: %(status)s: %(status_msg)s') % \
                        {'status': helpers.get_uf_show(show), 'status_msg': message}
            else:
                message = _('Status is now: %(status)s') % { 'status':
                        helpers.get_uf_show(show) }
            tag_msg = 'status'

        if message.startswith('/me ') or message.startswith('/me\n'):
            tag_msg = tag_name
        else:
            # do not do this if gcstats, avoid dupping contact_name
            # eg. nkour: nkour is now Offline
            if contact_name and kind != constants.KIND_GCSTATUS:
                # add stuff before and after contact name
                before_str = gajim.config.get('before_nickname')
                before_str = helpers.from_one_line(before_str)
                after_str = gajim.config.get('after_nickname')
                after_str = helpers.from_one_line(after_str)
                format = before_str + contact_name + after_str + ' '
                if tag_name:
                    buf.insert_with_tags_by_name(end_iter, format, tag_name)
                else:
                    buf.insert(end_iter, format)
        if subject:
            message = _('Subject: %s\n') % subject + message
        xhtml = None
        if message.startswith('<body '):
            xhtml = message

        if tag_msg:
            self.history_textview.print_real_text(message, [tag_msg],
                    name=contact_name, xhtml=xhtml, additional_data=additional_data)
        else:
            self.history_textview.print_real_text(message, name=contact_name,
                xhtml=xhtml, additional_data=additional_data)
        buffer_ = self.history_textview.tv.get_buffer()
        eob = buffer_.get_end_iter()
        buffer_.insert_with_tags_by_name(eob, '\n', 'eol')
Example #40
0
def get_transport_menu(contact, account):
    roster = gajim.interface.roster
    jid = contact.jid

    menu = Gtk.Menu()

    # Send single message
    item = Gtk.MenuItem.new_with_mnemonic(_('Send Single _Message...'))
    item.connect('activate', roster.on_send_single_message_menuitem_activate,
        account, contact)
    menu.append(item)
    if 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.MenuItem.new_with_mnemonic(
        _('Send Cus_tom Status'))
    if blocked:
        send_custom_status_menuitem.set_sensitive(False)
    else:
        status_menuitems = Gtk.Menu()
        send_custom_status_menuitem.set_submenu(status_menuitems)
        for s in ('online', 'chat', 'away', 'xa', 'dnd', 'offline'):
            status_menuitem = Gtk.MenuItem.new_with_label(helpers.get_uf_show(
                s))
            status_menuitem.connect('activate', roster.on_send_custom_status,
                [(contact, account)], s)
            status_menuitems.append(status_menuitem)
    menu.append(send_custom_status_menuitem)
    if gajim.account_is_disconnected(account):
        send_custom_status_menuitem.set_sensitive(False)

    item = Gtk.SeparatorMenuItem.new() # separator
    menu.append(item)

    # Execute Command
    item = Gtk.MenuItem.new_with_mnemonic(_('E_xecute Command...'))
    menu.append(item)
    item.connect('activate', roster.on_execute_command, contact, account,
        contact.resource)
    if gajim.account_is_disconnected(account):
        item.set_sensitive(False)

    # Manage Transport submenu
    item = Gtk.MenuItem.new_with_mnemonic(_('_Manage Transport'))
    manage_transport_submenu = Gtk.Menu()
    item.set_submenu(manage_transport_submenu)
    menu.append(item)

    # Modify Transport
    item = Gtk.MenuItem.new_with_mnemonic(_('_Modify Transport'))
    manage_transport_submenu.append(item)
    item.connect('activate', roster.on_edit_agent, contact, account)
    if gajim.account_is_disconnected(account):
        item.set_sensitive(False)

    # Rename
    item = Gtk.MenuItem.new_with_mnemonic(_('_Rename...'))
    manage_transport_submenu.append(item)
    item.connect('activate', roster.on_rename, 'agent', jid, account)
    if gajim.account_is_disconnected(account):
        item.set_sensitive(False)

    item = Gtk.SeparatorMenuItem.new() # separator
    manage_transport_submenu.append(item)

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

    manage_transport_submenu.append(item)
    if gajim.account_is_disconnected(account):
        item.set_sensitive(False)

    # Remove
    item = Gtk.MenuItem.new_with_mnemonic(_('Remo_ve'))
    manage_transport_submenu.append(item)
    item.connect('activate', roster.on_remove_agent, [(contact, account)])
    if gajim.account_is_disconnected(account):
        item.set_sensitive(False)

    item = Gtk.SeparatorMenuItem.new() # separator
    menu.append(item)

    # Information
    information_menuitem = Gtk.MenuItem.new_with_mnemonic(_('_Information'))
    menu.append(information_menuitem)
    information_menuitem.connect('activate', roster.on_info, contact, account)
    if gajim.account_is_disconnected(account):
        information_menuitem.set_sensitive(False)

    menu.connect('selection-done', gtkgui_helpers.destroy_widget)
    menu.show_all()
    return menu
Example #41
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)