Daniel Brötzmann pushed to branch mainwindow at gajim / gajim
Commits: cbbcac0d by wurstsalat at 2021-03-09T19:13:06+01:00 Tooltips: Remove NotificationAreaTooltip
- - - - - 16aaf747 by wurstsalat at 2021-03-09T19:13:13+01:00 Tooltips: Refactor
- - - - -
5 changed files:
- gajim/common/helpers.py - gajim/data/gui/tooltip_roster_contact.ui → gajim/data/gui/roster_tooltip.ui - gajim/gtk/roster.py - gajim/gtk/statusicon.py - gajim/gtk/tooltips.py
Changes:
===================================== gajim/common/helpers.py ===================================== @@ -714,108 +714,6 @@ def allow_sound_notification(account, sound_event): return True return False
-def get_notification_icon_tooltip_dict(): - """ - Return a dict of the form {acct: {'show': show, 'message': message, - 'event_lines': [list of text lines to show in tooltip]} - """ - # How many events before we show summarized, not per-user - max_ungrouped_events = 10 - - accounts = get_accounts_info() - - # 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 = app.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: - text = ngettext('%d message pending', - '%d messages pending', - messages[jid], - messages[jid], - messages[jid]) - contact = app.contacts.get_first_contact_from_jid( - account['name'], jid) - text += ' ' - if jid in app.gc_connected[account['name']]: - text += _('from group chat %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) - account['event_lines'].append(text) - else: - for jid in non_messages: - text = ngettext('%d event pending', - '%d events pending', - non_messages[jid], - non_messages[jid], - non_messages[jid]) - text += ' ' + _('from user %s') % (jid) - account[account]['event_lines'].append(text) - - return accounts - -def get_accounts_info(): - """ - Helper for notification icon tooltip - """ - accounts = [] - accounts_list = sorted(app.settings.get_active_accounts()) - for account in accounts_list: - - status = get_connection_status(account) - message = app.connections[account].status_message - single_line = get_uf_show(status) - if message is None: - message = '' - else: - message = message.strip() - if message != '': - single_line += ': ' + message - account_label = app.get_account_label(account) - accounts.append({'name': account, - 'account_label': account_label, - 'status_line': single_line, - 'show': status, - 'message': message}) - return accounts - def get_current_show(account): if account not in app.connections: return 'offline'
===================================== gajim/data/gui/tooltip_roster_contact.ui → gajim/data/gui/roster_tooltip.ui ===================================== @@ -1,289 +1,241 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.36.0 --> +<!-- Generated with glade 3.38.2 --> <interface> - <requires lib="gtk+" version="3.22"/> + <requires lib="gtk+" version="3.24"/> + <!-- n-columns=2 n-rows=9 --> <object class="GtkGrid" id="tooltip_grid"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> <property name="halign">start</property> - <property name="border_width">6</property> - <property name="row_spacing">3</property> - <property name="column_spacing">12</property> - <child> - <object class="GtkLabel" id="resource_label"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">end</property> - <property name="valign">start</property> - <property name="label" translatable="yes">Resource:</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">5</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="resource"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">start</property> - <property name="valign">start</property> - <property name="hexpand">True</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">5</property> - </packing> - </child> + <property name="border-width">6</property> + <property name="row-spacing">3</property> + <property name="column-spacing">12</property> <child> <object class="GtkLabel" id="jid"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> <property name="halign">start</property> <property name="valign">start</property> - <property name="hexpand">True</property> + <property name="label"><jid></property> <property name="ellipsize">end</property> - <property name="max_width_chars">36</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">1</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="idle_since_label"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">end</property> - <property name="valign">start</property> - <property name="label" translatable="yes">Idle since:</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">12</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="idle_since"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">start</property> - <property name="valign">start</property> - <property name="hexpand">True</property> + <property name="max-width-chars">36</property> + <property name="xalign">0</property> </object> <packing> - <property name="left_attach">1</property> - <property name="top_attach">12</property> + <property name="left-attach">1</property> + <property name="top-attach">1</property> </packing> </child> <child> <object class="GtkLabel" id="mood_label"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> <property name="halign">end</property> <property name="valign">start</property> <property name="label" translatable="yes">Mood:</property> </object> <packing> - <property name="left_attach">0</property> - <property name="top_attach">6</property> + <property name="left-attach">0</property> + <property name="top-attach">3</property> </packing> </child> <child> <object class="GtkLabel" id="activity_label"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> <property name="halign">end</property> <property name="valign">start</property> <property name="label" translatable="yes">Activity:</property> <property name="lines">2</property> </object> <packing> - <property name="left_attach">0</property> - <property name="top_attach">7</property> + <property name="left-attach">0</property> + <property name="top-attach">4</property> </packing> </child> <child> <object class="GtkLabel" id="tune_label"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> <property name="halign">end</property> <property name="valign">start</property> <property name="label" translatable="yes">Tune:</property> </object> <packing> - <property name="left_attach">0</property> - <property name="top_attach">8</property> + <property name="left-attach">0</property> + <property name="top-attach">5</property> </packing> </child> <child> <object class="GtkLabel" id="location_label"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> <property name="halign">end</property> <property name="valign">start</property> <property name="label" translatable="yes">Location:</property> </object> <packing> - <property name="left_attach">0</property> - <property name="top_attach">9</property> + <property name="left-attach">0</property> + <property name="top-attach">6</property> </packing> </child> <child> <object class="GtkLabel" id="mood"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> <property name="halign">start</property> <property name="valign">start</property> <property name="hexpand">True</property> </object> <packing> - <property name="left_attach">1</property> - <property name="top_attach">6</property> + <property name="left-attach">1</property> + <property name="top-attach">3</property> </packing> </child> <child> <object class="GtkLabel" id="activity"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> <property name="halign">start</property> <property name="valign">start</property> <property name="hexpand">True</property> </object> <packing> - <property name="left_attach">1</property> - <property name="top_attach">7</property> + <property name="left-attach">1</property> + <property name="top-attach">4</property> </packing> </child> <child> <object class="GtkLabel" id="tune"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> <property name="halign">start</property> <property name="valign">start</property> <property name="hexpand">True</property> </object> <packing> - <property name="left_attach">1</property> - <property name="top_attach">8</property> + <property name="left-attach">1</property> + <property name="top-attach">5</property> </packing> </child> <child> <object class="GtkLabel" id="location"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> <property name="halign">start</property> <property name="valign">start</property> <property name="hexpand">True</property> </object> <packing> - <property name="left_attach">1</property> - <property name="top_attach">9</property> + <property name="left-attach">1</property> + <property name="top-attach">6</property> </packing> </child> <child> - <object class="GtkLabel" id="sub_label"> + <object class="GtkLabel" id="name"> <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">end</property> + <property name="can-focus">False</property> + <property name="halign">start</property> <property name="valign">start</property> - <property name="label" translatable="yes">Subscription:</property> + <property name="label"><name></property> + <property name="ellipsize">end</property> + <property name="single-line-mode">True</property> + <property name="max-width-chars">25</property> + <property name="yalign">0</property> + <style> + <class name="large-header"/> + </style> </object> <packing> - <property name="left_attach">0</property> - <property name="top_attach">11</property> + <property name="left-attach">1</property> + <property name="top-attach">0</property> </packing> </child> <child> - <object class="GtkLabel" id="sub"> + <object class="GtkImage" id="avatar"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> <property name="halign">start</property> <property name="valign">start</property> - <property name="hexpand">True</property> + <property name="icon-name">image-missing</property> + <property name="icon_size">6</property> </object> <packing> - <property name="left_attach">1</property> - <property name="top_attach">11</property> + <property name="left-attach">0</property> + <property name="top-attach">0</property> + <property name="height">3</property> </packing> </child> <child> - <object class="GtkLabel" id="status"> + <object class="GtkLabel" id="sub_label"> <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">start</property> + <property name="can-focus">False</property> + <property name="halign">end</property> <property name="valign">start</property> - <property name="wrap">True</property> - <property name="wrap_mode">word-char</property> - <property name="ellipsize">end</property> - <property name="max_width_chars">40</property> - <property name="lines">3</property> - <property name="xalign">0</property> - <attributes> - <attribute name="style" value="italic"/> - </attributes> + <property name="label" translatable="yes">Subscription:</property> </object> <packing> - <property name="left_attach">1</property> - <property name="top_attach">4</property> + <property name="left-attach">0</property> + <property name="top-attach">7</property> </packing> </child> <child> - <object class="GtkLabel" id="name"> + <object class="GtkLabel" id="sub"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> <property name="halign">start</property> <property name="valign">start</property> - <property name="ellipsize">end</property> - <property name="single_line_mode">True</property> - <property name="max_width_chars">25</property> - <style> - <class name="large-header"/> - </style> + <property name="hexpand">True</property> </object> <packing> - <property name="left_attach">1</property> - <property name="top_attach">0</property> + <property name="left-attach">1</property> + <property name="top-attach">7</property> </packing> </child> <child> - <object class="GtkLabel" id="user_show"> + <object class="GtkLabel" id="idle_since_label"> <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">start</property> + <property name="can-focus">False</property> + <property name="halign">end</property> <property name="valign">start</property> - <property name="vexpand">True</property> + <property name="label" translatable="yes">Idle since:</property> </object> <packing> - <property name="left_attach">1</property> - <property name="top_attach">2</property> + <property name="left-attach">0</property> + <property name="top-attach">8</property> </packing> </child> <child> - <object class="GtkImage" id="avatar"> + <object class="GtkLabel" id="idle_since"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> <property name="halign">start</property> <property name="valign">start</property> - <property name="icon_name">image-missing</property> + <property name="hexpand">True</property> </object> <packing> - <property name="left_attach">0</property> - <property name="top_attach">0</property> - <property name="height">5</property> + <property name="left-attach">1</property> + <property name="top-attach">8</property> </packing> </child> <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> + <!-- n-columns=2 n-rows=1 --> + <object class="GtkGrid" id="resource_grid"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="halign">start</property> + <property name="valign">start</property> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + </object> + <packing> + <property name="left-attach">1</property> + <property name="top-attach">2</property> + </packing> </child> </object> </interface>
===================================== gajim/gtk/roster.py ===================================== @@ -19,6 +19,7 @@
from gajim.gui_menu_builder import get_roster_menu
+from .tooltips import RosterTooltip from .util import EventHelper from .util import get_builder
@@ -49,6 +50,8 @@ def __init__(self, account): self._account = account self._client = app.get_client(account)
+ self._roster_tooltip = RosterTooltip() + self._ui = get_builder('roster.ui') self._ui.roster_treeview.set_model(None) self.add(self._ui.roster_treeview) @@ -62,6 +65,8 @@ def __init__(self, account): self._store.set_sort_func(Column.TEXT, self._tree_compare_iters)
self._roster = self._ui.roster_treeview + self._roster.set_has_tooltip(True) + self._roster.connect('query-tooltip', self._on_query_tooltip)
# Drag and Drop entries = [Gtk.TargetEntry.new( @@ -214,6 +219,37 @@ def _on_drag_data_received(self, treeview, _drag_context, x_coord, source_group, dest_group)
+ def _on_query_tooltip(self, treeview, x_coord, y_coord, _keyboard_mode, + tooltip): + try: + path = treeview.get_path_at_pos(x_coord, y_coord) + row = path[0] + except TypeError: + self._roster_tooltip.clear_tooltip() + return False + + if not row: + self._roster_tooltip.clear_tooltip() + return False + + iter_ = None + try: + model = treeview.get_model() + iter_ = model.get_iter(row) + except Exception: + self._roster_tooltip.clear_tooltip() + return False + + if not model[iter_][Column.IS_CONTACT]: + # It’s a group + self._roster_tooltip.clear_tooltip() + return False + + contact = self._get_contact(model[iter_][Column.JID_OR_GROUP]) + value, widget = self._roster_tooltip.get_tooltip(row, contact) + tooltip.set_custom(widget) + return value + def _on_show_offline(self, action, param): action.set_state(param) app.settings.set('showoffline', param.get_boolean())
===================================== gajim/gtk/statusicon.py ===================================== @@ -34,7 +34,6 @@ from .util import restore_roster_position from .util import open_window from .single_message import SingleMessageWindow -from .tooltips import NotificationAreaTooltip
class StatusIcon: @@ -53,16 +52,13 @@ def __init__(self): self._ui.connect_signals(self) self.popup_menus = [] self.status_icon = None - self.tooltip = NotificationAreaTooltip() self._icon_size = '16'
def show_icon(self): if not self.status_icon: self.status_icon = Gtk.StatusIcon() - self.status_icon.set_property('has-tooltip', True) self.status_icon.connect('activate', self._on_activate) self.status_icon.connect('popup-menu', self._on_popup_menu) - self.status_icon.connect('query-tooltip', self._on_query_tooltip) self.status_icon.connect('size-changed', self.set_img)
self.set_img() @@ -108,10 +104,6 @@ def _on_event_removed(self, _event_list): """ self.set_img()
- def _on_query_tooltip(self, _status_icon, _x, _y, _keyboard_mode, tooltip): - tooltip.set_custom(self.tooltip.get_tooltip()) - return True - def _on_popup_menu(self, _status_icon, button, activate_time): if button == 1: # Left click self._on_left_click() @@ -137,7 +129,7 @@ def on_status_icon_size_changed(self, _statusicon, size):
def set_img(self, *args): """ - Apart from image, we also update tooltip text here + Update image """ if not app.interface.systray_enabled: return
===================================== gajim/gtk/tooltips.py ===================================== @@ -35,129 +35,24 @@
from gajim.common import app from gajim.common import helpers -from gajim.common.helpers import get_connection_status from gajim.common.const import AvatarSize from gajim.common.const import PEPEventType from gajim.common.i18n import Q_ from gajim.common.i18n import _ from gajim.gtkgui_helpers import add_css_class
+from .avatar import get_show_circle from .util import get_builder -from .util import get_icon_name from .util import format_mood from .util import format_activity from .util import format_tune from .util import format_location from .util import get_css_show_class
- log = logging.getLogger('gajim.gui.tooltips')
-class StatusTable: - """ - Contains methods for creating status table. This is used in Roster and - NotificationArea tooltips - """ - - def __init__(self): - self.current_row = 0 - self.table = None - self.text_label = None - self.spacer_label = ' ' - - def create_table(self): - self.table = Gtk.Grid() - self.table.insert_column(0) - self.table.set_property('column-spacing', 3) - - def add_text_row(self, text, col_inc=0): - self.table.insert_row(self.current_row) - self.text_label = Gtk.Label() - self.text_label.set_line_wrap(True) - self.text_label.set_line_wrap_mode(Pango.WrapMode.WORD_CHAR) - self.text_label.set_lines(3) - self.text_label.set_ellipsize(Pango.EllipsizeMode.END) - self.text_label.set_max_width_chars(30) - self.text_label.set_halign(Gtk.Align.START) - self.text_label.set_valign(Gtk.Align.START) - self.text_label.set_xalign(0) - self.text_label.set_selectable(False) - - self.text_label.set_text(text) - self.table.attach(self.text_label, 1 + col_inc, - self.current_row, - 3 - col_inc, - 1) - self.current_row += 1 - - def add_status_row(self, show, str_status, indent=True, transport=None): - """ - Append a new row with status icon to the table - """ - self.table.insert_row(self.current_row) - image = Gtk.Image() - icon_name = get_icon_name(show, transport=transport) - image.set_from_icon_name(icon_name, Gtk.IconSize.MENU) - spacer = Gtk.Label(label=self.spacer_label) - image.set_halign(Gtk.Align.START) - image.set_valign(Gtk.Align.CENTER) - if indent: - self.table.attach(spacer, 1, self.current_row, 1, 1) - self.table.attach(image, 2, self.current_row, 1, 1) - status_label = Gtk.Label() - status_label.set_text(str_status) - status_label.set_halign(Gtk.Align.START) - status_label.set_valign(Gtk.Align.START) - status_label.set_xalign(0) - status_label.set_line_wrap(True) - status_label.set_line_wrap_mode(Pango.WrapMode.WORD_CHAR) - status_label.set_lines(3) - status_label.set_ellipsize(Pango.EllipsizeMode.END) - status_label.set_max_width_chars(30) - self.table.attach(status_label, 3, self.current_row, 1, 1) - self.current_row += 1 - - def fill_table_with_accounts(self, accounts): - for acct in accounts: - message = acct['message'] - message = helpers.reduce_chars_newlines(message, 100, 1) - message = GLib.markup_escape_text(message) - - account_label = GLib.markup_escape_text(acct['account_label']) - if message: - status = '%s - %s' % (account_label, message) - else: - status = account_label - - self.add_status_row(acct['show'], status, indent=False) - - for line in acct['event_lines']: - self.add_text_row(' ' + line, 1) - - -class NotificationAreaTooltip(StatusTable): - """ - Tooltip that is shown in the notification area - """ - - def __init__(self): - StatusTable.__init__(self) - - def get_tooltip(self): - self.create_table() - - accounts = helpers.get_notification_icon_tooltip_dict() - self.fill_table_with_accounts(accounts) - self.table.set_property('column-spacing', 1) - - hbox = Gtk.HBox() - hbox.add(self.table) - hbox.show_all() - return hbox - - -class GCTooltip(): +class GCTooltip: def __init__(self): self.contact = None
@@ -231,198 +126,113 @@ def destroy(self): self._ui.tooltip_grid.destroy()
-class RosterTooltip(StatusTable): +class RosterTooltip: def __init__(self): - StatusTable.__init__(self) - self.create_table() - self.account = None - self.row = None - self.contact_jid = None - self.prim_contact = None - self.last_widget = None - self.num_resources = 0 - - self._ui = get_builder('tooltip_roster_contact.ui') + self._row = None + self._ui = get_builder('roster_tooltip.ui')
def clear_tooltip(self): - """ - Hide all Elements of the Tooltip Grid - """ - for child in self._ui.tooltip_grid.get_children(): - child.hide() - status_table = self._ui.tooltip_grid.get_child_at(1, 3) - if status_table: - status_table.destroy() - self.create_table() - self.row = None - - def get_tooltip(self, row, connected_contacts, account, typ): - if self.row == row: + self._row = None + for widget in self._ui.resource_grid.get_children(): + widget.destroy() + for widget in self._ui.tooltip_grid.get_children(): + widget.hide() + + def get_tooltip(self, row, contact): + if self._row == row: return True, self._ui.tooltip_grid
- self._populate_grid(connected_contacts, account, typ) - self.row = row + self._populate_grid(contact) + self._row = row return False, self._ui.tooltip_grid
- def _populate_grid(self, contacts, account, typ): - """ - Populate the Tooltip Grid with data of from the contact - """ - self.current_row = 0 - self.account = account - if self.last_widget: - self.last_widget.set_vexpand(False) - + def _populate_grid(self, contact): self.clear_tooltip() + scale = self._ui.tooltip_grid.get_scale_factor()
- if account == 'all': - # Tooltip for merged accounts row - self._show_merged_account_tooltip() - return - - if typ == 'account': - jid = app.get_jid_from_account(account) - contacts = [] - connection = app.connections[account] - # get our current contact info - - nbr_on, nbr_total = app.\ - contacts.get_nb_online_total_contacts(accounts=[account]) - account_name = app.get_account_label(account) - if app.account_is_available(account): - account_name += ' (%s/%s)' % (repr(nbr_on), repr(nbr_total)) - contact = app.contacts.create_self_contact( - jid=jid, - account=account, - name=account_name, - show=get_connection_status(account), - status=connection.status_message, - resource=connection.get_own_jid().resource, - priority=connection.priority) - - contacts.append(contact) - - # Username/Account/Groupchat - self.prim_contact = app.contacts.get_highest_prio_contact_from_contacts( - contacts) - if self.prim_contact is None: - log.error('No contact for Roster tooltip found') - log.error('contacts: %s, typ: %s, account: %s', - contacts, typ, account) - return - self.contact_jid = self.prim_contact.jid - name = GLib.markup_escape_text(self.prim_contact.get_shown_name()) - - if app.settings.get('mergeaccounts'): - name = GLib.markup_escape_text( - self.prim_contact.account.name) - - self._ui.name.set_markup(name) - self._ui.name.show() + # Avatar + surface = contact.get_avatar(AvatarSize.TOOLTIP, scale) + self._ui.avatar.set_from_surface(surface) + self._ui.avatar.show()
- self.num_resources = 0 - # put contacts in dict, where key is priority - contacts_dict = {} - for contact in contacts: - if contact.resource: - self.num_resources += 1 - priority = int(contact.priority) - if priority in contacts_dict: - contacts_dict[priority].append(contact) - else: - contacts_dict[priority] = [contact] - if self.num_resources > 1: - transport = app.get_transport_name_from_jid(self.prim_contact.jid) - if transport == 'jabber': - transport = None - contact_keys = sorted(contacts_dict.keys()) - contact_keys.reverse() - for priority in contact_keys: - for acontact in contacts_dict[priority]: - show = self._get_icon_name_for_tooltip(acontact) - status = acontact.status - resource_line = '%s (%s)' % (acontact.resource, - str(acontact.priority)) - self.add_status_row( - show, resource_line, transport=transport) - if status: - self.add_text_row(status, 2) - - self._ui.tooltip_grid.attach(self.table, 1, 3, 2, 1) - self.table.show_all() - - else: # only one resource - if contact.is_groupchat: - disco_info = app.storage.cache.get_last_disco_info(contact.jid) - if disco_info is not None: - description = disco_info.muc_description - if description: - self._ui.status.set_text(description) - self._ui.status.show() - elif contact.show and contact.status: - status = contact.status.strip() - if status: - self._ui.status.set_text(status) - self._ui.status.show() - - # PEP Info - self._append_pep_info(contact) + # Name + self._ui.name.set_markup(GLib.markup_escape_text(contact.name)) + self._ui.name.show()
# JID - self._ui.jid.set_text(self.prim_contact.jid) + self._ui.jid.set_text(str(contact.jid)) self._ui.jid.show()
- # contact has only one resource - if self.num_resources == 1 and contact.resource: - res = GLib.markup_escape_text(contact.resource) - prio = str(contact.priority) - self._ui.resource.set_text("{} ({})".format(res, prio)) - self._ui.resource.show() - self._ui.resource_label.show() - - if self.prim_contact.jid not in app.gc_connected[account]: - if (account and - self.prim_contact.sub and - self.prim_contact.sub != 'both'): - # ('both' is the normal sub so we don't show it) - self._ui.sub.set_text(helpers.get_uf_sub(self.prim_contact.sub)) - self._ui.sub.show() - self._ui.sub_label.show() - - self._set_idle_time(contact) + # Resources with show, status, priority + resources = contact.get_resources() + self._build_resource_grid(resources, scale)
- # Avatar - scale = self._ui.tooltip_grid.get_scale_factor() - surface = app.contacts.get_avatar( - account, self.prim_contact.jid, AvatarSize.TOOLTIP, scale) - self._ui.avatar.set_from_surface(surface) - self._ui.avatar.show() + # Subscription + if contact.subscription and contact.subscription != 'both': + # 'both' is the normal subscription value, just omit it + self._ui.sub.set_text(helpers.get_uf_sub(contact.subscription)) + self._ui.sub.show() + self._ui.sub_label.show() + + # Idle time + # TODO + # self._set_idle_time(contact) + + # PEP info + # TODO + # self._append_pep_info(contact)
app.plugin_manager.gui_extension_point( - 'roster_tooltip_populate', self, contacts, self._ui.tooltip_grid) - - # Sets the Widget that is at the bottom to expand. - # This is needed in case the Picture takes more Space than the Labels - i = 1 - while i < 15: - if self._ui.tooltip_grid.get_child_at(1, i): - if self._ui.tooltip_grid.get_child_at(1, i).get_visible(): - self.last_widget = self._ui.tooltip_grid.get_child_at(1, i) - i += 1 - self.last_widget.set_vexpand(True) - - def _show_merged_account_tooltip(self): - accounts = helpers.get_notification_icon_tooltip_dict() - self.spacer_label = '' - self.fill_table_with_accounts(accounts) - self._ui.tooltip_grid.attach(self.table, 1, 3, 2, 1) - self.table.show_all() + 'roster_tooltip_populate', self, contact, self._ui.tooltip_grid) + + # This sets the bottom-most widget to expand, in case the avatar + # takes more space than the labels + row_count = 1 + while row_count < 9: + widget = self._ui.tooltip_grid.get_child_at(1, row_count) + if widget and widget.get_visible(): + last_widget = widget + row_count += 1 + else: + break + last_widget.set_vexpand(True) + + def _build_resource_grid(self, resources, scale): + row_num = 0 + for contact in resources: + show_surface = get_show_circle( + contact.show, AvatarSize.ROSTER, scale) + show_image = Gtk.Image.new_from_surface(show_surface) + show_image.set_halign(Gtk.Align.START) + show_image.set_valign(Gtk.Align.CENTER) + self._ui.resource_grid.attach(show_image, 0, row_num, 1, 1) + + resource_string = GLib.markup_escape_text(contact.jid.resource) + resource_label = Gtk.Label() + resource_label.set_halign(Gtk.Align.START) + resource_label.set_xalign(0) + resource_label.set_ellipsize(Pango.EllipsizeMode.END) + resource_label.set_max_width_chars(30) + resource_label.set_text(f'{resource_string} ({contact.priority})') + self._ui.resource_grid.attach(resource_label, 1, row_num, 1, 1) + + if contact.status: + row_num += 1 + status_text = GLib.markup_escape_text(contact.status) + status_label = Gtk.Label() + status_label.set_halign(Gtk.Align.START) + status_label.set_xalign(0) + status_label.set_ellipsize(Pango.EllipsizeMode.END) + status_label.set_max_width_chars(30) + status_label.set_text(status_text) + self._ui.resource_grid.attach( + status_label, 1, row_num, 1, 1) + + row_num += 1 + + self._ui.resource_grid.show_all()
def _append_pep_info(self, contact): - """ - Append Tune, Mood, Activity, Location information of the - specified contact to the given property list. - """ if PEPEventType.MOOD in contact.pep: mood = format_mood(*contact.pep[PEPEventType.MOOD]) self._ui.mood.set_markup(mood) @@ -461,36 +271,8 @@ def _set_idle_time(self, contact): self._ui.idle_since.show() self._ui.idle_since_label.show()
- if contact.show and self.num_resources < 2: - show = helpers.get_uf_show(contact.show) - # Contact is Groupchat - if (self.account and - self.prim_contact.jid in app.gc_connected[self.account]): - if app.gc_connected[self.account][self.prim_contact.jid]: - show = _('Connected') - else: - show = _('Disconnected') - - colorize_status(self._ui.user_show, contact.show) - self._ui.user_show.set_text(show) - self._ui.user_show.show() - - @staticmethod - def _get_icon_name_for_tooltip(contact): - """ - Helper function used for tooltip contacts/accounts - - Tooltip on account has fake contact with sub == '', in this case we show - real status of the account - """ - if contact.ask == 'subscribe': - return 'requested' - if contact.sub in ('both', 'to', ''): - return contact.show - return 'not in roster' -
-class FileTransfersTooltip(): +class FileTransfersTooltip: def __init__(self): self.sid = None self.widget = None
View it on GitLab: https://dev.gajim.org/gajim/gajim/-/compare/74fc36e644c0dfe4988a14c31ed201d3...