Author: steve-e
Date: 2008-04-26 12:18:33 +0200 (Sat, 26 Apr 2008)
New Revision: 9536
Modified:
trunk/src/roster_window.py
Log:
Fixing a few modelfilter bugs.
* Show all groups in merged accounts view that have online contacts. Fixes #3890
* Allow metacontacts over several accounts. Fixes #3889
* Fix on_drop_in_group when two accounts in merged view have the same contact
* Fix potential traceback when receiving a message
Modified: trunk/src/roster_window.py
===================================================================
--- trunk/src/roster_window.py 2008-04-26 02:06:08 UTC (rev 9535)
+++ trunk/src/roster_window.py 2008-04-26 10:18:33 UTC (rev 9536)
@@ -298,7 +298,8 @@
print ""
- def _add_entity(self, contact, account, groups = None, big_brother_contact = None):
+ def _add_entity(self, contact, account, groups = None, big_brother_contact = None,
+ big_brother_account = None):
'''Add the given contact to roster data model.
Contact is added regardless if he is already in roster or not.
@@ -316,7 +317,7 @@
# Add contact under big brother
parent_iters = self._get_contact_iter(big_brother_contact.jid,
- account, self.model)
+ big_brother_account, self.model)
assert len(parent_iters) > 0,\
"Big brother is not yet in roster!"
@@ -356,6 +357,11 @@
i_ = self.model.append(child_iterG, (None, contact.get_shown_name(),
typestr, contact.jid, account, None, None))
added_iters.append(i_)
+
+ # Restore the group expand state
+ if group not in gajim.groups[account]:
+ # FIXME: care about expand/collapse state
+ gajim.groups[account][group] = {'expand': True}
assert len(added_iters), "%s has not been added to roster!" % contact.jid
return added_iters
@@ -406,7 +412,7 @@
return True
- def _add_metacontact_family(self, family):
+ def _add_metacontact_family(self, family, account):
'''Add the give Metacontact family to roster data model.
Add Big Brother to his groups and all others under him.
@@ -416,17 +422,27 @@
Keyword arguments:
family -- the family, see Contacts.get_metacontacts_family()
'''
- big_brother_data = gajim.contacts.get_metacontacts_big_brother(family)
+
+ if self.regroup:
+ # group all together
+ nearby_family = family
+ else:
+ # we want one nearby_family per account
+ nearby_family = [data for data in family
+ if account == data['account']]
+
+ big_brother_data = gajim.contacts.get_metacontacts_big_brother(nearby_family)
big_brother_jid = big_brother_data['jid']
big_brother_account = big_brother_data['account']
big_brother_contact = gajim.contacts.get_first_contact_from_jid(big_brother_account, big_brother_jid)
assert len(self._get_contact_iter(big_brother_jid, big_brother_account, self.model)) == 0,\
- "Big brother %s already in roster" % big_brother_jid
+ "Big brother %s already in roster \n Family: %s" % (big_brother_jid, family)
self._add_entity(big_brother_contact, big_brother_account)
brothers = []
- for data in family:
+ # Filter family members
+ for data in nearby_family:
if data == big_brother_data:
continue # already added
@@ -437,35 +453,47 @@
if not _contact:
# Corresponding account is not connected
continue
-
+
assert len(self._get_contact_iter(_jid, _account, self.model)) == 0,\
- "%s already in roster" % _jid
- self._add_entity(_contact, _account, big_brother_contact = big_brother_contact)
+ "%s already in roster. \n Family: " % (_jid, nearby_family)
+ self._add_entity(_contact, _account, big_brother_contact = big_brother_contact,
+ big_brother_account = big_brother_account)
brothers.append((_contact, _account))
brothers.insert(0, (big_brother_contact, big_brother_account))
return brothers
- def _remove_metacontact_family(self, family):
+ def _remove_metacontact_family(self, family, account):
'''Remove the give Metacontact family from roster data model.
See Contacts.get_metacontacts_family() and RosterWindow._remove_entity()
'''
+ if self.regroup:
+ # remove all
+ nearby_family = family
+ else:
+ # remove nearby_family per account
+ nearby_family = [data for data in family
+ if account == data['account']]
+
# Family might has changed (actual big brother not on top).
- # Remove in correct order: Childs first
- for data in family:
+ # Remove childs first then big brother
+ family_in_roster = False
+ for data in nearby_family:
_account = data['account']
_jid = data['jid']
_contact = gajim.contacts.get_first_contact_from_jid(_account, _jid)
- if not _contact:
- # Corresponding account is not online
+ iters = self._get_contact_iter(_jid, _account, self.model)
+ if not iters or not _contact:
+ # Family might not be up to date.
+ # Only try to remove what is actually in the roster
continue
-
- iters = self._get_contact_iter(_jid, _account, self.model)
- assert iters, "%s shall be removed but is not in roster" % _jid
+ assert iters, "%s shall be removed but is not in roster \n Family: %s" % (_jid, family)
+ family_in_roster = True
+
parent_iter = self.model.iter_parent(iters[0])
parent_type = self.model[parent_iter][C_TYPE]
@@ -480,7 +508,10 @@
assert ok, "%s was not removed" % _jid
assert len(self._get_contact_iter(_jid, _account, self.model)) == 0,\
"%s is removed but still in roster" % _jid
-
+
+ if not family_in_roster:
+ return False
+
iters = self._get_contact_iter(old_big_jid, old_big_account, self.model)
assert len(iters) > 0, "Old Big Brother %s is not in roster anymore" % old_big_jid
assert not self.model.iter_children(iters[0]),\
@@ -558,14 +589,17 @@
contacts = []
if family:
# We have a family. So we are a metacontact.
- # Add our whole family
- contacts = self._add_metacontact_family(family)
+ # Add all family members that we shall be grouped with
+ if self.regroup:
+ # remove existing family members to regroup them
+ self._remove_metacontact_family(family, account)
+ contacts = self._add_metacontact_family(family, account)
else:
# We are a normal contact
contacts = [(contact, account),]
self._add_entity(contact, account)
- # Draw all groups of the contact
+ # Draw the contact and its groups contact
if contact.is_transport():
contact.groups = [_('Transports')]
if is_observer:
@@ -573,24 +607,14 @@
groups = contact.groups
if not groups:
groups = [_('General')]
- for group in groups:
- # Restore the group expand state
- if group not in gajim.groups[account]:
- #if account + group in self.collapsed_rows:
- #ishidden = False
- #else:
- ishidden = True
- gajim.groups[account][group] = {'expand': ishidden}
-
- if not self.starting:
- self.draw_group(group, account)
-
if not self.starting:
for c, acc in contacts:
self.draw_contact(c.jid, acc)
self.draw_avatar(c.jid, acc)
+ for group in groups:
+ self.draw_group(group, account)
self.draw_account(account)
-
+
return contacts[0][0] # it's contact/big brother with highest priority
@@ -617,7 +641,7 @@
family = gajim.contacts.get_metacontacts_family(account, jid)
if family:
# We have a family. So we are a metacontact.
- self._remove_metacontact_family(family)
+ self._remove_metacontact_family(family, account)
else:
self._remove_entity(contact, account)
@@ -730,7 +754,7 @@
for contact in gajim.contacts.get_contacts(account, jid):
for group in groups:
if group not in contact.groups:
- # statement needed for drap from meta to group
+ # we might be dropped from meta to group
contact.groups.append(group)
gajim.connections[account].update_contact(jid, contact.name,
contact.groups)
@@ -961,7 +985,16 @@
brothers = []
family = gajim.contacts.get_metacontacts_family(account, jid)
if family: # Are we a metacontact (have a familiy)
- big_brother_data = gajim.contacts.get_metacontacts_big_brother(family)
+
+ if self.regroup:
+ # group all together
+ nearby_family = family
+ else:
+ # we want one nearby_family per account
+ nearby_family = [data for data in family
+ if account == data['account']]
+
+ big_brother_data = gajim.contacts.get_metacontacts_big_brother(nearby_family)
big_brother_jid = big_brother_data['jid']
big_brother_account = big_brother_data['account']
@@ -975,8 +1008,8 @@
else:
# We are the new big brother but haven't been before
# Remove us and all our brothers and then re-add us so that
- self._remove_metacontact_family(family)
- brothers = self._add_metacontact_family(family)
+ self._remove_metacontact_family(family, account)
+ brothers = self._add_metacontact_family(family, account)
big_brother_c, big_brother_acc = brothers[0]
brothers = brothers[1:]
self.draw_avatar(big_brother_c.jid, big_brother_acc)
@@ -1177,11 +1210,22 @@
if not type_:
return False
if type_ == 'account':
+ # Always show account
return True
+
account = model[iter][C_ACCOUNT]
if not account:
return False
+
account = account.decode('utf-8')
+ if self.regroup:
+ # C_ACCOUNT for groups depends on the order
+ # accounts were connected
+ # Check all accounts for online group contacts
+ accounts = gajim.contacts.get_accounts()
+ else:
+ accounts = [account]
+
jid = model[iter][C_JID]
if not jid:
return False
@@ -1191,12 +1235,13 @@
group = jid
if group == _('Transports'):
return gajim.config.get('show_transports_group')
- for contact in gajim.contacts.iter_contacts(account):
- # Is this contact in this group ?
- if group in contact.groups or (group == _('General') and not \
- contact.groups):
- if self.contact_is_visible(contact, account):
- return True
+ for _acc in accounts:
+ for contact in gajim.contacts.iter_contacts(_acc):
+ # Is this contact in this group ?
+ if group in contact.groups or (group == _('General') and not \
+ contact.groups):
+ if self.contact_is_visible(contact, _acc):
+ return True
return False
if type_ == 'contact':
contact = gajim.contacts.get_first_contact_from_jid(account, jid)
@@ -1903,6 +1948,7 @@
# If visible, try to get first line of contact in roster
+ path = None
iters = self._get_contact_iter(jid, account)
if iters:
path = self.modelfilter.get_path(iters[0])
@@ -3526,11 +3572,12 @@
else:
gajim.config.set('confirm_metacontacts', 'yes')
- # We might have dropped on a metacontact. Readd it.
+ # We might have dropped on a metacontact.
+ # Remove it and readd later with updated family info
dest_family = gajim.contacts.get_metacontacts_family(account_dest,
c_dest.jid)
if dest_family:
- self._remove_metacontact_family(dest_family)
+ self._remove_metacontact_family(dest_family, account_dest)
else:
self._remove_entity(c_dest, account_dest)
@@ -3541,18 +3588,25 @@
# Remove old source contact(s)
if was_big_brother:
# We have got little brothers. Readd them all
- self._remove_metacontact_family(old_family)
+ self._remove_metacontact_family(old_family, account_source)
else:
# We are only a litle brother. Simply remove us from our big brother
- self._remove_entity(c_source, account_source)
+ if self._get_contact_iter(c_source.jid, account_source):
+ # When we have been in the group before.
+ # Do not try to remove us again
+ self._remove_entity(c_source, account_source)
- own_data = {}
- own_data['jid'] = c_source.jid
- own_data['account'] = account_source
- old_family.append(own_data)
+ own_data = {}
+ own_data['jid'] = c_source.jid
+ own_data['account'] = account_source
+ # Don't touch the rest of the family
+ old_family = [own_data]
# Apply new tag and update contact
for data in old_family:
+ if account_source != data['account'] and not self.regroup:
+ continue
+
_account = data['account']
_jid = data['jid']
_contact = gajim.contacts.get_first_contact_from_jid(_account, _jid)
@@ -3566,7 +3620,7 @@
# Re-add all and update GUI
new_family = gajim.contacts.get_metacontacts_family(account_source,
c_source.jid)
- brothers = self._add_metacontact_family(new_family)
+ brothers = self._add_metacontact_family(new_family, account_source)
for c, acc in brothers:
self.draw_contact(c.jid, acc)
@@ -3608,18 +3662,21 @@
# Little brother
# Remove whole family. Remove us from the family.
# Then re-add other family members.
- self._remove_metacontact_family(family)
+ self._remove_metacontact_family(family, account)
gajim.contacts.remove_metacontact(account, c_source.jid)
for data in family:
- if data['jid'] == c_source.jid:
+ if account != data['account'] and not self.regroup:
continue
+ if data['jid'] == c_source.jid and\
+ data['account'] == account:
+ continue
self.add_contact(data['jid'], data['account'])
break;
self.add_contact_to_groups(c_source.jid, account, [grp_dest,])
else:
- # Simple contact
+ # Normal contact
self.remove_contact_from_groups(c_source.jid, account, [grp_source,])
self.add_contact_to_groups(c_source.jid, account, [grp_dest,])
@@ -5656,8 +5713,8 @@
self.tree = self.xml.get_widget('roster_treeview')
sel = self.tree.get_selection()
sel.set_mode(gtk.SELECTION_MULTIPLE)
- sel.connect('changed',
- self.on_treeview_selection_changed)
+ #sel.connect('changed',
+ # self.on_treeview_selection_changed)
self._last_selected_contact = [] # holds a list of (jid, account) tupples
self.transports_state_images = {'16': {}, '32': {}, 'opened': {},