From 20965b9ba583c7c760bde64d11ec45564135b13d Mon Sep 17 00:00:00 2001 From: Yann Leboulanger Date: Tue, 3 Jul 2007 09:31:43 +0000 Subject: [PATCH] [lukas and I] improve tooltip to show info about pending events. fixes #1971 --- src/common/helpers.py | 164 ++++++++++++++++++++++++++++-------------- src/tooltips.py | 15 ++-- 2 files changed, 120 insertions(+), 59 deletions(-) diff --git a/src/common/helpers.py b/src/common/helpers.py index 12865a24d..bfc9ec7ff 100644 --- a/src/common/helpers.py +++ b/src/common/helpers.py @@ -5,6 +5,7 @@ ## Copyright (C) 2005 ## Dimitur Kirov ## Travis Shirk +## Copyright (C) 2007 Lukas Petrovicky ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published @@ -874,62 +875,121 @@ def reduce_chars_newlines(text, max_chars = 0, max_lines = 0): reduced_text = '' return reduced_text -def get_notification_icon_tooltip_text(): - text = None - unread_chat = gajim.events.get_nb_events(types = ['printed_chat', - 'chat']) - unread_single_chat = gajim.events.get_nb_events(types = ['normal']) - unread_gc = gajim.events.get_nb_events(types = ['printed_gc_msg', - 'printed_marked_gc_msg', 'gc_msg']) - unread_pm = gajim.events.get_nb_events(types = ['printed_pm', 'pm']) +def get_account_status(account): + status = reduce_chars_newlines(account['status_line'], 100, 1) + return status + +def get_notification_icon_tooltip_dict(): + '''returns a dict of the form {acct: {'show': show, 'message': message, + 'event_lines': [list of text lines to show in tooltip]}''' + # How many events must there be before they're shown summarized, not per-user + max_ungrouped_events = 10 accounts = get_accounts_info() - if unread_chat or unread_single_chat or unread_gc or unread_pm: - text = 'Gajim ' - awaiting_events = unread_chat + unread_single_chat + unread_gc + unread_pm - if awaiting_events == unread_chat or awaiting_events == unread_single_chat \ - or awaiting_events == unread_gc or awaiting_events == unread_pm: - # This condition is like previous if but with xor... - # Print in one line - text += '-' - else: - # Print in multiple lines - text += '\n ' - if unread_chat: - text += ngettext( - ' %d unread message', - ' %d unread messages', - unread_chat, unread_chat, unread_chat) - text += '\n ' - if unread_single_chat: - text += ngettext( - ' %d unread single message', - ' %d unread single messages', - unread_single_chat, unread_single_chat, unread_single_chat) - text += '\n ' - if unread_gc: - text += ngettext( - ' %d unread group chat message', - ' %d unread group chat messages', - unread_gc, unread_gc, unread_gc) - text += '\n ' - if unread_pm: - text += ngettext( - ' %d unread private message', - ' %d unread private messages', - unread_pm, unread_pm, unread_pm) - text += '\n ' - text = text[:-4] # remove latest '\n ' - elif len(accounts) > 1: - text = _('Gajim') - elif len(accounts) == 1: - message = accounts[0]['status_line'] - message = reduce_chars_newlines(message, 100, 1) - text = _('Gajim - %s') % message - else: - text = _('Gajim - %s') % get_uf_show('offline') + # Gather events. (With accounts, when there are more.) + for account in accounts: + account_name = account['name'] + account['event_lines'] = [] + # Gather events per-account + pending_events = gajim.events.get_events(account = account_name) + messages, non_messages, total_messages, total_non_messages = {}, {}, 0, 0 + for jid in pending_events: + for event in pending_events[jid]: + if event.type_.count('file') > 0: + # This is a non-messagee event. + messages[jid] = non_messages.get(jid, 0) + 1 + total_non_messages = total_non_messages + 1 + else: + # This is a message. + messages[jid] = messages.get(jid, 0) + 1 + total_messages = total_messages + 1 + # Display unread messages numbers, if any + if total_messages > 0: + if total_messages > max_ungrouped_events: + text = ngettext( + '%d message pending', + '%d messages pending', + total_messages, total_messages, total_messages) + account['event_lines'].append(text) + else: + for jid in messages.keys(): + text = ngettext( + '%d message pending', + '%d messages pending', + messages[jid], messages[jid], messages[jid]) + contact = gajim.contacts.get_first_contact_from_jid( + account['name'], jid) + if jid in gajim.gc_connected[account['name']]: + text += _(' from room %s') % (jid) + elif contact: + name = contact.get_shown_name() + text += _(' from user %s') % (name) + else: + text += _(' from %s') % (jid) + account['event_lines'].append(text) + # Display unseen events numbers, if any + if total_non_messages > 0: + if total_non_messages > max_ungrouped_events: + text = ngettext( + '%d event pending', + '%d events pending', + total_non_messages, total_non_messages, total_non_messages) + accounts[account]['event_lines'].append(text) + else: + for jid in non_messages.keys(): + text = ngettext( + '%d event pending', + '%d events pending', + non_messages[jid], non_messages[jid], non_messages[jid]) + text += _(' from user %s') % (jid) + accounts[account]['event_lines'].append(text) + + return accounts + +def get_notification_icon_tooltip_text(): + text = None + # How many events must there be before they're shown summarized, not per-user + max_ungrouped_events = 10 + # Character which should be used to indent in the tooltip. + indent_with = ' ' + + accounts = get_notification_icon_tooltip_dict() + + if len(accounts) == 0: + # No configured account + return _('Gajim') + + # at least one account present + + # Is there more that one account? + if len(accounts) == 1: + show_more_accounts = False + else: + show_more_accounts = True + + # If there is only one account, its status is shown on the first line. + if show_more_accounts: + text = _('Gajim') + else: + text = _('Gajim - %s') % (get_account_status(accounts[0])) + + # Gather and display events. (With accounts, when there are more.) + for account in accounts: + account_name = account['name'] + # Set account status, if not set above + if (show_more_accounts): + message = '\n' + indent_with + ' %s - %s' + text += message % (account_name, get_account_status(account)) + # Account list shown, messages need to be indented more + indent_how = 2 + else: + # If no account list is shown, messages could have default indenting. + indent_how = 1 + for line in account['event_lines']: + text += '\n' + indent_with * indent_how + ' ' + text += line return text def get_accounts_info(): diff --git a/src/tooltips.py b/src/tooltips.py index 3d9812be3..5b9c101b2 100644 --- a/src/tooltips.py +++ b/src/tooltips.py @@ -160,13 +160,15 @@ class StatusTable: self.table = gtk.Table(4, 1) self.table.set_property('column-spacing', 2) - def add_text_row(self, text): + def add_text_row(self, text, col_inc = 0): + self.current_row += 1 self.text_label = gtk.Label() self.text_label.set_line_wrap(True) self.text_label.set_alignment(0, 0) self.text_label.set_selectable(False) self.text_label.set_markup(text) - self.table.attach(self.text_label, 1, 4, 1, 2) + self.table.attach(self.text_label, 1 + col_inc, 4, self.current_row, + self.current_row + 1) def get_status_info(self, resource, priority, show, status): str_status = resource + ' (' + unicode(priority) + ')' @@ -247,21 +249,20 @@ class NotificationAreaTooltip(BaseTooltip, StatusTable): self.add_status_row(file_path, acct['show'], gobject.markup_escape_text(acct['name']) , show_lock=show_lock) + for line in acct['event_lines']: + self.add_text_row(' ' + line, 2) def populate(self, data): self.create_window() self.create_table() - accounts = helpers.get_accounts_info() + + accounts = helpers.get_notification_icon_tooltip_dict() if len(accounts) > 1: self.table.resize(2, 1) self.fill_table_with_accounts(accounts) self.hbox = gtk.HBox() self.table.set_property('column-spacing', 1) - text = helpers.get_notification_icon_tooltip_text() - text = gobject.markup_escape_text(text) - - self.add_text_row(text) self.hbox.add(self.table) self.win.add(self.hbox)