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:
Stephan Erb 2008-04-20 14:01:04 +00:00
parent 0374e72b28
commit 4e6bd4ee8f
6 changed files with 4871 additions and 4402 deletions

View File

@ -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)

View File

@ -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 \

View File

@ -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

View File

@ -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)

View File

@ -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'):

File diff suppressed because it is too large Load Diff