Yann Leboulanger pushed to branch master at gajim / gajim

Commits:

1 changed file:

Changes:

  • gajim/roster_window.py
    ... ... @@ -84,6 +84,7 @@ class Column(IntEnum):
    84 84
         LOCATION_PIXBUF = 8
    
    85 85
         AVATAR_PIXBUF = 9  # avatar_pixbuf
    
    86 86
         PADLOCK_PIXBUF = 10  # use for account row only
    
    87
    +    VISIBLE = 11
    
    87 88
     
    
    88 89
     empty_pixbuf = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB, True, 8, 1, 1)
    
    89 90
     empty_pixbuf.fill(0xffffff00)
    
    ... ... @@ -251,7 +252,7 @@ class RosterWindow:
    251 252
                 it = self.model.append(None, [
    
    252 253
                     app.interface.jabber_state_images['16'][show],
    
    253 254
                     _('Merged accounts'), 'account', '', 'all', None, None, None,
    
    254
    -                None, None, None] + [None] * self.nb_ext_renderers)
    
    255
    +                None, None, None, True] + [None] * self.nb_ext_renderers)
    
    255 256
                 self._iters['MERGED']['account'] = it
    
    256 257
             else:
    
    257 258
                 show = app.SHOW_LIST[app.connections[account].connected]
    
    ... ... @@ -267,7 +268,7 @@ class RosterWindow:
    267 268
                 it = self.model.append(None, [
    
    268 269
                     app.interface.jabber_state_images['16'][show],
    
    269 270
                     GLib.markup_escape_text(account), 'account', our_jid,
    
    270
    -                account, None, None, None, None, None, tls_pixbuf] +
    
    271
    +                account, None, None, None, None, None, tls_pixbuf, True] +
    
    271 272
                     [None] * self.nb_ext_renderers)
    
    272 273
                 self._iters[account]['account'] = it
    
    273 274
     
    
    ... ... @@ -327,7 +328,7 @@ class RosterWindow:
    327 328
             iter_group = self.model.append(iter_parent,
    
    328 329
                 [app.interface.jabber_state_images['16']['closed'],
    
    329 330
                 GLib.markup_escape_text(group), 'group', group, account, None,
    
    330
    -            None, None, None, None, None] + [None] * self.nb_ext_renderers)
    
    331
    +            None, None, None, None, None, False] + [None] * self.nb_ext_renderers)
    
    331 332
             self.draw_group(group, account)
    
    332 333
             self._iters[account_group]['groups'][group] = iter_group
    
    333 334
             return iter_group
    
    ... ... @@ -350,6 +351,7 @@ class RosterWindow:
    350 351
                       big_brother_contact. (default None)
    
    351 352
             """
    
    352 353
             added_iters = []
    
    354
    +        visible = self.contact_is_visible(contact, account)
    
    353 355
             if big_brother_contact:
    
    354 356
                 # Add contact under big brother
    
    355 357
     
    
    ... ... @@ -364,7 +366,7 @@ class RosterWindow:
    364 366
                 for child_iter in parent_iters:
    
    365 367
                     it = self.model.append(child_iter, [None,
    
    366 368
                         contact.get_shown_name(), 'contact', contact.jid, account,
    
    367
    -                    None, None, None, None, None, None] + \
    
    369
    +                    None, None, None, None, None, None, visible] + \
    
    368 370
                         [None] * self.nb_ext_renderers)
    
    369 371
                     added_iters.append(it)
    
    370 372
                     if contact.jid in self._iters[account]['contacts']:
    
    ... ... @@ -393,7 +395,7 @@ class RosterWindow:
    393 395
                     # for more
    
    394 396
                     i_ = self.model.append(child_iterG, [None,
    
    395 397
                         contact.get_shown_name(), typestr, contact.jid, account,
    
    396
    -                    None, None, None, None, None, None] + \
    
    398
    +                    None, None, None, None, None, None, visible] + \
    
    397 399
                         [None] * self.nb_ext_renderers)
    
    398 400
                     added_iters.append(i_)
    
    399 401
                     if contact.jid in self._iters[account]['contacts']:
    
    ... ... @@ -653,7 +655,7 @@ class RosterWindow:
    653 655
             child_iterA = self._get_account_iter(account, self.model)
    
    654 656
             self._iters[account]['contacts'][jid] = [self.model.append(child_iterA,
    
    655 657
                 [None, app.nicks[account], 'self_contact', jid, account, None,
    
    656
    -            None, None, None, None, None] + [None] * self.nb_ext_renderers)]
    
    658
    +            None, None, None, None, None, True] + [None] * self.nb_ext_renderers)]
    
    657 659
     
    
    658 660
             self.draw_completely(jid, account)
    
    659 661
             self.draw_account(account)
    
    ... ... @@ -1012,6 +1014,10 @@ class RosterWindow:
    1012 1014
                     # Peform delayed recalibration
    
    1013 1015
                     self._recalibrate_metacontact_family(family, account)
    
    1014 1016
                 self.draw_contact(jid, account)
    
    1017
    +            # Hide Group if all childs are hidden
    
    1018
    +            contact = app.contacts.get_contact(account, jid)
    
    1019
    +            for group in contact.get_shown_groups():
    
    1020
    +                self.draw_group(group, account)
    
    1015 1021
     
    
    1016 1022
         # FIXME: integrate into add_contact()
    
    1017 1023
         def add_to_not_in_the_roster(self, account, jid, nick='', resource=''):
    
    ... ... @@ -1131,6 +1137,24 @@ class RosterWindow:
    1131 1137
     
    
    1132 1138
             self.model[child_iter][Column.NAME] = text
    
    1133 1139
     
    
    1140
    +        # Hide group if no more contacts
    
    1141
    +        iterG = self._get_group_iter(group, account, model=self.modelfilter)
    
    1142
    +        to_hide = []
    
    1143
    +        while(iterG):
    
    1144
    +            parent = self.modelfilter.iter_parent(iterG)
    
    1145
    +            if (not self.modelfilter.iter_has_child(iterG)) or (len(to_hide) > \
    
    1146
    +            0 and self.modelfilter.iter_n_children(iterG) == 1):
    
    1147
    +                to_hide.append(iterG)
    
    1148
    +                if not parent or self.modelfilter[parent][Column.TYPE] != \
    
    1149
    +                'group':
    
    1150
    +                    iterG = None
    
    1151
    +                else:
    
    1152
    +                    iterG = parent
    
    1153
    +            else:
    
    1154
    +                iterG = None
    
    1155
    +        for iter_ in to_hide:
    
    1156
    +            self.modelfilter[iter_][Column.VISIBLE] = False
    
    1157
    +
    
    1134 1158
         def _really_draw_groups(self):
    
    1135 1159
             for ag in self.groups_to_draw.values():
    
    1136 1160
                 acct = ag['account']
    
    ... ... @@ -1289,34 +1313,41 @@ class RosterWindow:
    1289 1313
                     img = state_images[icon_name]
    
    1290 1314
                     self.model[child_iter][Column.IMG] = img
    
    1291 1315
                     self.model[child_iter][Column.NAME] = name
    
    1316
    +                #TODO: compute visible
    
    1317
    +                visible = True
    
    1318
    +                self.model[child_iter][Column.VISIBLE] = visible
    
    1292 1319
             else:
    
    1293 1320
                 # A normal contact or little brother
    
    1294 1321
                 state_images = self.get_appropriate_state_images(jid,
    
    1295 1322
                         icon_name = icon_name)
    
    1296 1323
     
    
    1324
    +            visible = self.contact_is_visible(contact, account)
    
    1297 1325
                 # All iters have the same icon (no expand/collapse)
    
    1298 1326
                 img = state_images[icon_name]
    
    1299 1327
                 for child_iter in child_iters:
    
    1300 1328
                     self.model[child_iter][Column.IMG] = img
    
    1301 1329
                     self.model[child_iter][Column.NAME] = name
    
    1330
    +                self.model[child_iter][Column.VISIBLE] = visible
    
    1331
    +                if visible:
    
    1332
    +                    parent_iter = self.model.iter_parent(child_iter)
    
    1333
    +                    self.model[parent_iter][Column.VISIBLE] = True
    
    1302 1334
     
    
    1303 1335
                 # We are a little brother
    
    1304 1336
                 if family and not is_big_brother and not self.starting:
    
    1305 1337
                     self.draw_parent_contact(jid, account)
    
    1306 1338
     
    
    1307
    -        delimiter = app.connections[account].nested_group_delimiter
    
    1308
    -        for group in contact.get_shown_groups():
    
    1309
    -            # We need to make sure that _visible_func is called for
    
    1310
    -            # our groups otherwise we might not be shown
    
    1311
    -            group_splited = group.split(delimiter)
    
    1312
    -            i = 1
    
    1313
    -            while i < len(group_splited) + 1:
    
    1314
    -                g = delimiter.join(group_splited[:i])
    
    1315
    -                iterG = self._get_group_iter(g, account, model=self.model)
    
    1316
    -                if iterG:
    
    1317
    -                    # it's not self contact
    
    1318
    -                    self.model[iterG][Column.JID] = self.model[iterG][Column.JID]
    
    1319
    -                i += 1
    
    1339
    +        if visible:
    
    1340
    +            delimiter = app.connections[account].nested_group_delimiter
    
    1341
    +            for group in contact.get_shown_groups():
    
    1342
    +                group_splited = group.split(delimiter)
    
    1343
    +                i = 1
    
    1344
    +                while i < len(group_splited) + 1:
    
    1345
    +                    g = delimiter.join(group_splited[:i])
    
    1346
    +                    iterG = self._get_group_iter(g, account, model=self.model)
    
    1347
    +                    if iterG:
    
    1348
    +                        # it's not self contact
    
    1349
    +                        self.model[iterG][Column.VISIBLE] = True
    
    1350
    +                    i += 1
    
    1320 1351
     
    
    1321 1352
             app.plugin_manager.gui_extension_point('roster_draw_contact', self,
    
    1322 1353
                 jid, account, contact)
    
    ... ... @@ -1582,7 +1613,9 @@ class RosterWindow:
    1582 1613
             if self.filtering:
    
    1583 1614
                 return
    
    1584 1615
             self.filtering = True
    
    1585
    -        self.modelfilter.refilter()
    
    1616
    +        for account in app.connections:
    
    1617
    +            for jid in app.contacts.get_jid_list(account):
    
    1618
    +                self.adjust_and_draw_contact_context(jid, account)
    
    1586 1619
             self.filtering = False
    
    1587 1620
     
    
    1588 1621
         def contact_has_pending_roster_events(self, contact, account):
    
    ... ... @@ -1604,6 +1637,8 @@ class RosterWindow:
    1604 1637
                 return self.rfilter_string in contact.get_shown_name().lower()
    
    1605 1638
             if self.contact_has_pending_roster_events(contact, account):
    
    1606 1639
                 return True
    
    1640
    +        if app.config.get('showoffline'):
    
    1641
    +            return True
    
    1607 1642
     
    
    1608 1643
             if contact.show in ('offline', 'error'):
    
    1609 1644
                 if contact.jid in app.to_be_removed[account]:
    
    ... ... @@ -1612,6 +1647,8 @@ class RosterWindow:
    1612 1647
             if app.config.get('show_only_chat_and_online') and contact.show in (
    
    1613 1648
             'away', 'xa', 'busy'):
    
    1614 1649
                 return False
    
    1650
    +        if _('Transports') in contact.get_shown_groups():
    
    1651
    +            return app.config.get('show_transports_group')
    
    1615 1652
             return True
    
    1616 1653
     
    
    1617 1654
         def _visible_func(self, model, titer, dummy):
    
    ... ... @@ -1620,6 +1657,9 @@ class RosterWindow:
    1620 1657
             """
    
    1621 1658
             if self.starting_filtering:
    
    1622 1659
                 return False
    
    1660
    +
    
    1661
    +        visible = model[titer][Column.VISIBLE]
    
    1662
    +
    
    1623 1663
             type_ = model[titer][Column.TYPE]
    
    1624 1664
             if not type_:
    
    1625 1665
                 return False
    
    ... ... @@ -1635,6 +1675,9 @@ class RosterWindow:
    1635 1675
             if not jid:
    
    1636 1676
                 return False
    
    1637 1677
     
    
    1678
    +        if not self.rfilter_enabled:
    
    1679
    +            return visible
    
    1680
    +
    
    1638 1681
             if type_ == 'group':
    
    1639 1682
                 group = jid
    
    1640 1683
                 if group == _('Transports'):
    
    ... ... @@ -1645,84 +1688,31 @@ class RosterWindow:
    1645 1688
                     for _acc in accounts:
    
    1646 1689
                         for contact in app.contacts.iter_contacts(_acc):
    
    1647 1690
                             if group in contact.get_shown_groups():
    
    1648
    -                            if self.rfilter_enabled:
    
    1649
    -                                if self.rfilter_string in \
    
    1650
    -                                contact.get_shown_name().lower():
    
    1651
    -                                    return True
    
    1652
    -                            elif self.contact_has_pending_roster_events(contact,
    
    1653
    -                            _acc):
    
    1691
    +                            if self.rfilter_string in \
    
    1692
    +                            contact.get_shown_name().lower():
    
    1654 1693
                                     return True
    
    1655
    -                    if self.rfilter_enabled:
    
    1656
    -                        # No transport has been found
    
    1657
    -                        return False
    
    1658
    -                return app.config.get('show_transports_group') and \
    
    1659
    -                    (app.account_is_connected(account) or \
    
    1660
    -                    app.config.get('showoffline'))
    
    1661
    -            if app.config.get('showoffline'):
    
    1662
    -                return True
    
    1694
    +                        elif self.contact_has_pending_roster_events(contact,
    
    1695
    +                        _acc):
    
    1696
    +                            return True
    
    1697
    +                    # No transport has been found
    
    1698
    +                    return False
    
    1663 1699
     
    
    1664
    -            if self.regroup:
    
    1665
    -                # Column.ACCOUNT for groups depends on the order
    
    1666
    -                # accounts were connected
    
    1667
    -                # Check all accounts for online group contacts
    
    1668
    -                accounts = app.contacts.get_accounts()
    
    1669
    -            else:
    
    1670
    -                accounts = [account]
    
    1671
    -            for _acc in accounts:
    
    1672
    -                delimiter = app.connections[_acc].nested_group_delimiter
    
    1673
    -                for contact in app.contacts.iter_contacts(_acc):
    
    1674
    -                    if not self.contact_is_visible(contact, _acc):
    
    1675
    -                        continue
    
    1676
    -                    # Is this contact in this group?
    
    1677
    -                    for grp in contact.get_shown_groups():
    
    1678
    -                        while grp:
    
    1679
    -                            if group == grp:
    
    1680
    -                                return True
    
    1681
    -                            grp = delimiter.join(grp.split(delimiter)[:-1])
    
    1682
    -            return False
    
    1683 1700
             if type_ == 'contact':
    
    1684
    -            if self.rfilter_enabled:
    
    1685
    -                if model.iter_has_child(titer):
    
    1686
    -                    iter_c = model.iter_children(titer)
    
    1687
    -                    while iter_c:
    
    1688
    -                        if self.rfilter_string in model[iter_c][Column.NAME].lower():
    
    1689
    -                            return True
    
    1690
    -                        iter_c = model.iter_next(iter_c)
    
    1691
    -                return self.rfilter_string in model[titer][Column.NAME].lower()
    
    1692
    -            if app.config.get('showoffline'):
    
    1693
    -                return True
    
    1694
    -            bb_jid = None
    
    1695
    -            bb_account = None
    
    1696
    -            family = app.contacts.get_metacontacts_family(account, jid)
    
    1697
    -            if family:
    
    1698
    -                nearby_family, bb_jid, bb_account = \
    
    1699
    -                        self._get_nearby_family_and_big_brother(family, account)
    
    1700
    -            if (bb_jid, bb_account) == (jid, account):
    
    1701
    -                # Show the big brother if a child has pending events
    
    1702
    -                for data in nearby_family:
    
    1703
    -                    jid = data['jid']
    
    1704
    -                    account = data['account']
    
    1705
    -                    contact = app.contacts.get_contact_with_highest_priority(
    
    1706
    -                        account, jid)
    
    1707
    -                    if contact and self.contact_is_visible(contact, account):
    
    1701
    +            if model.iter_has_child(titer):
    
    1702
    +                iter_c = model.iter_children(titer)
    
    1703
    +                while iter_c:
    
    1704
    +                    if self.rfilter_string in model[iter_c][Column.NAME].lower():
    
    1708 1705
                             return True
    
    1709
    -                return False
    
    1710
    -            else:
    
    1711
    -                contact = app.contacts.get_contact_with_highest_priority(
    
    1712
    -                    account, jid)
    
    1713
    -                return self.contact_is_visible(contact, account)
    
    1706
    +                    iter_c = model.iter_next(iter_c)
    
    1707
    +            return self.rfilter_string in model[titer][Column.NAME].lower()
    
    1708
    +
    
    1714 1709
             if type_ == 'agent':
    
    1715
    -            if self.rfilter_enabled:
    
    1716
    -                return self.rfilter_string in model[titer][Column.NAME].lower()
    
    1717
    -            contact = app.contacts.get_contact_with_highest_priority(account,
    
    1718
    -                jid)
    
    1719
    -            return self.contact_has_pending_roster_events(contact, account) or \
    
    1720
    -                (app.config.get('show_transports_group') and \
    
    1721
    -                (app.account_is_connected(account) or \
    
    1722
    -                app.config.get('showoffline')))
    
    1723
    -        if type_ == 'groupchat' and self.rfilter_enabled:
    
    1724 1710
                 return self.rfilter_string in model[titer][Column.NAME].lower()
    
    1725
    -        return True
    
    1711
    +
    
    1712
    +        if type_ == 'groupchat':
    
    1713
    +            return self.rfilter_string in model[titer][Column.NAME].lower()
    
    1714
    +
    
    1715
    +        return visible
    
    1726 1716
     
    
    1727 1717
         def _compareIters(self, model, iter1, iter2, data=None):
    
    1728 1718
             """
    
    ... ... @@ -1732,8 +1722,6 @@ class RosterWindow:
    1732 1722
             name2 = model[iter2][Column.NAME]
    
    1733 1723
             if not name1 or not name2:
    
    1734 1724
                 return 0
    
    1735
    -        name1 = name1
    
    1736
    -        name2 = name2
    
    1737 1725
             type1 = model[iter1][Column.TYPE]
    
    1738 1726
             type2 = model[iter2][Column.TYPE]
    
    1739 1727
             if type1 == 'self_contact':
    
    ... ... @@ -1742,11 +1730,7 @@ class RosterWindow:
    1742 1730
                 return 1
    
    1743 1731
             if type1 == 'group':
    
    1744 1732
                 name1 = model[iter1][Column.JID]
    
    1745
    -            if name1:
    
    1746
    -                name1 = name1
    
    1747 1733
                 name2 = model[iter2][Column.JID]
    
    1748
    -            if name2:
    
    1749
    -                name2 = name2
    
    1750 1734
                 if name1 == _('Transports'):
    
    1751 1735
                     return 1
    
    1752 1736
                 if name2 == _('Transports'):
    
    ... ... @@ -1763,8 +1747,6 @@ class RosterWindow:
    1763 1747
             account2 = model[iter2][Column.ACCOUNT]
    
    1764 1748
             if not account1 or not account2:
    
    1765 1749
                 return 0
    
    1766
    -        account1 = account1
    
    1767
    -        account2 = account2
    
    1768 1750
             if type1 == 'account':
    
    1769 1751
                 return locale.strcoll(account1, account2)
    
    1770 1752
             jid1 = model[iter1][Column.JID]
    
    ... ... @@ -4064,13 +4046,8 @@ class RosterWindow:
    4064 4046
             action.set_state(param)
    
    4065 4047
             app.config.set('showoffline', param.get_boolean())
    
    4066 4048
             self.refilter_shown_roster_items()
    
    4067
    -        if param.get_boolean():
    
    4068
    -            # We need to filter twice to show groups with no contacts inside
    
    4069
    -            # in the correct expand state
    
    4070
    -            self.refilter_shown_roster_items()
    
    4071
    -            self.window.lookup_action('show-active').set_enabled(False)
    
    4072
    -        else:
    
    4073
    -            self.window.lookup_action('show-active').set_enabled(True)
    
    4049
    +        self.window.lookup_action('show-active').set_enabled(
    
    4050
    +            not param.get_boolean())
    
    4074 4051
     
    
    4075 4052
         def on_show_active_contacts_action(self, action, param):
    
    4076 4053
             """
    
    ... ... @@ -4079,14 +4056,8 @@ class RosterWindow:
    4079 4056
             action.set_state(param)
    
    4080 4057
             app.config.set('show_only_chat_and_online', param.get_boolean())
    
    4081 4058
             self.refilter_shown_roster_items()
    
    4082
    -
    
    4083
    -        if param.get_boolean():
    
    4084
    -            # We need to filter twice to show groups with no contacts inside
    
    4085
    -            # in the correct expand state
    
    4086
    -            self.refilter_shown_roster_items()
    
    4087
    -            self.window.lookup_action('show-offline').set_enabled(False)
    
    4088
    -        else:
    
    4089
    -            self.window.lookup_action('show-offline').set_enabled(True)
    
    4059
    +        self.window.lookup_action('show-offline').set_enabled(
    
    4060
    +            not param.get_boolean())
    
    4090 4061
     
    
    4091 4062
         def on_show_roster_action(self, action, param):
    
    4092 4063
             # when num controls is 0 this menuitem is hidden, but still need to
    
    ... ... @@ -5693,12 +5664,12 @@ class RosterWindow:
    5693 5664
             self.nb_ext_renderers = 0
    
    5694 5665
             # When we quit, rememver if we already saved config once
    
    5695 5666
             self.save_done = False
    
    5696
    -        # [icon, name, type, jid, account, editable, mood_pixbuf,
    
    5667
    +        # [icon, name, type, jid, account, mood_pixbuf,
    
    5697 5668
             # activity_pixbuf, tune_pixbuf, location_pixbuf, avatar_pixbuf,
    
    5698
    -        # padlock_pixbuf]
    
    5669
    +        # padlock_pixbuf, visible]
    
    5699 5670
             self.columns = [Gtk.Image, str, str, str, str,
    
    5700 5671
                 GdkPixbuf.Pixbuf, GdkPixbuf.Pixbuf, GdkPixbuf.Pixbuf, GdkPixbuf.Pixbuf,
    
    5701
    -            GdkPixbuf.Pixbuf, GdkPixbuf.Pixbuf]
    
    5672
    +            GdkPixbuf.Pixbuf, GdkPixbuf.Pixbuf, bool]
    
    5702 5673
             self.xml = gtkgui_helpers.get_gtk_builder('roster_window.ui')
    
    5703 5674
             self.window = self.xml.get_object('roster_window')
    
    5704 5675
             application.add_window(self.window)