# HG changeset patch # User Goffi # Date 1469375229 -7200 # Node ID 20fb71b656e32f29cd1f234e0f28e1898ea6e2ba # Parent 0694a2611badc3b56fb58b8227a11d1fee9b2409 quick_frontend, primitivus (contact_list): improved and simplified handling of "special" entities: - special_extras has been removed - specials handle all entities (bare + full) in a single set diff -r 0694a2611bad -r 20fb71b656e3 frontends/src/primitivus/chat.py --- a/frontends/src/primitivus/chat.py Tue Jul 19 21:25:22 2016 +0200 +++ b/frontends/src/primitivus/chat.py Sun Jul 24 17:47:09 2016 +0200 @@ -553,7 +553,7 @@ super(Chat, self)._onHistoryPrinted() def onPrivateCreated(self, widget): - self.host.contact_lists[widget.profile].specialResourceVisible(widget.target) + self.host.contact_lists[widget.profile].setSpecial(widget.target, C.CONTACT_SPECIAL_GROUP) def onSelected(self): self.focus_marker_set = False diff -r 0694a2611bad -r 20fb71b656e3 frontends/src/primitivus/contact_list.py --- a/frontends/src/primitivus/contact_list.py Tue Jul 19 21:25:22 2016 +0200 +++ b/frontends/src/primitivus/contact_list.py Sun Jul 24 17:47:09 2016 +0200 @@ -122,17 +122,6 @@ log.debug(u"Not element found for {} in setFocus".format(text)) - def specialResourceVisible(self, entity): - """Assure a resource of a special entity is visible and clickable - - Mainly used to display private conversation in MUC rooms - @param entity: full jid of the resource to show - """ - assert isinstance(entity, jid.JID) - if entity not in self._special_extras: - self._special_extras.add(entity) - self.update() - # events def _groupClicked(self, group_wid): @@ -163,7 +152,7 @@ # Methods to build the widget - def _buildEntityWidget(self, entity, keys=None, use_bare_jid=False, with_notifs=True, with_show_attr=True, markup_prepend=None, markup_append = None): + def _buildEntityWidget(self, entity, keys=None, use_bare_jid=False, with_notifs=True, with_show_attr=True, markup_prepend=None, markup_append=None, special=False): """Build one contact markup data @param entity (jid.JID): entity to build @@ -177,6 +166,7 @@ @param with_show_attr (bool): if True, show color corresponding to presence status @param markup_prepend (list): markup to prepend to the generated one before building the widget @param markup_append (list): markup to append to the generated one before building the widget + @param special (bool): True if entity is a special one @return (list): markup data are expected by Urwid text widgets """ markup = [] @@ -269,25 +259,18 @@ def _buildSpecials(self, content): """Build the special entities""" - specials = list(self.contact_list._specials) - specials.sort() - extra_shown = set() + specials = sorted(self.contact_list.getSpecials()) + current = None for entity in specials: - # the special widgets - widget = self._buildEntityWidget(entity, ('cache_nick', 'cache_name', 'node'), with_show_attr=False) - content.append(widget) - - # resources which must be displayed (e.g. MUC private conversations) - extras = [extra for extra in self.contact_list._special_extras if extra.bare == entity.bare] - extras.sort() - for extra in extras: - widget = self._buildEntityWidget(extra, ('resource',), markup_prepend = ' ') - content.append(widget) - extra_shown.add(extra) - - # entities which must be visible but not resource of current special entities - for extra in self.contact_list._special_extras.difference(extra_shown): - widget = self._buildEntityWidget(extra, ('resource',)) + if current is not None and current.bare == entity.bare: + # nested entity (e.g. MUC private conversations) + widget = self._buildEntityWidget(entity, ('resource',), markup_prepend=' ', special=True) + else: + # the special widgets + if entity.resource: + widget = self._buildEntityWidget(entity, ('resource',), special=True) + else: + widget = self._buildEntityWidget(entity, ('cache_nick', 'cache_name', 'node'), with_show_attr=False, special=True) content.append(widget) def _buildList(self): diff -r 0694a2611bad -r 20fb71b656e3 frontends/src/quick_frontend/quick_chat.py --- a/frontends/src/quick_frontend/quick_chat.py Tue Jul 19 21:25:22 2016 +0200 +++ b/frontends/src/quick_frontend/quick_chat.py Sun Jul 24 17:47:09 2016 +0200 @@ -106,7 +106,7 @@ except KeyError: log.error(u"extra data is missing user nick for uid {}".format(self.uid)) return "" - if self.parent.type == C.CHAT_GROUP or entity in contact_list.getSpecialExtras(C.CONTACT_SPECIAL_GROUP): + if self.parent.type == C.CHAT_GROUP or entity in contact_list.getSpecials(C.CONTACT_SPECIAL_GROUP): return entity.resource or "" if entity.bare in contact_list: return contact_list.getCache(entity, 'nick') or contact_list.getCache(entity, 'name') or entity.node or entity diff -r 0694a2611bad -r 20fb71b656e3 frontends/src/quick_frontend/quick_contact_list.py --- a/frontends/src/quick_frontend/quick_contact_list.py Tue Jul 19 21:25:22 2016 +0200 +++ b/frontends/src/quick_frontend/quick_contact_list.py Sun Jul 24 17:47:09 2016 +0200 @@ -56,10 +56,9 @@ # for different profiles (e.g. directed presence) self._cache = {} - # special entities (groupchat, gateways, etc), bare jids + # special entities (groupchat, gateways, etc) + # may be bare or full jid self._specials = set() - # extras are specials with full jids (e.g.: private MUC conversation) - self._special_extras = set() # group data contain jids in groups and misc frontend data # None key is used for jids with not group @@ -178,20 +177,6 @@ """ return self._cache[entity] - def getSpecialExtras(self, special_type=None): - """Return special extras with given type - - If special_type is None, return all special extras. - - @param special_type(unicode, None): one of special type (e.g. C.CONTACT_SPECIAL_GROUP) - None to return all special extras. - @return (set[jid.JID]) - """ - if special_type is None: - return self._special_extras - specials = self.getSpecials(special_type) - return {extra for extra in self._special_extras if extra.bare in specials} - def _gotContacts(self, contacts): """Called during filling, add contacts and notice parent that contacts are filled""" for contact in contacts: @@ -289,22 +274,25 @@ """Set special flag on an entity @param entity(jid.JID): jid of the special entity + if the jid is full, will be added to special extras @param special_type: one of special type (e.g. C.CONTACT_SPECIAL_GROUP) or None to remove special flag """ assert special_type in C.CONTACT_SPECIAL_ALLOWED + (None,) self.setCache(entity, C.CONTACT_SPECIAL, special_type) - def getSpecials(self, special_type=None): + def getSpecials(self, special_type=None, bare=False): """Return all the bare JIDs of the special roster entities of with given type. - If special_type is None, return all specials. - @param special_type: one of special type (e.g. C.CONTACT_SPECIAL_GROUP) or None to return all specials. - @return: set(jid.JID) + @param special_type(unicode, None): if not None, filter by special type (e.g. C.CONTACT_SPECIAL_GROUP) + @param bare(bool): return only bare jids if True + @return (iter[jid.JID]): found special entities """ - if special_type is None: - return self._specials - return set([entity for entity in self._specials if self.getCache(entity, C.CONTACT_SPECIAL) == special_type]) - + for entity in self._specials: + if bare and entity.resource: + continue + if special_type is not None and self.getCache(entity, C.CONTACT_SPECIAL) != special_type: + continue + yield entity def disconnect(self): # for now we just clear contacts on disconnect @@ -320,7 +308,6 @@ self._cache.clear() self._groups.clear() self._specials.clear() - self._special_extras.clear() self._roster.clear() self.update() @@ -369,9 +356,9 @@ if C.CONTACT_SPECIAL in attributes: if attributes[C.CONTACT_SPECIAL] is None: del attributes[C.CONTACT_SPECIAL] - self._specials.remove(entity_bare) + self._specials.remove(entity) else: - self._specials.add(entity_bare) + self._specials.add(entity) cache[C.CONTACT_MAIN_RESOURCE] = None # now the attributes we keep in cache @@ -441,7 +428,7 @@ self._groups[group]['jids'].remove(entity_bare) if not self._groups[group]['jids']: self._groups.pop(group) # FIXME: we use pop because of pyjamas: http://wiki.goffi.org/wiki/Issues_with_Pyjamas/en - for iterable in (self._selected, self._specials, self._special_extras): + for iterable in (self._selected, self._specials): to_remove = set() for set_entity in iterable: if set_entity.bare == entity.bare: