From 7378efcb21c0669aa757181199e27c08889c212e Mon Sep 17 00:00:00 2001 From: Benjamin Richter Date: Sat, 26 Sep 2009 20:23:59 +0200 Subject: [PATCH] Improve group renaming efficiency. Fixes #4212 --- src/common/connection.py | 5 ++ src/common/xmpp/roster_nb.py | 10 ++++ src/common/zeroconf/connection_zeroconf.py | 5 ++ src/common/zeroconf/roster_zeroconf.py | 4 ++ src/roster_window.py | 63 ++++++++++++++++------ 5 files changed, 70 insertions(+), 17 deletions(-) diff --git a/src/common/connection.py b/src/common/connection.py index 27b840f7b..bcbdc459a 100644 --- a/src/common/connection.py +++ b/src/common/connection.py @@ -1487,6 +1487,11 @@ class Connection(ConnectionHandlers): self.connection.getRoster().setItem(jid = jid, name = name, groups = groups) + def update_contacts(self, contacts): + '''update multiple roster items on jabber server''' + if self.connection: + self.connection.getRoster().setItemMulti(contacts) + def send_new_account_infos(self, form, is_form): if is_form: # Get username and password and put them in new_account_info diff --git a/src/common/xmpp/roster_nb.py b/src/common/xmpp/roster_nb.py index a34e6ced1..715476b9e 100644 --- a/src/common/xmpp/roster_nb.py +++ b/src/common/xmpp/roster_nb.py @@ -174,6 +174,16 @@ class NonBlockingRoster(PlugIn): item=query.setTag('item',attrs) for group in groups: item.addChild(node=Node('group',payload=[group])) self._owner.send(iq) + def setItemMulti(self,items): + ''' Renames multiple contacts and sets their group lists.''' + iq=Iq('set',NS_ROSTER) + query=iq.getTag('query') + for i in items: + attrs={'jid':i['jid']} + if i['name']: attrs['name']=i['name'] + item=query.setTag('item',attrs) + for group in i['groups']: item.addChild(node=Node('group',payload=[group])) + self._owner.send(iq) def getItems(self): ''' Return list of all [bare] JIDs that the roster is currently tracks.''' return self._data.keys() diff --git a/src/common/zeroconf/connection_zeroconf.py b/src/common/zeroconf/connection_zeroconf.py index e832378bc..c23f4a125 100644 --- a/src/common/zeroconf/connection_zeroconf.py +++ b/src/common/zeroconf/connection_zeroconf.py @@ -526,6 +526,11 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf): self.connection.getRoster().setItem(jid = jid, name = name, groups = groups) + def update_contacts(self, contacts): + '''update multiple roster items''' + if self.connection: + self.connection.getRoster().setItemMulti(contacts) + def new_account(self, name, config, sync = False): gajim.log.debug('This should not happen (new_account)') diff --git a/src/common/zeroconf/roster_zeroconf.py b/src/common/zeroconf/roster_zeroconf.py index 38808b06b..42fe0edd6 100644 --- a/src/common/zeroconf/roster_zeroconf.py +++ b/src/common/zeroconf/roster_zeroconf.py @@ -88,6 +88,10 @@ class Roster: self._data[jid]['status'] = status self._data[jid]['show'] = status + def setItemMulti(self, items): + for i in items: + self.setItem(jid=i['jid'], name=i['name'], groups=i['groups']) + def delItem(self, jid): #print 'roster_zeroconf.py: delItem %s' % jid if jid in self._data: diff --git a/src/roster_window.py b/src/roster_window.py index 7bc4c1cf1..c5eb1474e 100644 --- a/src/roster_window.py +++ b/src/roster_window.py @@ -848,6 +848,51 @@ class RosterWindow: '''Remove transport from roster and redraw account and group.''' self.remove_contact(jid, account, force=True, backend=True) return True + + def rename_group(self, old_name, new_name): + """ + rename a roster group + """ + if old_name == new_name: + return + + # Groups may not change name from or to a special groups + for g in helpers.special_groups: + if g in (new_name, old_name): + return + + # update all contacts in the given group + if self.regroup: + accounts = gajim.connections.keys() + else: + accounts = [account,] + + for acc in accounts: + changed_contacts = [] + for jid in gajim.contacts.get_jid_list(acc): + contact = gajim.contacts.get_first_contact_from_jid(acc, jid) + if old_name not in contact.groups: + continue + + self.remove_contact(jid, acc, force=True) + + contact.groups.remove(old_name) + if new_name not in contact.groups: + contact.groups.append(new_name) + + changed_contacts.append({'jid':jid, 'name':contact.name, + 'groups':contact.groups}) + + gajim.connections[acc].update_contacts(changed_contacts) + + for c in changed_contacts: + self.add_contact(c['jid'], acc) + + self._adjust_group_expand_collapse_state(new_name, acc) + + self.draw_group(old_name, acc) + self.draw_group(new_name, acc) + def add_contact_to_groups(self, jid, account, groups, update=True): '''Add contact to given groups and redraw them. @@ -2711,23 +2756,7 @@ class RosterWindow: win.show_title() elif row_type == 'group': # in C_JID column, we hold the group name (which is not escaped) - if old_text == new_text: - return - # Groups may not change name from or to a special groups - for g in helpers.special_groups: - if g in (new_text, old_text): - return - # update all contacts in the given group - if self.regroup: - accounts = gajim.connections.keys() - else: - accounts = [account,] - for acc in accounts: - for jid in gajim.contacts.get_jid_list(acc): - contact = gajim.contacts.get_first_contact_from_jid(acc, jid) - if old_text in contact.groups: - self.add_contact_to_groups(jid, acc, [new_text,]) - self.remove_contact_from_groups(jid, acc, [old_text,]) + self.rename_group(old_text, new_text) def on_canceled(): if 'rename' in gajim.interface.instances: