Port roster_window to gtk.TreeModelFilter.
Contacts are now online hidden when they connect/reconnect and not completely removed/readded. Should come with a great speed improvement for people with big rosters. There are still a few known problems but non that should dalay this patch any longer. Related bugs will be tracked with 'modelfilter' keyword. See #1201
This commit is contained in:
parent
0374e72b28
commit
4e6bd4ee8f
|
@ -2108,7 +2108,7 @@ class ChatControl(ChatControlBase):
|
||||||
if (not show_transports and gajim.jid_is_transport(jid)) or \
|
if (not show_transports and gajim.jid_is_transport(jid)) or \
|
||||||
(not show_offline and typ == 'chat' and \
|
(not show_offline and typ == 'chat' and \
|
||||||
len(gajim.contacts.get_contacts(self.account, jid)) < 2):
|
len(gajim.contacts.get_contacts(self.account, jid)) < 2):
|
||||||
gajim.interface.roster.really_remove_contact(self.contact,
|
gajim.interface.roster.remove_to_be_removed(self.contact.jid,
|
||||||
self.account)
|
self.account)
|
||||||
elif typ == 'pm':
|
elif typ == 'pm':
|
||||||
control.remove_contact(nick)
|
control.remove_contact(nick)
|
||||||
|
|
|
@ -245,6 +245,11 @@ class Contacts:
|
||||||
return c
|
return c
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def iter_contacts(self, account):
|
||||||
|
for jid in self._contacts[account]:
|
||||||
|
for contact in self._contacts[account][jid]:
|
||||||
|
yield contact
|
||||||
|
|
||||||
def get_contact_from_full_jid(self, account, fjid):
|
def get_contact_from_full_jid(self, account, fjid):
|
||||||
''' Get Contact object for specific resource of given jid'''
|
''' Get Contact object for specific resource of given jid'''
|
||||||
barejid, resource = common.gajim.get_room_and_nick_from_fjid(fjid)
|
barejid, resource = common.gajim.get_room_and_nick_from_fjid(fjid)
|
||||||
|
@ -292,10 +297,6 @@ class Contacts:
|
||||||
for account in accounts:
|
for account in accounts:
|
||||||
our_jid = common.gajim.get_jid_from_account(account)
|
our_jid = common.gajim.get_jid_from_account(account)
|
||||||
for jid in self.get_jid_list(account):
|
for jid in self.get_jid_list(account):
|
||||||
if self.has_brother(account, jid) and not \
|
|
||||||
self.is_big_brother(account, jid):
|
|
||||||
# count metacontacts only once
|
|
||||||
continue
|
|
||||||
if jid == our_jid:
|
if jid == our_jid:
|
||||||
continue
|
continue
|
||||||
if common.gajim.jid_is_transport(jid) and not \
|
if common.gajim.jid_is_transport(jid) and not \
|
||||||
|
|
|
@ -91,63 +91,21 @@ class EditGroupsDialog:
|
||||||
if response_id == gtk.RESPONSE_CLOSE:
|
if response_id == gtk.RESPONSE_CLOSE:
|
||||||
self.dialog.destroy()
|
self.dialog.destroy()
|
||||||
|
|
||||||
def update_contact(self):
|
|
||||||
for (contact, account) in self.list_:
|
|
||||||
tag = gajim.contacts.get_metacontacts_tag(account, contact.jid)
|
|
||||||
if not tag:
|
|
||||||
gajim.interface.roster.remove_contact(contact, account)
|
|
||||||
gajim.interface.roster.add_contact_to_roster(contact.jid, account)
|
|
||||||
gajim.connections[account].update_contact(contact.jid, contact.name,
|
|
||||||
contact.groups)
|
|
||||||
continue
|
|
||||||
all_jid = gajim.contacts.get_metacontacts_jids(tag)
|
|
||||||
for _account in all_jid:
|
|
||||||
if not gajim.interface.roster.regroup and _account != account:
|
|
||||||
continue
|
|
||||||
for _jid in all_jid[_account]:
|
|
||||||
c = gajim.contacts.get_first_contact_from_jid(_account, _jid)
|
|
||||||
if not c:
|
|
||||||
continue
|
|
||||||
gajim.interface.roster.remove_contact(c, _account)
|
|
||||||
gajim.interface.roster.add_contact_to_roster(_jid, _account)
|
|
||||||
gajim.connections[_account].update_contact(_jid, c.name,
|
|
||||||
c.groups)
|
|
||||||
|
|
||||||
def remove_group(self, group):
|
def remove_group(self, group):
|
||||||
'''remove group group from all contacts and all their brothers'''
|
'''remove group group from all contacts and all their brothers'''
|
||||||
for (contact, account) in self.list_:
|
for (contact, account) in self.list_:
|
||||||
tag = gajim.contacts.get_metacontacts_tag(account, contact.jid)
|
gajim.interface.roster.remove_contact_from_groups(contact.jid, account, [group])
|
||||||
if not tag:
|
|
||||||
if group in contact.groups:
|
# FIXME: Ugly workaround.
|
||||||
contact.groups.remove(group)
|
gajim.interface.roster.draw_group(_('General'), account)
|
||||||
continue
|
|
||||||
all_jid = gajim.contacts.get_metacontacts_jids(tag)
|
|
||||||
for _account in all_jid:
|
|
||||||
if not gajim.interface.roster.regroup and _account != account:
|
|
||||||
continue
|
|
||||||
for _jid in all_jid[_account]:
|
|
||||||
contacts = gajim.contacts.get_contacts(_account, _jid)
|
|
||||||
for c in contacts:
|
|
||||||
if group in c.groups:
|
|
||||||
c.groups.remove(group)
|
|
||||||
|
|
||||||
def add_group(self, group):
|
def add_group(self, group):
|
||||||
'''add group group to all contacts and all their brothers'''
|
'''add group group to all contacts and all their brothers'''
|
||||||
for (contact, account) in self.list_:
|
for (contact, account) in self.list_:
|
||||||
tag = gajim.contacts.get_metacontacts_tag(account, contact.jid)
|
gajim.interface.roster.add_contact_to_groups(contact.jid, account, [group])
|
||||||
if not tag:
|
|
||||||
if group not in contact.groups:
|
# FIXME: Ugly workaround. Maybe we haven't been in any group (defaults to General)
|
||||||
contact.groups.append(group)
|
gajim.interface.roster.draw_group(_('General'), account)
|
||||||
continue
|
|
||||||
all_jid = gajim.contacts.get_metacontacts_jids(tag)
|
|
||||||
for _account in all_jid:
|
|
||||||
if not gajim.interface.roster.regroup and _account != account:
|
|
||||||
continue
|
|
||||||
for _jid in all_jid[_account]:
|
|
||||||
contacts = gajim.contacts.get_contacts(_account, _jid)
|
|
||||||
for c in contacts:
|
|
||||||
if not group in c.groups:
|
|
||||||
c.groups.append(group)
|
|
||||||
|
|
||||||
def on_add_button_clicked(self, widget):
|
def on_add_button_clicked(self, widget):
|
||||||
group = self.xml.get_widget('group_entry').get_text().decode('utf-8')
|
group = self.xml.get_widget('group_entry').get_text().decode('utf-8')
|
||||||
|
@ -166,7 +124,6 @@ class EditGroupsDialog:
|
||||||
self.changes_made = True
|
self.changes_made = True
|
||||||
model.append((group, True, False))
|
model.append((group, True, False))
|
||||||
self.add_group(group)
|
self.add_group(group)
|
||||||
self.update_contact()
|
|
||||||
self.init_list() # Re-draw list to sort new item
|
self.init_list() # Re-draw list to sort new item
|
||||||
|
|
||||||
def group_toggled_cb(self, cell, path):
|
def group_toggled_cb(self, cell, path):
|
||||||
|
@ -182,7 +139,6 @@ class EditGroupsDialog:
|
||||||
self.add_group(group)
|
self.add_group(group)
|
||||||
else:
|
else:
|
||||||
self.remove_group(group)
|
self.remove_group(group)
|
||||||
self.update_contact()
|
|
||||||
|
|
||||||
def init_list(self):
|
def init_list(self):
|
||||||
store = gtk.ListStore(str, bool, bool)
|
store = gtk.ListStore(str, bool, bool)
|
||||||
|
@ -200,7 +156,11 @@ class EditGroupsDialog:
|
||||||
if g in groups:
|
if g in groups:
|
||||||
continue
|
continue
|
||||||
groups[g] = 0
|
groups[g] = 0
|
||||||
for g in contact.groups:
|
c_groups = contact.groups
|
||||||
|
# FIXME: Move to backend
|
||||||
|
if not c_groups:
|
||||||
|
c_groups = [_('General')]
|
||||||
|
for g in c_groups:
|
||||||
groups[g] += 1
|
groups[g] += 1
|
||||||
group_list = []
|
group_list = []
|
||||||
# Remove special groups if they are empty
|
# Remove special groups if they are empty
|
||||||
|
|
36
src/gajim.py
36
src/gajim.py
|
@ -644,7 +644,6 @@ class Interface:
|
||||||
old_show = 0
|
old_show = 0
|
||||||
gajim.contacts.add_contact(account, contact1)
|
gajim.contacts.add_contact(account, contact1)
|
||||||
lcontact.append(contact1)
|
lcontact.append(contact1)
|
||||||
self.roster.add_self_contact(account)
|
|
||||||
elif contact1.show in statuss:
|
elif contact1.show in statuss:
|
||||||
old_show = statuss.index(contact1.show)
|
old_show = statuss.index(contact1.show)
|
||||||
if (resources != [''] and (len(lcontact) != 1 or
|
if (resources != [''] and (len(lcontact) != 1 or
|
||||||
|
@ -653,6 +652,9 @@ class Interface:
|
||||||
contact1 = gajim.contacts.copy_contact(contact1)
|
contact1 = gajim.contacts.copy_contact(contact1)
|
||||||
lcontact.append(contact1)
|
lcontact.append(contact1)
|
||||||
contact1.resource = resource
|
contact1.resource = resource
|
||||||
|
# FIXME ugly workaround for self contact
|
||||||
|
self.roster.add_contact(contact1.jid, account)
|
||||||
|
|
||||||
if contact1.jid.find('@') > 0 and len(lcontact) == 1:
|
if contact1.jid.find('@') > 0 and len(lcontact) == 1:
|
||||||
# It's not an agent
|
# It's not an agent
|
||||||
if old_show == 0 and new_show > 1:
|
if old_show == 0 and new_show > 1:
|
||||||
|
@ -669,8 +671,8 @@ class Interface:
|
||||||
if contact1.jid in gajim.newly_added[account]:
|
if contact1.jid in gajim.newly_added[account]:
|
||||||
gajim.newly_added[account].remove(contact1.jid)
|
gajim.newly_added[account].remove(contact1.jid)
|
||||||
self.roster.draw_contact(contact1.jid, account)
|
self.roster.draw_contact(contact1.jid, account)
|
||||||
gobject.timeout_add_seconds(5, self.roster.really_remove_contact,
|
gobject.timeout_add_seconds(5, self.roster.remove_to_be_removed,
|
||||||
contact1, account)
|
contact1.jid, account)
|
||||||
contact1.show = array[1]
|
contact1.show = array[1]
|
||||||
contact1.status = status_message
|
contact1.status = status_message
|
||||||
contact1.priority = priority
|
contact1.priority = priority
|
||||||
|
@ -686,6 +688,7 @@ class Interface:
|
||||||
# It must be an agent
|
# It must be an agent
|
||||||
if ji in jid_list:
|
if ji in jid_list:
|
||||||
# Update existing iter
|
# Update existing iter
|
||||||
|
self.roster.modelfilter.refilter()
|
||||||
self.roster.draw_contact(ji, account)
|
self.roster.draw_contact(ji, account)
|
||||||
self.roster.draw_group(_('Transports'), account)
|
self.roster.draw_group(_('Transports'), account)
|
||||||
if new_show > 1 and ji in gajim.transport_avatar[account]:
|
if new_show > 1 and ji in gajim.transport_avatar[account]:
|
||||||
|
@ -942,10 +945,10 @@ class Interface:
|
||||||
if jid in gajim.contacts.get_jid_list(account):
|
if jid in gajim.contacts.get_jid_list(account):
|
||||||
c = gajim.contacts.get_first_contact_from_jid(account, jid)
|
c = gajim.contacts.get_first_contact_from_jid(account, jid)
|
||||||
c.resource = array[1]
|
c.resource = array[1]
|
||||||
self.roster.remove_contact(c, account)
|
self.roster.remove_contact(c.jid, account)
|
||||||
if _('Not in Roster') in c.groups:
|
if _('Not in Roster') in c.groups:
|
||||||
c.groups.remove(_('Not in Roster'))
|
c.groups.remove(_('Not in Roster'))
|
||||||
self.roster.add_contact_to_roster(c.jid, account)
|
self.roster.add_contact(c.jid, account)
|
||||||
else:
|
else:
|
||||||
keyID = ''
|
keyID = ''
|
||||||
attached_keys = gajim.config.get_per('accounts', account,
|
attached_keys = gajim.config.get_per('accounts', account,
|
||||||
|
@ -958,7 +961,7 @@ class Interface:
|
||||||
groups = [], show = 'online', status = 'online',
|
groups = [], show = 'online', status = 'online',
|
||||||
ask = 'to', resource = array[1], keyID = keyID)
|
ask = 'to', resource = array[1], keyID = keyID)
|
||||||
gajim.contacts.add_contact(account, contact1)
|
gajim.contacts.add_contact(account, contact1)
|
||||||
self.roster.add_contact_to_roster(jid, account)
|
self.roster.add_contact(jid, account)
|
||||||
dialogs.InformationDialog(_('Authorization accepted'),
|
dialogs.InformationDialog(_('Authorization accepted'),
|
||||||
_('The contact "%s" has authorized you to see his or her status.')
|
_('The contact "%s" has authorized you to see his or her status.')
|
||||||
% jid)
|
% jid)
|
||||||
|
@ -1013,7 +1016,7 @@ class Interface:
|
||||||
# This way we'll really remove it
|
# This way we'll really remove it
|
||||||
gajim.to_be_removed[account].remove(c.jid)
|
gajim.to_be_removed[account].remove(c.jid)
|
||||||
gajim.contacts.remove_jid(account, c.jid)
|
gajim.contacts.remove_jid(account, c.jid)
|
||||||
self.roster.remove_contact(c, account)
|
self.roster.remove_contact(c.jid, account)
|
||||||
|
|
||||||
def handle_event_register_agent_info(self, account, array):
|
def handle_event_register_agent_info(self, account, array):
|
||||||
# ('REGISTER_AGENT_INFO', account, (agent, infos, is_form))
|
# ('REGISTER_AGENT_INFO', account, (agent, infos, is_form))
|
||||||
|
@ -1476,7 +1479,7 @@ class Interface:
|
||||||
not name and not groups:
|
not name and not groups:
|
||||||
if contacts:
|
if contacts:
|
||||||
c = contacts[0]
|
c = contacts[0]
|
||||||
self.roster.remove_contact(c, account)
|
self.roster.remove_contact(c.jid, account)
|
||||||
gajim.contacts.remove_jid(account, jid)
|
gajim.contacts.remove_jid(account, jid)
|
||||||
self.roster.draw_account(account)
|
self.roster.draw_account(account)
|
||||||
if gajim.events.get_events(account, c.jid):
|
if gajim.events.get_events(account, c.jid):
|
||||||
|
@ -1490,7 +1493,7 @@ class Interface:
|
||||||
show = 'not in roster', status = '', sub = 'none',
|
show = 'not in roster', status = '', sub = 'none',
|
||||||
keyID = keyID)
|
keyID = keyID)
|
||||||
gajim.contacts.add_contact(account, contact)
|
gajim.contacts.add_contact(account, contact)
|
||||||
self.roster.add_contact_to_roster(contact.jid, account)
|
self.roster.add_contact(contact.jid, account)
|
||||||
#FIXME if it was the only one in its group, remove the group
|
#FIXME if it was the only one in its group, remove the group
|
||||||
return
|
return
|
||||||
elif not contacts:
|
elif not contacts:
|
||||||
|
@ -1500,12 +1503,12 @@ class Interface:
|
||||||
contact = gajim.contacts.create_contact(jid = jid, name = name,
|
contact = gajim.contacts.create_contact(jid = jid, name = name,
|
||||||
groups = groups, show = 'offline', sub = sub, ask = ask)
|
groups = groups, show = 'offline', sub = sub, ask = ask)
|
||||||
gajim.contacts.add_contact(account, contact)
|
gajim.contacts.add_contact(account, contact)
|
||||||
self.roster.add_contact_to_roster(jid, account)
|
self.roster.add_contact(jid, account)
|
||||||
else:
|
else:
|
||||||
re_add = False
|
re_add = False
|
||||||
# if sub changed: remove and re-add, maybe observer status changed
|
# if sub changed: remove and re-add, maybe observer status changed
|
||||||
if contacts[0].sub != sub:
|
if contacts[0].sub != sub:
|
||||||
self.roster.remove_contact(contacts[0], account)
|
self.roster.remove_contact(contacts[0].jid, account)
|
||||||
re_add = True
|
re_add = True
|
||||||
for contact in contacts:
|
for contact in contacts:
|
||||||
if not name:
|
if not name:
|
||||||
|
@ -1516,7 +1519,7 @@ class Interface:
|
||||||
if groups:
|
if groups:
|
||||||
contact.groups = groups
|
contact.groups = groups
|
||||||
if re_add:
|
if re_add:
|
||||||
self.roster.add_contact_to_roster(jid, account)
|
self.roster.add_contact(jid, account)
|
||||||
self.roster.draw_contact(jid, account)
|
self.roster.draw_contact(jid, account)
|
||||||
if self.remote_ctrl:
|
if self.remote_ctrl:
|
||||||
self.remote_ctrl.raise_signal('RosterInfo', (account, array))
|
self.remote_ctrl.raise_signal('RosterInfo', (account, array))
|
||||||
|
@ -1666,7 +1669,7 @@ class Interface:
|
||||||
if no_queue: # We didn't have a queue: we change icons
|
if no_queue: # We didn't have a queue: we change icons
|
||||||
if not gajim.contacts.get_contact_with_highest_priority(account, jid):
|
if not gajim.contacts.get_contact_with_highest_priority(account, jid):
|
||||||
if type_ == 'gc-invitation':
|
if type_ == 'gc-invitation':
|
||||||
self.roster.add_groupchat_to_roster(account, jid,
|
self.roster.add_groupchat(account, jid,
|
||||||
status='offline')
|
status='offline')
|
||||||
else:
|
else:
|
||||||
# add contact to roster ("Not In The Roster") if he is not
|
# add contact to roster ("Not In The Roster") if he is not
|
||||||
|
@ -1674,8 +1677,7 @@ class Interface:
|
||||||
self.roster.draw_contact(jid, account)
|
self.roster.draw_contact(jid, account)
|
||||||
|
|
||||||
# Show contact in roster (if he is invisible for example) and select line
|
# Show contact in roster (if he is invisible for example) and select line
|
||||||
path = self.roster.get_path(jid, account)
|
self.roster.show_and_select_contact_if_having_events(jid, account)
|
||||||
self.roster.show_and_select_path(path, jid, account)
|
|
||||||
|
|
||||||
def remove_first_event(self, account, jid, type_ = None):
|
def remove_first_event(self, account, jid, type_ = None):
|
||||||
event = gajim.events.get_first_event(account, jid, type_)
|
event = gajim.events.get_first_event(account, jid, type_)
|
||||||
|
@ -1693,7 +1695,7 @@ class Interface:
|
||||||
if contact and (contact.show in ('error', 'offline') and \
|
if contact and (contact.show in ('error', 'offline') and \
|
||||||
not gajim.config.get('showoffline') or (
|
not gajim.config.get('showoffline') or (
|
||||||
gajim.jid_is_transport(jid) and not show_transport)):
|
gajim.jid_is_transport(jid) and not show_transport)):
|
||||||
self.roster.really_remove_contact(contact, account)
|
self.roster.remove_contact(contact.jid, account)
|
||||||
self.roster.show_title()
|
self.roster.show_title()
|
||||||
self.roster.draw_contact(jid, account)
|
self.roster.draw_contact(jid, account)
|
||||||
|
|
||||||
|
@ -1739,7 +1741,7 @@ class Interface:
|
||||||
groups = [_('Not in Roster')], show = 'not in roster', status = '',
|
groups = [_('Not in Roster')], show = 'not in roster', status = '',
|
||||||
sub = 'none', keyID = keyID)
|
sub = 'none', keyID = keyID)
|
||||||
gajim.contacts.add_contact(account, contact)
|
gajim.contacts.add_contact(account, contact)
|
||||||
self.roster.add_contact_to_roster(contact.jid, account)
|
self.roster.add_contact(contact.jid, account)
|
||||||
file_props = array[1]
|
file_props = array[1]
|
||||||
contact = gajim.contacts.get_first_contact_from_jid(account, jid)
|
contact = gajim.contacts.get_first_contact_from_jid(account, jid)
|
||||||
|
|
||||||
|
|
|
@ -1587,7 +1587,7 @@ class GroupchatControl(ChatControlBase):
|
||||||
|
|
||||||
del win._controls[self.account][self.contact.jid]
|
del win._controls[self.account][self.contact.jid]
|
||||||
|
|
||||||
gajim.interface.roster.add_groupchat_to_roster(self.account,
|
gajim.interface.roster.add_groupchat(self.account,
|
||||||
self.contact.jid, status = self.subject)
|
self.contact.jid, status = self.subject)
|
||||||
|
|
||||||
def shutdown(self, status='offline'):
|
def shutdown(self, status='offline'):
|
||||||
|
|
9128
src/roster_window.py
9128
src/roster_window.py
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue