Daniel Brötzmann pushed to branch mainwindow at gajim / gajim

Commits:

5 changed files:

Changes:

  • gajim/common/helpers.py
    ... ... @@ -714,108 +714,6 @@ def allow_sound_notification(account, sound_event):
    714 714
             return True
    
    715 715
         return False
    
    716 716
     
    
    717
    -def get_notification_icon_tooltip_dict():
    
    718
    -    """
    
    719
    -    Return a dict of the form {acct: {'show': show, 'message': message,
    
    720
    -    'event_lines': [list of text lines to show in tooltip]}
    
    721
    -    """
    
    722
    -    # How many events before we show summarized, not per-user
    
    723
    -    max_ungrouped_events = 10
    
    724
    -
    
    725
    -    accounts = get_accounts_info()
    
    726
    -
    
    727
    -    # Gather events. (With accounts, when there are more.)
    
    728
    -    for account in accounts:
    
    729
    -        account_name = account['name']
    
    730
    -        account['event_lines'] = []
    
    731
    -        # Gather events per-account
    
    732
    -        pending_events = app.events.get_events(account=account_name)
    
    733
    -        messages, non_messages = {}, {}
    
    734
    -        total_messages, total_non_messages = 0, 0
    
    735
    -        for jid in pending_events:
    
    736
    -            for event in pending_events[jid]:
    
    737
    -                if event.type_.count('file') > 0:
    
    738
    -                    # This is a non-messagee event.
    
    739
    -                    messages[jid] = non_messages.get(jid, 0) + 1
    
    740
    -                    total_non_messages = total_non_messages + 1
    
    741
    -                else:
    
    742
    -                    # This is a message.
    
    743
    -                    messages[jid] = messages.get(jid, 0) + 1
    
    744
    -                    total_messages = total_messages + 1
    
    745
    -        # Display unread messages numbers, if any
    
    746
    -        if total_messages > 0:
    
    747
    -            if total_messages > max_ungrouped_events:
    
    748
    -                text = ngettext('%d message pending',
    
    749
    -                                '%d messages pending',
    
    750
    -                                total_messages,
    
    751
    -                                total_messages,
    
    752
    -                                total_messages)
    
    753
    -                account['event_lines'].append(text)
    
    754
    -            else:
    
    755
    -                for jid in messages:
    
    756
    -                    text = ngettext('%d message pending',
    
    757
    -                                    '%d messages pending',
    
    758
    -                                    messages[jid],
    
    759
    -                                    messages[jid],
    
    760
    -                                    messages[jid])
    
    761
    -                    contact = app.contacts.get_first_contact_from_jid(
    
    762
    -                        account['name'], jid)
    
    763
    -                    text += ' '
    
    764
    -                    if jid in app.gc_connected[account['name']]:
    
    765
    -                        text += _('from group chat %s') % (jid)
    
    766
    -                    elif contact:
    
    767
    -                        name = contact.get_shown_name()
    
    768
    -                        text += _('from user %s') % (name)
    
    769
    -                    else:
    
    770
    -                        text += _('from %s') % (jid)
    
    771
    -                    account['event_lines'].append(text)
    
    772
    -
    
    773
    -        # Display unseen events numbers, if any
    
    774
    -        if total_non_messages > 0:
    
    775
    -            if total_non_messages > max_ungrouped_events:
    
    776
    -                text = ngettext('%d event pending',
    
    777
    -                                '%d events pending',
    
    778
    -                                total_non_messages,
    
    779
    -                                total_non_messages,
    
    780
    -                                total_non_messages)
    
    781
    -                account['event_lines'].append(text)
    
    782
    -            else:
    
    783
    -                for jid in non_messages:
    
    784
    -                    text = ngettext('%d event pending',
    
    785
    -                                    '%d events pending',
    
    786
    -                                    non_messages[jid],
    
    787
    -                                    non_messages[jid],
    
    788
    -                                    non_messages[jid])
    
    789
    -                    text += ' ' + _('from user %s') % (jid)
    
    790
    -                    account[account]['event_lines'].append(text)
    
    791
    -
    
    792
    -    return accounts
    
    793
    -
    
    794
    -def get_accounts_info():
    
    795
    -    """
    
    796
    -    Helper for notification icon tooltip
    
    797
    -    """
    
    798
    -    accounts = []
    
    799
    -    accounts_list = sorted(app.settings.get_active_accounts())
    
    800
    -    for account in accounts_list:
    
    801
    -
    
    802
    -        status = get_connection_status(account)
    
    803
    -        message = app.connections[account].status_message
    
    804
    -        single_line = get_uf_show(status)
    
    805
    -        if message is None:
    
    806
    -            message = ''
    
    807
    -        else:
    
    808
    -            message = message.strip()
    
    809
    -        if message != '':
    
    810
    -            single_line += ': ' + message
    
    811
    -        account_label = app.get_account_label(account)
    
    812
    -        accounts.append({'name': account,
    
    813
    -                         'account_label': account_label,
    
    814
    -                         'status_line': single_line,
    
    815
    -                         'show': status,
    
    816
    -                         'message': message})
    
    817
    -    return accounts
    
    818
    -
    
    819 717
     def get_current_show(account):
    
    820 718
         if account not in app.connections:
    
    821 719
             return 'offline'
    

  • gajim/data/gui/tooltip_roster_contact.ui → gajim/data/gui/roster_tooltip.ui
    1 1
     <?xml version="1.0" encoding="UTF-8"?>
    
    2
    -<!-- Generated with glade 3.36.0 -->
    
    2
    +<!-- Generated with glade 3.38.2 -->
    
    3 3
     <interface>
    
    4
    -  <requires lib="gtk+" version="3.22"/>
    
    4
    +  <requires lib="gtk+" version="3.24"/>
    
    5
    +  <!-- n-columns=2 n-rows=9 -->
    
    5 6
       <object class="GtkGrid" id="tooltip_grid">
    
    6 7
         <property name="visible">True</property>
    
    7
    -    <property name="can_focus">False</property>
    
    8
    +    <property name="can-focus">False</property>
    
    8 9
         <property name="halign">start</property>
    
    9
    -    <property name="border_width">6</property>
    
    10
    -    <property name="row_spacing">3</property>
    
    11
    -    <property name="column_spacing">12</property>
    
    12
    -    <child>
    
    13
    -      <object class="GtkLabel" id="resource_label">
    
    14
    -        <property name="visible">True</property>
    
    15
    -        <property name="can_focus">False</property>
    
    16
    -        <property name="halign">end</property>
    
    17
    -        <property name="valign">start</property>
    
    18
    -        <property name="label" translatable="yes">Resource:</property>
    
    19
    -      </object>
    
    20
    -      <packing>
    
    21
    -        <property name="left_attach">0</property>
    
    22
    -        <property name="top_attach">5</property>
    
    23
    -      </packing>
    
    24
    -    </child>
    
    25
    -    <child>
    
    26
    -      <object class="GtkLabel" id="resource">
    
    27
    -        <property name="visible">True</property>
    
    28
    -        <property name="can_focus">False</property>
    
    29
    -        <property name="halign">start</property>
    
    30
    -        <property name="valign">start</property>
    
    31
    -        <property name="hexpand">True</property>
    
    32
    -      </object>
    
    33
    -      <packing>
    
    34
    -        <property name="left_attach">1</property>
    
    35
    -        <property name="top_attach">5</property>
    
    36
    -      </packing>
    
    37
    -    </child>
    
    10
    +    <property name="border-width">6</property>
    
    11
    +    <property name="row-spacing">3</property>
    
    12
    +    <property name="column-spacing">12</property>
    
    38 13
         <child>
    
    39 14
           <object class="GtkLabel" id="jid">
    
    40 15
             <property name="visible">True</property>
    
    41
    -        <property name="can_focus">False</property>
    
    16
    +        <property name="can-focus">False</property>
    
    42 17
             <property name="halign">start</property>
    
    43 18
             <property name="valign">start</property>
    
    44
    -        <property name="hexpand">True</property>
    
    19
    +        <property name="label">&lt;jid&gt;</property>
    
    45 20
             <property name="ellipsize">end</property>
    
    46
    -        <property name="max_width_chars">36</property>
    
    47
    -        <attributes>
    
    48
    -          <attribute name="weight" value="bold"/>
    
    49
    -        </attributes>
    
    50
    -      </object>
    
    51
    -      <packing>
    
    52
    -        <property name="left_attach">1</property>
    
    53
    -        <property name="top_attach">1</property>
    
    54
    -      </packing>
    
    55
    -    </child>
    
    56
    -    <child>
    
    57
    -      <object class="GtkLabel" id="idle_since_label">
    
    58
    -        <property name="visible">True</property>
    
    59
    -        <property name="can_focus">False</property>
    
    60
    -        <property name="halign">end</property>
    
    61
    -        <property name="valign">start</property>
    
    62
    -        <property name="label" translatable="yes">Idle since:</property>
    
    63
    -      </object>
    
    64
    -      <packing>
    
    65
    -        <property name="left_attach">0</property>
    
    66
    -        <property name="top_attach">12</property>
    
    67
    -      </packing>
    
    68
    -    </child>
    
    69
    -    <child>
    
    70
    -      <object class="GtkLabel" id="idle_since">
    
    71
    -        <property name="visible">True</property>
    
    72
    -        <property name="can_focus">False</property>
    
    73
    -        <property name="halign">start</property>
    
    74
    -        <property name="valign">start</property>
    
    75
    -        <property name="hexpand">True</property>
    
    21
    +        <property name="max-width-chars">36</property>
    
    22
    +        <property name="xalign">0</property>
    
    76 23
           </object>
    
    77 24
           <packing>
    
    78
    -        <property name="left_attach">1</property>
    
    79
    -        <property name="top_attach">12</property>
    
    25
    +        <property name="left-attach">1</property>
    
    26
    +        <property name="top-attach">1</property>
    
    80 27
           </packing>
    
    81 28
         </child>
    
    82 29
         <child>
    
    83 30
           <object class="GtkLabel" id="mood_label">
    
    84 31
             <property name="visible">True</property>
    
    85
    -        <property name="can_focus">False</property>
    
    32
    +        <property name="can-focus">False</property>
    
    86 33
             <property name="halign">end</property>
    
    87 34
             <property name="valign">start</property>
    
    88 35
             <property name="label" translatable="yes">Mood:</property>
    
    89 36
           </object>
    
    90 37
           <packing>
    
    91
    -        <property name="left_attach">0</property>
    
    92
    -        <property name="top_attach">6</property>
    
    38
    +        <property name="left-attach">0</property>
    
    39
    +        <property name="top-attach">3</property>
    
    93 40
           </packing>
    
    94 41
         </child>
    
    95 42
         <child>
    
    96 43
           <object class="GtkLabel" id="activity_label">
    
    97 44
             <property name="visible">True</property>
    
    98
    -        <property name="can_focus">False</property>
    
    45
    +        <property name="can-focus">False</property>
    
    99 46
             <property name="halign">end</property>
    
    100 47
             <property name="valign">start</property>
    
    101 48
             <property name="label" translatable="yes">Activity:</property>
    
    102 49
             <property name="lines">2</property>
    
    103 50
           </object>
    
    104 51
           <packing>
    
    105
    -        <property name="left_attach">0</property>
    
    106
    -        <property name="top_attach">7</property>
    
    52
    +        <property name="left-attach">0</property>
    
    53
    +        <property name="top-attach">4</property>
    
    107 54
           </packing>
    
    108 55
         </child>
    
    109 56
         <child>
    
    110 57
           <object class="GtkLabel" id="tune_label">
    
    111 58
             <property name="visible">True</property>
    
    112
    -        <property name="can_focus">False</property>
    
    59
    +        <property name="can-focus">False</property>
    
    113 60
             <property name="halign">end</property>
    
    114 61
             <property name="valign">start</property>
    
    115 62
             <property name="label" translatable="yes">Tune:</property>
    
    116 63
           </object>
    
    117 64
           <packing>
    
    118
    -        <property name="left_attach">0</property>
    
    119
    -        <property name="top_attach">8</property>
    
    65
    +        <property name="left-attach">0</property>
    
    66
    +        <property name="top-attach">5</property>
    
    120 67
           </packing>
    
    121 68
         </child>
    
    122 69
         <child>
    
    123 70
           <object class="GtkLabel" id="location_label">
    
    124 71
             <property name="visible">True</property>
    
    125
    -        <property name="can_focus">False</property>
    
    72
    +        <property name="can-focus">False</property>
    
    126 73
             <property name="halign">end</property>
    
    127 74
             <property name="valign">start</property>
    
    128 75
             <property name="label" translatable="yes">Location:</property>
    
    129 76
           </object>
    
    130 77
           <packing>
    
    131
    -        <property name="left_attach">0</property>
    
    132
    -        <property name="top_attach">9</property>
    
    78
    +        <property name="left-attach">0</property>
    
    79
    +        <property name="top-attach">6</property>
    
    133 80
           </packing>
    
    134 81
         </child>
    
    135 82
         <child>
    
    136 83
           <object class="GtkLabel" id="mood">
    
    137 84
             <property name="visible">True</property>
    
    138
    -        <property name="can_focus">False</property>
    
    85
    +        <property name="can-focus">False</property>
    
    139 86
             <property name="halign">start</property>
    
    140 87
             <property name="valign">start</property>
    
    141 88
             <property name="hexpand">True</property>
    
    142 89
           </object>
    
    143 90
           <packing>
    
    144
    -        <property name="left_attach">1</property>
    
    145
    -        <property name="top_attach">6</property>
    
    91
    +        <property name="left-attach">1</property>
    
    92
    +        <property name="top-attach">3</property>
    
    146 93
           </packing>
    
    147 94
         </child>
    
    148 95
         <child>
    
    149 96
           <object class="GtkLabel" id="activity">
    
    150 97
             <property name="visible">True</property>
    
    151
    -        <property name="can_focus">False</property>
    
    98
    +        <property name="can-focus">False</property>
    
    152 99
             <property name="halign">start</property>
    
    153 100
             <property name="valign">start</property>
    
    154 101
             <property name="hexpand">True</property>
    
    155 102
           </object>
    
    156 103
           <packing>
    
    157
    -        <property name="left_attach">1</property>
    
    158
    -        <property name="top_attach">7</property>
    
    104
    +        <property name="left-attach">1</property>
    
    105
    +        <property name="top-attach">4</property>
    
    159 106
           </packing>
    
    160 107
         </child>
    
    161 108
         <child>
    
    162 109
           <object class="GtkLabel" id="tune">
    
    163 110
             <property name="visible">True</property>
    
    164
    -        <property name="can_focus">False</property>
    
    111
    +        <property name="can-focus">False</property>
    
    165 112
             <property name="halign">start</property>
    
    166 113
             <property name="valign">start</property>
    
    167 114
             <property name="hexpand">True</property>
    
    168 115
           </object>
    
    169 116
           <packing>
    
    170
    -        <property name="left_attach">1</property>
    
    171
    -        <property name="top_attach">8</property>
    
    117
    +        <property name="left-attach">1</property>
    
    118
    +        <property name="top-attach">5</property>
    
    172 119
           </packing>
    
    173 120
         </child>
    
    174 121
         <child>
    
    175 122
           <object class="GtkLabel" id="location">
    
    176 123
             <property name="visible">True</property>
    
    177
    -        <property name="can_focus">False</property>
    
    124
    +        <property name="can-focus">False</property>
    
    178 125
             <property name="halign">start</property>
    
    179 126
             <property name="valign">start</property>
    
    180 127
             <property name="hexpand">True</property>
    
    181 128
           </object>
    
    182 129
           <packing>
    
    183
    -        <property name="left_attach">1</property>
    
    184
    -        <property name="top_attach">9</property>
    
    130
    +        <property name="left-attach">1</property>
    
    131
    +        <property name="top-attach">6</property>
    
    185 132
           </packing>
    
    186 133
         </child>
    
    187 134
         <child>
    
    188
    -      <object class="GtkLabel" id="sub_label">
    
    135
    +      <object class="GtkLabel" id="name">
    
    189 136
             <property name="visible">True</property>
    
    190
    -        <property name="can_focus">False</property>
    
    191
    -        <property name="halign">end</property>
    
    137
    +        <property name="can-focus">False</property>
    
    138
    +        <property name="halign">start</property>
    
    192 139
             <property name="valign">start</property>
    
    193
    -        <property name="label" translatable="yes">Subscription:</property>
    
    140
    +        <property name="label">&lt;name&gt;</property>
    
    141
    +        <property name="ellipsize">end</property>
    
    142
    +        <property name="single-line-mode">True</property>
    
    143
    +        <property name="max-width-chars">25</property>
    
    144
    +        <property name="yalign">0</property>
    
    145
    +        <style>
    
    146
    +          <class name="large-header"/>
    
    147
    +        </style>
    
    194 148
           </object>
    
    195 149
           <packing>
    
    196
    -        <property name="left_attach">0</property>
    
    197
    -        <property name="top_attach">11</property>
    
    150
    +        <property name="left-attach">1</property>
    
    151
    +        <property name="top-attach">0</property>
    
    198 152
           </packing>
    
    199 153
         </child>
    
    200 154
         <child>
    
    201
    -      <object class="GtkLabel" id="sub">
    
    155
    +      <object class="GtkImage" id="avatar">
    
    202 156
             <property name="visible">True</property>
    
    203
    -        <property name="can_focus">False</property>
    
    157
    +        <property name="can-focus">False</property>
    
    204 158
             <property name="halign">start</property>
    
    205 159
             <property name="valign">start</property>
    
    206
    -        <property name="hexpand">True</property>
    
    160
    +        <property name="icon-name">image-missing</property>
    
    161
    +        <property name="icon_size">6</property>
    
    207 162
           </object>
    
    208 163
           <packing>
    
    209
    -        <property name="left_attach">1</property>
    
    210
    -        <property name="top_attach">11</property>
    
    164
    +        <property name="left-attach">0</property>
    
    165
    +        <property name="top-attach">0</property>
    
    166
    +        <property name="height">3</property>
    
    211 167
           </packing>
    
    212 168
         </child>
    
    213 169
         <child>
    
    214
    -      <object class="GtkLabel" id="status">
    
    170
    +      <object class="GtkLabel" id="sub_label">
    
    215 171
             <property name="visible">True</property>
    
    216
    -        <property name="can_focus">False</property>
    
    217
    -        <property name="halign">start</property>
    
    172
    +        <property name="can-focus">False</property>
    
    173
    +        <property name="halign">end</property>
    
    218 174
             <property name="valign">start</property>
    
    219
    -        <property name="wrap">True</property>
    
    220
    -        <property name="wrap_mode">word-char</property>
    
    221
    -        <property name="ellipsize">end</property>
    
    222
    -        <property name="max_width_chars">40</property>
    
    223
    -        <property name="lines">3</property>
    
    224
    -        <property name="xalign">0</property>
    
    225
    -        <attributes>
    
    226
    -          <attribute name="style" value="italic"/>
    
    227
    -        </attributes>
    
    175
    +        <property name="label" translatable="yes">Subscription:</property>
    
    228 176
           </object>
    
    229 177
           <packing>
    
    230
    -        <property name="left_attach">1</property>
    
    231
    -        <property name="top_attach">4</property>
    
    178
    +        <property name="left-attach">0</property>
    
    179
    +        <property name="top-attach">7</property>
    
    232 180
           </packing>
    
    233 181
         </child>
    
    234 182
         <child>
    
    235
    -      <object class="GtkLabel" id="name">
    
    183
    +      <object class="GtkLabel" id="sub">
    
    236 184
             <property name="visible">True</property>
    
    237
    -        <property name="can_focus">False</property>
    
    185
    +        <property name="can-focus">False</property>
    
    238 186
             <property name="halign">start</property>
    
    239 187
             <property name="valign">start</property>
    
    240
    -        <property name="ellipsize">end</property>
    
    241
    -        <property name="single_line_mode">True</property>
    
    242
    -        <property name="max_width_chars">25</property>
    
    243
    -        <style>
    
    244
    -          <class name="large-header"/>
    
    245
    -        </style>
    
    188
    +        <property name="hexpand">True</property>
    
    246 189
           </object>
    
    247 190
           <packing>
    
    248
    -        <property name="left_attach">1</property>
    
    249
    -        <property name="top_attach">0</property>
    
    191
    +        <property name="left-attach">1</property>
    
    192
    +        <property name="top-attach">7</property>
    
    250 193
           </packing>
    
    251 194
         </child>
    
    252 195
         <child>
    
    253
    -      <object class="GtkLabel" id="user_show">
    
    196
    +      <object class="GtkLabel" id="idle_since_label">
    
    254 197
             <property name="visible">True</property>
    
    255
    -        <property name="can_focus">False</property>
    
    256
    -        <property name="halign">start</property>
    
    198
    +        <property name="can-focus">False</property>
    
    199
    +        <property name="halign">end</property>
    
    257 200
             <property name="valign">start</property>
    
    258
    -        <property name="vexpand">True</property>
    
    201
    +        <property name="label" translatable="yes">Idle since:</property>
    
    259 202
           </object>
    
    260 203
           <packing>
    
    261
    -        <property name="left_attach">1</property>
    
    262
    -        <property name="top_attach">2</property>
    
    204
    +        <property name="left-attach">0</property>
    
    205
    +        <property name="top-attach">8</property>
    
    263 206
           </packing>
    
    264 207
         </child>
    
    265 208
         <child>
    
    266
    -      <object class="GtkImage" id="avatar">
    
    209
    +      <object class="GtkLabel" id="idle_since">
    
    267 210
             <property name="visible">True</property>
    
    268
    -        <property name="can_focus">False</property>
    
    211
    +        <property name="can-focus">False</property>
    
    269 212
             <property name="halign">start</property>
    
    270 213
             <property name="valign">start</property>
    
    271
    -        <property name="icon_name">image-missing</property>
    
    214
    +        <property name="hexpand">True</property>
    
    272 215
           </object>
    
    273 216
           <packing>
    
    274
    -        <property name="left_attach">0</property>
    
    275
    -        <property name="top_attach">0</property>
    
    276
    -        <property name="height">5</property>
    
    217
    +        <property name="left-attach">1</property>
    
    218
    +        <property name="top-attach">8</property>
    
    277 219
           </packing>
    
    278 220
         </child>
    
    279 221
         <child>
    
    280
    -      <placeholder/>
    
    281
    -    </child>
    
    282
    -    <child>
    
    283
    -      <placeholder/>
    
    284
    -    </child>
    
    285
    -    <child>
    
    286
    -      <placeholder/>
    
    222
    +      <!-- n-columns=2 n-rows=1 -->
    
    223
    +      <object class="GtkGrid" id="resource_grid">
    
    224
    +        <property name="visible">True</property>
    
    225
    +        <property name="can-focus">False</property>
    
    226
    +        <property name="halign">start</property>
    
    227
    +        <property name="valign">start</property>
    
    228
    +        <child>
    
    229
    +          <placeholder/>
    
    230
    +        </child>
    
    231
    +        <child>
    
    232
    +          <placeholder/>
    
    233
    +        </child>
    
    234
    +      </object>
    
    235
    +      <packing>
    
    236
    +        <property name="left-attach">1</property>
    
    237
    +        <property name="top-attach">2</property>
    
    238
    +      </packing>
    
    287 239
         </child>
    
    288 240
       </object>
    
    289 241
     </interface>

  • gajim/gtk/roster.py
    ... ... @@ -19,6 +19,7 @@
    19 19
     
    
    20 20
     from gajim.gui_menu_builder import get_roster_menu
    
    21 21
     
    
    22
    +from .tooltips import RosterTooltip
    
    22 23
     from .util import EventHelper
    
    23 24
     from .util import get_builder
    
    24 25
     
    
    ... ... @@ -49,6 +50,8 @@ def __init__(self, account):
    49 50
             self._account = account
    
    50 51
             self._client = app.get_client(account)
    
    51 52
     
    
    53
    +        self._roster_tooltip = RosterTooltip()
    
    54
    +
    
    52 55
             self._ui = get_builder('roster.ui')
    
    53 56
             self._ui.roster_treeview.set_model(None)
    
    54 57
             self.add(self._ui.roster_treeview)
    
    ... ... @@ -62,6 +65,8 @@ def __init__(self, account):
    62 65
             self._store.set_sort_func(Column.TEXT, self._tree_compare_iters)
    
    63 66
     
    
    64 67
             self._roster = self._ui.roster_treeview
    
    68
    +        self._roster.set_has_tooltip(True)
    
    69
    +        self._roster.connect('query-tooltip', self._on_query_tooltip)
    
    65 70
     
    
    66 71
             # Drag and Drop
    
    67 72
             entries = [Gtk.TargetEntry.new(
    
    ... ... @@ -214,6 +219,37 @@ def _on_drag_data_received(self, treeview, _drag_context, x_coord,
    214 219
                                                            source_group,
    
    215 220
                                                            dest_group)
    
    216 221
     
    
    222
    +    def _on_query_tooltip(self, treeview, x_coord, y_coord, _keyboard_mode,
    
    223
    +                          tooltip):
    
    224
    +        try:
    
    225
    +            path = treeview.get_path_at_pos(x_coord, y_coord)
    
    226
    +            row = path[0]
    
    227
    +        except TypeError:
    
    228
    +            self._roster_tooltip.clear_tooltip()
    
    229
    +            return False
    
    230
    +
    
    231
    +        if not row:
    
    232
    +            self._roster_tooltip.clear_tooltip()
    
    233
    +            return False
    
    234
    +
    
    235
    +        iter_ = None
    
    236
    +        try:
    
    237
    +            model = treeview.get_model()
    
    238
    +            iter_ = model.get_iter(row)
    
    239
    +        except Exception:
    
    240
    +            self._roster_tooltip.clear_tooltip()
    
    241
    +            return False
    
    242
    +
    
    243
    +        if not model[iter_][Column.IS_CONTACT]:
    
    244
    +            # It’s a group
    
    245
    +            self._roster_tooltip.clear_tooltip()
    
    246
    +            return False
    
    247
    +
    
    248
    +        contact = self._get_contact(model[iter_][Column.JID_OR_GROUP])
    
    249
    +        value, widget = self._roster_tooltip.get_tooltip(row, contact)
    
    250
    +        tooltip.set_custom(widget)
    
    251
    +        return value
    
    252
    +
    
    217 253
         def _on_show_offline(self, action, param):
    
    218 254
             action.set_state(param)
    
    219 255
             app.settings.set('showoffline', param.get_boolean())
    

  • gajim/gtk/statusicon.py
    ... ... @@ -34,7 +34,6 @@
    34 34
     from .util import restore_roster_position
    
    35 35
     from .util import open_window
    
    36 36
     from .single_message import SingleMessageWindow
    
    37
    -from .tooltips import NotificationAreaTooltip
    
    38 37
     
    
    39 38
     
    
    40 39
     class StatusIcon:
    
    ... ... @@ -53,16 +52,13 @@ def __init__(self):
    53 52
             self._ui.connect_signals(self)
    
    54 53
             self.popup_menus = []
    
    55 54
             self.status_icon = None
    
    56
    -        self.tooltip = NotificationAreaTooltip()
    
    57 55
             self._icon_size = '16'
    
    58 56
     
    
    59 57
         def show_icon(self):
    
    60 58
             if not self.status_icon:
    
    61 59
                 self.status_icon = Gtk.StatusIcon()
    
    62
    -            self.status_icon.set_property('has-tooltip', True)
    
    63 60
                 self.status_icon.connect('activate', self._on_activate)
    
    64 61
                 self.status_icon.connect('popup-menu', self._on_popup_menu)
    
    65
    -            self.status_icon.connect('query-tooltip', self._on_query_tooltip)
    
    66 62
                 self.status_icon.connect('size-changed', self.set_img)
    
    67 63
     
    
    68 64
             self.set_img()
    
    ... ... @@ -108,10 +104,6 @@ def _on_event_removed(self, _event_list):
    108 104
             """
    
    109 105
             self.set_img()
    
    110 106
     
    
    111
    -    def _on_query_tooltip(self, _status_icon, _x, _y, _keyboard_mode, tooltip):
    
    112
    -        tooltip.set_custom(self.tooltip.get_tooltip())
    
    113
    -        return True
    
    114
    -
    
    115 107
         def _on_popup_menu(self, _status_icon, button, activate_time):
    
    116 108
             if button == 1: # Left click
    
    117 109
                 self._on_left_click()
    
    ... ... @@ -137,7 +129,7 @@ def on_status_icon_size_changed(self, _statusicon, size):
    137 129
     
    
    138 130
         def set_img(self, *args):
    
    139 131
             """
    
    140
    -        Apart from image, we also update tooltip text here
    
    132
    +        Update image
    
    141 133
             """
    
    142 134
             if not app.interface.systray_enabled:
    
    143 135
                 return
    

  • gajim/gtk/tooltips.py
    ... ... @@ -35,129 +35,24 @@
    35 35
     
    
    36 36
     from gajim.common import app
    
    37 37
     from gajim.common import helpers
    
    38
    -from gajim.common.helpers import get_connection_status
    
    39 38
     from gajim.common.const import AvatarSize
    
    40 39
     from gajim.common.const import PEPEventType
    
    41 40
     from gajim.common.i18n import Q_
    
    42 41
     from gajim.common.i18n import _
    
    43 42
     from gajim.gtkgui_helpers import add_css_class
    
    44 43
     
    
    44
    +from .avatar import get_show_circle
    
    45 45
     from .util import get_builder
    
    46
    -from .util import get_icon_name
    
    47 46
     from .util import format_mood
    
    48 47
     from .util import format_activity
    
    49 48
     from .util import format_tune
    
    50 49
     from .util import format_location
    
    51 50
     from .util import get_css_show_class
    
    52 51
     
    
    53
    -
    
    54 52
     log = logging.getLogger('gajim.gui.tooltips')
    
    55 53
     
    
    56 54
     
    
    57
    -class StatusTable:
    
    58
    -    """
    
    59
    -    Contains methods for creating status table. This is used in Roster and
    
    60
    -    NotificationArea tooltips
    
    61
    -    """
    
    62
    -
    
    63
    -    def __init__(self):
    
    64
    -        self.current_row = 0
    
    65
    -        self.table = None
    
    66
    -        self.text_label = None
    
    67
    -        self.spacer_label = '   '
    
    68
    -
    
    69
    -    def create_table(self):
    
    70
    -        self.table = Gtk.Grid()
    
    71
    -        self.table.insert_column(0)
    
    72
    -        self.table.set_property('column-spacing', 3)
    
    73
    -
    
    74
    -    def add_text_row(self, text, col_inc=0):
    
    75
    -        self.table.insert_row(self.current_row)
    
    76
    -        self.text_label = Gtk.Label()
    
    77
    -        self.text_label.set_line_wrap(True)
    
    78
    -        self.text_label.set_line_wrap_mode(Pango.WrapMode.WORD_CHAR)
    
    79
    -        self.text_label.set_lines(3)
    
    80
    -        self.text_label.set_ellipsize(Pango.EllipsizeMode.END)
    
    81
    -        self.text_label.set_max_width_chars(30)
    
    82
    -        self.text_label.set_halign(Gtk.Align.START)
    
    83
    -        self.text_label.set_valign(Gtk.Align.START)
    
    84
    -        self.text_label.set_xalign(0)
    
    85
    -        self.text_label.set_selectable(False)
    
    86
    -
    
    87
    -        self.text_label.set_text(text)
    
    88
    -        self.table.attach(self.text_label, 1 + col_inc,
    
    89
    -                          self.current_row,
    
    90
    -                          3 - col_inc,
    
    91
    -                          1)
    
    92
    -        self.current_row += 1
    
    93
    -
    
    94
    -    def add_status_row(self, show, str_status, indent=True, transport=None):
    
    95
    -        """
    
    96
    -        Append a new row with status icon to the table
    
    97
    -        """
    
    98
    -        self.table.insert_row(self.current_row)
    
    99
    -        image = Gtk.Image()
    
    100
    -        icon_name = get_icon_name(show, transport=transport)
    
    101
    -        image.set_from_icon_name(icon_name, Gtk.IconSize.MENU)
    
    102
    -        spacer = Gtk.Label(label=self.spacer_label)
    
    103
    -        image.set_halign(Gtk.Align.START)
    
    104
    -        image.set_valign(Gtk.Align.CENTER)
    
    105
    -        if indent:
    
    106
    -            self.table.attach(spacer, 1, self.current_row, 1, 1)
    
    107
    -        self.table.attach(image, 2, self.current_row, 1, 1)
    
    108
    -        status_label = Gtk.Label()
    
    109
    -        status_label.set_text(str_status)
    
    110
    -        status_label.set_halign(Gtk.Align.START)
    
    111
    -        status_label.set_valign(Gtk.Align.START)
    
    112
    -        status_label.set_xalign(0)
    
    113
    -        status_label.set_line_wrap(True)
    
    114
    -        status_label.set_line_wrap_mode(Pango.WrapMode.WORD_CHAR)
    
    115
    -        status_label.set_lines(3)
    
    116
    -        status_label.set_ellipsize(Pango.EllipsizeMode.END)
    
    117
    -        status_label.set_max_width_chars(30)
    
    118
    -        self.table.attach(status_label, 3, self.current_row, 1, 1)
    
    119
    -        self.current_row += 1
    
    120
    -
    
    121
    -    def fill_table_with_accounts(self, accounts):
    
    122
    -        for acct in accounts:
    
    123
    -            message = acct['message']
    
    124
    -            message = helpers.reduce_chars_newlines(message, 100, 1)
    
    125
    -            message = GLib.markup_escape_text(message)
    
    126
    -
    
    127
    -            account_label = GLib.markup_escape_text(acct['account_label'])
    
    128
    -            if message:
    
    129
    -                status = '%s - %s' % (account_label, message)
    
    130
    -            else:
    
    131
    -                status = account_label
    
    132
    -
    
    133
    -            self.add_status_row(acct['show'], status, indent=False)
    
    134
    -
    
    135
    -            for line in acct['event_lines']:
    
    136
    -                self.add_text_row('  ' + line, 1)
    
    137
    -
    
    138
    -
    
    139
    -class NotificationAreaTooltip(StatusTable):
    
    140
    -    """
    
    141
    -    Tooltip that is shown in the notification area
    
    142
    -    """
    
    143
    -
    
    144
    -    def __init__(self):
    
    145
    -        StatusTable.__init__(self)
    
    146
    -
    
    147
    -    def get_tooltip(self):
    
    148
    -        self.create_table()
    
    149
    -
    
    150
    -        accounts = helpers.get_notification_icon_tooltip_dict()
    
    151
    -        self.fill_table_with_accounts(accounts)
    
    152
    -        self.table.set_property('column-spacing', 1)
    
    153
    -
    
    154
    -        hbox = Gtk.HBox()
    
    155
    -        hbox.add(self.table)
    
    156
    -        hbox.show_all()
    
    157
    -        return hbox
    
    158
    -
    
    159
    -
    
    160
    -class GCTooltip():
    
    55
    +class GCTooltip:
    
    161 56
         def __init__(self):
    
    162 57
             self.contact = None
    
    163 58
     
    
    ... ... @@ -231,198 +126,113 @@ def destroy(self):
    231 126
             self._ui.tooltip_grid.destroy()
    
    232 127
     
    
    233 128
     
    
    234
    -class RosterTooltip(StatusTable):
    
    129
    +class RosterTooltip:
    
    235 130
         def __init__(self):
    
    236
    -        StatusTable.__init__(self)
    
    237
    -        self.create_table()
    
    238
    -        self.account = None
    
    239
    -        self.row = None
    
    240
    -        self.contact_jid = None
    
    241
    -        self.prim_contact = None
    
    242
    -        self.last_widget = None
    
    243
    -        self.num_resources = 0
    
    244
    -
    
    245
    -        self._ui = get_builder('tooltip_roster_contact.ui')
    
    131
    +        self._row = None
    
    132
    +        self._ui = get_builder('roster_tooltip.ui')
    
    246 133
     
    
    247 134
         def clear_tooltip(self):
    
    248
    -        """
    
    249
    -        Hide all Elements of the Tooltip Grid
    
    250
    -        """
    
    251
    -        for child in self._ui.tooltip_grid.get_children():
    
    252
    -            child.hide()
    
    253
    -        status_table = self._ui.tooltip_grid.get_child_at(1, 3)
    
    254
    -        if status_table:
    
    255
    -            status_table.destroy()
    
    256
    -            self.create_table()
    
    257
    -        self.row = None
    
    258
    -
    
    259
    -    def get_tooltip(self, row, connected_contacts, account, typ):
    
    260
    -        if self.row == row:
    
    135
    +        self._row = None
    
    136
    +        for widget in self._ui.resource_grid.get_children():
    
    137
    +            widget.destroy()
    
    138
    +        for widget in self._ui.tooltip_grid.get_children():
    
    139
    +            widget.hide()
    
    140
    +
    
    141
    +    def get_tooltip(self, row, contact):
    
    142
    +        if self._row == row:
    
    261 143
                 return True, self._ui.tooltip_grid
    
    262 144
     
    
    263
    -        self._populate_grid(connected_contacts, account, typ)
    
    264
    -        self.row = row
    
    145
    +        self._populate_grid(contact)
    
    146
    +        self._row = row
    
    265 147
             return False, self._ui.tooltip_grid
    
    266 148
     
    
    267
    -    def _populate_grid(self, contacts, account, typ):
    
    268
    -        """
    
    269
    -        Populate the Tooltip Grid with data of from the contact
    
    270
    -        """
    
    271
    -        self.current_row = 0
    
    272
    -        self.account = account
    
    273
    -        if self.last_widget:
    
    274
    -            self.last_widget.set_vexpand(False)
    
    275
    -
    
    149
    +    def _populate_grid(self, contact):
    
    276 150
             self.clear_tooltip()
    
    151
    +        scale = self._ui.tooltip_grid.get_scale_factor()
    
    277 152
     
    
    278
    -        if account == 'all':
    
    279
    -            # Tooltip for merged accounts row
    
    280
    -            self._show_merged_account_tooltip()
    
    281
    -            return
    
    282
    -
    
    283
    -        if typ == 'account':
    
    284
    -            jid = app.get_jid_from_account(account)
    
    285
    -            contacts = []
    
    286
    -            connection = app.connections[account]
    
    287
    -            # get our current contact info
    
    288
    -
    
    289
    -            nbr_on, nbr_total = app.\
    
    290
    -                contacts.get_nb_online_total_contacts(accounts=[account])
    
    291
    -            account_name = app.get_account_label(account)
    
    292
    -            if app.account_is_available(account):
    
    293
    -                account_name += ' (%s/%s)' % (repr(nbr_on), repr(nbr_total))
    
    294
    -            contact = app.contacts.create_self_contact(
    
    295
    -                jid=jid,
    
    296
    -                account=account,
    
    297
    -                name=account_name,
    
    298
    -                show=get_connection_status(account),
    
    299
    -                status=connection.status_message,
    
    300
    -                resource=connection.get_own_jid().resource,
    
    301
    -                priority=connection.priority)
    
    302
    -
    
    303
    -            contacts.append(contact)
    
    304
    -
    
    305
    -        # Username/Account/Groupchat
    
    306
    -        self.prim_contact = app.contacts.get_highest_prio_contact_from_contacts(
    
    307
    -            contacts)
    
    308
    -        if self.prim_contact is None:
    
    309
    -            log.error('No contact for Roster tooltip found')
    
    310
    -            log.error('contacts: %s, typ: %s, account: %s',
    
    311
    -                      contacts, typ, account)
    
    312
    -            return
    
    313
    -        self.contact_jid = self.prim_contact.jid
    
    314
    -        name = GLib.markup_escape_text(self.prim_contact.get_shown_name())
    
    315
    -
    
    316
    -        if app.settings.get('mergeaccounts'):
    
    317
    -            name = GLib.markup_escape_text(
    
    318
    -                self.prim_contact.account.name)
    
    319
    -
    
    320
    -        self._ui.name.set_markup(name)
    
    321
    -        self._ui.name.show()
    
    153
    +        # Avatar
    
    154
    +        surface = contact.get_avatar(AvatarSize.TOOLTIP, scale)
    
    155
    +        self._ui.avatar.set_from_surface(surface)
    
    156
    +        self._ui.avatar.show()
    
    322 157
     
    
    323
    -        self.num_resources = 0
    
    324
    -        # put contacts in dict, where key is priority
    
    325
    -        contacts_dict = {}
    
    326
    -        for contact in contacts:
    
    327
    -            if contact.resource:
    
    328
    -                self.num_resources += 1
    
    329
    -                priority = int(contact.priority)
    
    330
    -                if priority in contacts_dict:
    
    331
    -                    contacts_dict[priority].append(contact)
    
    332
    -                else:
    
    333
    -                    contacts_dict[priority] = [contact]
    
    334
    -        if self.num_resources > 1:
    
    335
    -            transport = app.get_transport_name_from_jid(self.prim_contact.jid)
    
    336
    -            if transport == 'jabber':
    
    337
    -                transport = None
    
    338
    -            contact_keys = sorted(contacts_dict.keys())
    
    339
    -            contact_keys.reverse()
    
    340
    -            for priority in contact_keys:
    
    341
    -                for acontact in contacts_dict[priority]:
    
    342
    -                    show = self._get_icon_name_for_tooltip(acontact)
    
    343
    -                    status = acontact.status
    
    344
    -                    resource_line = '%s (%s)' % (acontact.resource,
    
    345
    -                                                 str(acontact.priority))
    
    346
    -                    self.add_status_row(
    
    347
    -                        show, resource_line, transport=transport)
    
    348
    -                    if status:
    
    349
    -                        self.add_text_row(status, 2)
    
    350
    -
    
    351
    -            self._ui.tooltip_grid.attach(self.table, 1, 3, 2, 1)
    
    352
    -            self.table.show_all()
    
    353
    -
    
    354
    -        else:  # only one resource
    
    355
    -            if contact.is_groupchat:
    
    356
    -                disco_info = app.storage.cache.get_last_disco_info(contact.jid)
    
    357
    -                if disco_info is not None:
    
    358
    -                    description = disco_info.muc_description
    
    359
    -                    if description:
    
    360
    -                        self._ui.status.set_text(description)
    
    361
    -                        self._ui.status.show()
    
    362
    -            elif contact.show and contact.status:
    
    363
    -                status = contact.status.strip()
    
    364
    -                if status:
    
    365
    -                    self._ui.status.set_text(status)
    
    366
    -                    self._ui.status.show()
    
    367
    -
    
    368
    -        # PEP Info
    
    369
    -        self._append_pep_info(contact)
    
    158
    +        # Name
    
    159
    +        self._ui.name.set_markup(GLib.markup_escape_text(contact.name))
    
    160
    +        self._ui.name.show()
    
    370 161
     
    
    371 162
             # JID
    
    372
    -        self._ui.jid.set_text(self.prim_contact.jid)
    
    163
    +        self._ui.jid.set_text(str(contact.jid))
    
    373 164
             self._ui.jid.show()
    
    374 165
     
    
    375
    -        # contact has only one resource
    
    376
    -        if self.num_resources == 1 and contact.resource:
    
    377
    -            res = GLib.markup_escape_text(contact.resource)
    
    378
    -            prio = str(contact.priority)
    
    379
    -            self._ui.resource.set_text("{} ({})".format(res, prio))
    
    380
    -            self._ui.resource.show()
    
    381
    -            self._ui.resource_label.show()
    
    382
    -
    
    383
    -        if self.prim_contact.jid not in app.gc_connected[account]:
    
    384
    -            if (account and
    
    385
    -                    self.prim_contact.sub and
    
    386
    -                    self.prim_contact.sub != 'both'):
    
    387
    -                # ('both' is the normal sub so we don't show it)
    
    388
    -                self._ui.sub.set_text(helpers.get_uf_sub(self.prim_contact.sub))
    
    389
    -                self._ui.sub.show()
    
    390
    -                self._ui.sub_label.show()
    
    391
    -
    
    392
    -        self._set_idle_time(contact)
    
    166
    +        # Resources with show, status, priority
    
    167
    +        resources = contact.get_resources()
    
    168
    +        self._build_resource_grid(resources, scale)
    
    393 169
     
    
    394
    -        # Avatar
    
    395
    -        scale = self._ui.tooltip_grid.get_scale_factor()
    
    396
    -        surface = app.contacts.get_avatar(
    
    397
    -            account, self.prim_contact.jid, AvatarSize.TOOLTIP, scale)
    
    398
    -        self._ui.avatar.set_from_surface(surface)
    
    399
    -        self._ui.avatar.show()
    
    170
    +        # Subscription
    
    171
    +        if contact.subscription and contact.subscription != 'both':
    
    172
    +            # 'both' is the normal subscription value, just omit it
    
    173
    +            self._ui.sub.set_text(helpers.get_uf_sub(contact.subscription))
    
    174
    +            self._ui.sub.show()
    
    175
    +            self._ui.sub_label.show()
    
    176
    +
    
    177
    +        # Idle time
    
    178
    +        # TODO
    
    179
    +        # self._set_idle_time(contact)
    
    180
    +
    
    181
    +        # PEP info
    
    182
    +        # TODO
    
    183
    +        # self._append_pep_info(contact)
    
    400 184
     
    
    401 185
             app.plugin_manager.gui_extension_point(
    
    402
    -            'roster_tooltip_populate', self, contacts, self._ui.tooltip_grid)
    
    403
    -
    
    404
    -        # Sets the Widget that is at the bottom to expand.
    
    405
    -        # This is needed in case the Picture takes more Space than the Labels
    
    406
    -        i = 1
    
    407
    -        while i < 15:
    
    408
    -            if self._ui.tooltip_grid.get_child_at(1, i):
    
    409
    -                if self._ui.tooltip_grid.get_child_at(1, i).get_visible():
    
    410
    -                    self.last_widget = self._ui.tooltip_grid.get_child_at(1, i)
    
    411
    -            i += 1
    
    412
    -        self.last_widget.set_vexpand(True)
    
    413
    -
    
    414
    -    def _show_merged_account_tooltip(self):
    
    415
    -        accounts = helpers.get_notification_icon_tooltip_dict()
    
    416
    -        self.spacer_label = ''
    
    417
    -        self.fill_table_with_accounts(accounts)
    
    418
    -        self._ui.tooltip_grid.attach(self.table, 1, 3, 2, 1)
    
    419
    -        self.table.show_all()
    
    186
    +            'roster_tooltip_populate', self, contact, self._ui.tooltip_grid)
    
    187
    +
    
    188
    +        # This sets the bottom-most widget to expand, in case the avatar
    
    189
    +        # takes more space than the labels
    
    190
    +        row_count = 1
    
    191
    +        while row_count < 9:
    
    192
    +            widget = self._ui.tooltip_grid.get_child_at(1, row_count)
    
    193
    +            if widget and widget.get_visible():
    
    194
    +                last_widget = widget
    
    195
    +                row_count += 1
    
    196
    +            else:
    
    197
    +                break
    
    198
    +        last_widget.set_vexpand(True)
    
    199
    +
    
    200
    +    def _build_resource_grid(self, resources, scale):
    
    201
    +        row_num = 0
    
    202
    +        for contact in resources:
    
    203
    +            show_surface = get_show_circle(
    
    204
    +                contact.show, AvatarSize.ROSTER, scale)
    
    205
    +            show_image = Gtk.Image.new_from_surface(show_surface)
    
    206
    +            show_image.set_halign(Gtk.Align.START)
    
    207
    +            show_image.set_valign(Gtk.Align.CENTER)
    
    208
    +            self._ui.resource_grid.attach(show_image, 0, row_num, 1, 1)
    
    209
    +
    
    210
    +            resource_string = GLib.markup_escape_text(contact.jid.resource)
    
    211
    +            resource_label = Gtk.Label()
    
    212
    +            resource_label.set_halign(Gtk.Align.START)
    
    213
    +            resource_label.set_xalign(0)
    
    214
    +            resource_label.set_ellipsize(Pango.EllipsizeMode.END)
    
    215
    +            resource_label.set_max_width_chars(30)
    
    216
    +            resource_label.set_text(f'{resource_string} ({contact.priority})')
    
    217
    +            self._ui.resource_grid.attach(resource_label, 1, row_num, 1, 1)
    
    218
    +
    
    219
    +            if contact.status:
    
    220
    +                row_num += 1
    
    221
    +                status_text = GLib.markup_escape_text(contact.status)
    
    222
    +                status_label = Gtk.Label()
    
    223
    +                status_label.set_halign(Gtk.Align.START)
    
    224
    +                status_label.set_xalign(0)
    
    225
    +                status_label.set_ellipsize(Pango.EllipsizeMode.END)
    
    226
    +                status_label.set_max_width_chars(30)
    
    227
    +                status_label.set_text(status_text)
    
    228
    +                self._ui.resource_grid.attach(
    
    229
    +                    status_label, 1, row_num, 1, 1)
    
    230
    +
    
    231
    +            row_num += 1
    
    232
    +
    
    233
    +        self._ui.resource_grid.show_all()
    
    420 234
     
    
    421 235
         def _append_pep_info(self, contact):
    
    422
    -        """
    
    423
    -        Append Tune, Mood, Activity, Location information of the
    
    424
    -        specified contact to the given property list.
    
    425
    -        """
    
    426 236
             if PEPEventType.MOOD in contact.pep:
    
    427 237
                 mood = format_mood(*contact.pep[PEPEventType.MOOD])
    
    428 238
                 self._ui.mood.set_markup(mood)
    
    ... ... @@ -461,36 +271,8 @@ def _set_idle_time(self, contact):
    461 271
                 self._ui.idle_since.show()
    
    462 272
                 self._ui.idle_since_label.show()
    
    463 273
     
    
    464
    -        if contact.show and self.num_resources < 2:
    
    465
    -            show = helpers.get_uf_show(contact.show)
    
    466
    -            # Contact is Groupchat
    
    467
    -            if (self.account and
    
    468
    -                    self.prim_contact.jid in app.gc_connected[self.account]):
    
    469
    -                if app.gc_connected[self.account][self.prim_contact.jid]:
    
    470
    -                    show = _('Connected')
    
    471
    -                else:
    
    472
    -                    show = _('Disconnected')
    
    473
    -
    
    474
    -            colorize_status(self._ui.user_show, contact.show)
    
    475
    -            self._ui.user_show.set_text(show)
    
    476
    -            self._ui.user_show.show()
    
    477
    -
    
    478
    -    @staticmethod
    
    479
    -    def _get_icon_name_for_tooltip(contact):
    
    480
    -        """
    
    481
    -        Helper function used for tooltip contacts/accounts
    
    482
    -
    
    483
    -        Tooltip on account has fake contact with sub == '', in this case we show
    
    484
    -        real status of the account
    
    485
    -        """
    
    486
    -        if contact.ask == 'subscribe':
    
    487
    -            return 'requested'
    
    488
    -        if contact.sub in ('both', 'to', ''):
    
    489
    -            return contact.show
    
    490
    -        return 'not in roster'
    
    491
    -
    
    492 274
     
    
    493
    -class FileTransfersTooltip():
    
    275
    +class FileTransfersTooltip:
    
    494 276
         def __init__(self):
    
    495 277
             self.sid = None
    
    496 278
             self.widget = None