New metacontact way. JEP is not published yet, but I talked with the author. Old metacontact info are removed automaticaly

This commit is contained in:
Yann Leboulanger 2006-03-24 12:55:56 +00:00
parent 21a27b6072
commit f8db75e255
6 changed files with 302 additions and 287 deletions

View File

@ -302,7 +302,6 @@ class ChatControlBase(MessageControl):
# NOTE: handles mykeypress which is custom signal connected to this
# CB in new_tab(). for this singal see message_textview.py
jid = self.contact.jid
message_textview = widget
message_buffer = message_textview.get_buffer()
start_iter, end_iter = message_buffer.get_bounds()
@ -1450,12 +1449,7 @@ class ChatControl(ChatControlBase):
gajim.interface.roster.draw_contact(jid, self.account)
# Redraw parent too
contact = gajim.contacts.get_contact_with_highest_priority(self.account,
jid)
if gajim.contacts.is_subcontact(self.account, contact):
parent_contact = gajim.contacts.get_parent_contact(
self.account, contact)
gajim.interface.roster.draw_contact(parent_contact.jid, self.account)
gajim.interface.roster.draw_parent_contact(jid, self.account)
if gajim.interface.systray_enabled:
gajim.interface.systray.remove_jid(jid, self.account, typ)
if (self.contact.show == 'offline' or self.contact.show == 'error'):

View File

@ -342,8 +342,8 @@ class Connection(ConnectionHandlers):
con.RegisterDisconnectHandler(self._disconnectedReconnCB)
gajim.log.debug(_('Connected to server %s:%s with %s') % (self._current_host['host'],
self._current_host['port'], con_type))
# Ask meta_contacts before roster
self.get_meta_contacts()
# Ask metacontacts before roster
self.get_metacontacts()
self._register_handlers(con, con_type)
return True
@ -494,8 +494,8 @@ class Connection(ConnectionHandlers):
if self.connection:
con.set_send_timeout(self.keepalives, self.send_keepalive)
self.connection.onreceive(None)
# Ask meta_contacts before roster
self.get_meta_contacts()
# Ask metacontacts before roster
self.get_metacontacts()
def change_status(self, show, msg, sync = False, auto = False):
if not show in STATUS_LIST:
@ -807,26 +807,35 @@ class Connection(ConnectionHandlers):
iq5 = iq4.setTagData('password', bm['password'])
self.connection.send(iq)
def get_meta_contacts(self):
'''Get meta_contacts list from storage as described in JEP 0049'''
def get_metacontacts(self):
'''Get metacontacts list from storage as described in JEP 0049'''
if not self.connection:
return
iq = common.xmpp.Iq(typ='get')
iq2 = iq.addChild(name='query', namespace='jabber:iq:private')
iq2.addChild(name='storage', namespace='storage:metacontacts')
self.connection.send(iq)
#FIXME: remove the old infos, remove that before 0.10
iq = common.xmpp.Iq(typ='set')
iq2 = iq.addChild(name='query', namespace='jabber:iq:private')
iq2.addChild(name='gajim', namespace='gajim:metacontacts')
self.connection.send(iq)
def store_meta_contacts(self, children_list):
def store_metacontacts(self, tags_list):
''' Send meta contacts to the storage namespace '''
if not self.connection:
return
iq = common.xmpp.Iq(typ='set')
iq2 = iq.addChild(name='query', namespace='jabber:iq:private')
iq3 = iq2.addChild(name='gajim', namespace='gajim:metacontacts')
for parent_jid in children_list:
parent_tag = iq3.addChild(name='parent', attrs = {'name': parent_jid})
for child_jid in children_list[parent_jid]:
parent_tag.addChild(name='child', attrs = {'name': child_jid})
iq3 = iq2.addChild(name='storage', namespace='storage:metacontacts')
for tag in tags_list:
for data in tags_list[tag]:
jid = data['jid']
dict_ = {'jid': jid, 'tag': tag}
if data.has_key('priority'):
dict_['priority'] = data['priority']
iq3.addChild(name = 'meta', attrs = dict_)
self.connection.send(iq)
def send_agent_status(self, agent, ptype):

View File

@ -1061,20 +1061,23 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco)
self.bookmarks.append(bm)
self.dispatch('BOOKMARKS', self.bookmarks)
gajim_tag = query.getTag('gajim')
if gajim_tag:
ns = gajim_tag.getNamespace()
if ns == 'gajim:metacontacts':
# Meta contacts list
children_list = {}
for child in gajim_tag.getChildren():
parent_jid = child.getAttr('name')
if not parent_jid:
continue
children_list[parent_jid] = []
for cchild in child.getChildren():
children_list[parent_jid].append(cchild.getAttr('name'))
self.dispatch('META_CONTACTS', children_list)
elif ns == 'storage:metacontacts':
# Metacontact tags
# http://www.jabber.org/jeps/jep-XXXX.html
meta_list = {}
metas = storage.getTags('meta')
for meta in metas:
jid = meta.getAttr('jid')
tag = meta.getAttr('tag')
data = {'jid': jid}
prio = meta.getAttr('priority')
if prio != None:
data['priority'] = prio
if meta_list.has_key(tag):
meta_list[tag].append(data)
else:
meta_list[tag] = [data]
self.dispatch('METACONTACTS', meta_list)
# We can now continue connection by requesting the roster
self.connection.initRoster()
@ -1087,14 +1090,14 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco)
def _PrivateErrorCB(self, con, iq_obj):
gajim.log.debug('PrivateErrorCB')
query = iq_obj.getTag('query')
gajim_tag = query.getTag('gajim')
if gajim_tag:
storage_tag = query.getTag('storage')
if storage_tag:
ns = gajim_tag.getNamespace()
if ns == 'gajim:metacontacts':
if ns == 'storage:metacontacts':
# Private XML Storage (JEP49) is not supported by server
# Continue connecting
self.connection.initRoster()
def _rosterSetCB(self, con, iq_obj):
gajim.log.debug('rosterSetCB')
for item in iq_obj.getTag('query').getChildren():

View File

@ -27,7 +27,7 @@ import common.gajim
class Contact:
'''Information concerning each contact'''
def __init__(self, jid='', name='', groups=[], show='', status='', sub='',
ask='', resource='', priority=5, keyID='', our_chatstate=None,
ask='', resource='', priority=0, keyID='', our_chatstate=None,
chatstate=None, last_status_time=None, msg_id = None, composing_jep = None):
self.jid = jid
self.name = name
@ -93,25 +93,21 @@ class Contacts:
self._gc_contacts = {} # list of contacts that are in gc {acct: {room_jid: {nick: C}}}
# For meta contacts:
self._children_meta_contacts = {}
self._parent_meta_contacts = {}
self._metacontacts_tags = {}
def change_account_name(self, old_name, new_name):
self._contacts[new_name] = self._contacts[old_name]
self._gc_contacts[new_name] = self._gc_contacts[old_name]
self._children_meta_contacts[new_name] = self._children_meta_contacts[old_name]
self._parent_meta_contacts[new_name] = self._parent_meta_contacts[old_name]
self._metacontacts_tags[new_name] = self._metacontacts_tags[old_name]
del self._contacts[old_name]
del self._gc_contacts[old_name]
del self._children_meta_contacts[old_name]
del self._parent_meta_contacts[old_name]
del self._metacontacts_tags[old_name]
def add_account(self, account):
self._contacts[account] = {}
self._gc_contacts[account] = {}
if not self._children_meta_contacts.has_key(account):
self._children_meta_contacts[account] = {}
self._parent_meta_contacts[account] = {}
if not self._metacontacts_tags.has_key(account):
self._metacontacts_tags[account] = {}
def get_accounts(self):
return self._contacts.keys()
@ -119,11 +115,10 @@ class Contacts:
def remove_account(self, account):
del self._contacts[account]
del self._gc_contacts[account]
del self._children_meta_contacts[account]
del self._parent_meta_contacts[account]
del self._metacontacts_tags[account]
def create_contact(self, jid='', name='', groups=[], show='', status='',
sub='', ask='', resource='', priority=5, keyID='', our_chatstate=None,
sub='', ask='', resource='', priority=0, keyID='', our_chatstate=None,
chatstate=None, last_status_time=None, composing_jep=None):
return Contact(jid, name, groups, show, status, sub, ask, resource,
priority, keyID, our_chatstate, chatstate, last_status_time,
@ -172,11 +167,8 @@ class Contacts:
if not self._contacts[account].has_key(jid):
return
del self._contacts[account][jid]
if self._parent_meta_contacts[account].has_key(jid):
self.remove_subcontact(account, jid)
if self._children_meta_contacts[account].has_key(jid):
for cjid in self._children_meta_contacts[account][jid]:
self.remove_subcontact(account, cjid)
# remove metacontacts info
self.remove_metacontact(account, jid)
def get_contact(self, account, jid, resource = None):
'''Returns the list of contact instances for this jid (one per resource)
@ -222,77 +214,120 @@ class Contacts:
return self._contacts[account][jid][0]
return None
def define_meta_contacts(self, account, children_list):
self._parent_meta_contacts[account] = {}
for parent_jid in children_list:
list = self._children_meta_contacts[account][parent_jid] = []
for children_jid in children_list[parent_jid]:
if not children_jid in list:
list.append(children_jid)
self._parent_meta_contacts[account][children_jid] = parent_jid
def add_subcontact(self, account, parent_jid, child_jid):
self._parent_meta_contacts[account][child_jid] = parent_jid
if self._children_meta_contacts[account].has_key(parent_jid):
list = self._children_meta_contacts[account][parent_jid]
if not child_jid in list:
list.append(child_jid)
def define_metacontacts(self, account, tags_list):
self._metacontacts_tags[account] = tags_list
def get_new_metacontacts_tag(self, jid):
if not jid in self._metacontacts_tags.keys():
return jid
#FIXME: can this append ?
assert False
def get_metacontacts_tag(self, account, jid):
'''Returns the tag of a jid'''
if not self._metacontacts_tags.has_key(account):
return None
for tag in self._metacontacts_tags[account]:
for data in self._metacontacts_tags[account][tag]:
if data['jid'] == jid:
return tag
return None
def add_metacontact(self, brother_account, brother_jid, account, jid):
tag = self.get_metacontacts_tag(brother_account, brother_jid)
if not tag:
tag = self.get_new_metacontacts_tag(brother_jid)
self._metacontacts_tags[brother_account][tag] = [{'jid': brother_jid,
'tag': tag}]
common.gajim.connections[brother_account].store_metacontacts(
self._metacontacts_tags[brother_account])
# be sure jid has no other tag
old_tag = self.get_metacontacts_tag(account, jid)
while old_tag:
self.remove_metacontact(account, jid)
old_tag = self.get_metacontacts_tag(account, jid)
if not self._metacontacts_tags[account].has_key(tag):
self._metacontacts_tags[account][tag] = [{'jid': jid, 'tag': tag}]
else:
self._children_meta_contacts[account][parent_jid] = [child_jid]
common.gajim.connections[account].store_meta_contacts(
self._children_meta_contacts[account])
self._metacontacts_tags[account][tag].append({'jid': jid,
'tag': tag})
common.gajim.connections[account].store_metacontacts(
self._metacontacts_tags[account])
def remove_subcontact(self, account, child_jid):
parent_jid = self._parent_meta_contacts[account][child_jid]
self._children_meta_contacts[account][parent_jid].remove(child_jid)
if len(self._children_meta_contacts[account][parent_jid]) == 0:
del self._children_meta_contacts[account][parent_jid]
del self._parent_meta_contacts[account][child_jid]
common.gajim.connections[account].store_meta_contacts(
self._children_meta_contacts[account])
def remove_metacontact(self, account, jid):
found = None
for tag in self._metacontacts_tags[account]:
for data in self._metacontacts_tags[account][tag]:
if data['jid'] == jid:
found = data
break
if found:
self._metacontacts_tags[account][tag].remove(data)
break
common.gajim.connections[account].store_metacontacts(
self._metacontacts_tags[account])
def is_subcontact(self, account, contact):
jid = contact.jid
if jid in self._parent_meta_contacts[account] and \
self._contacts[account].has_key(
self._parent_meta_contacts[account][jid]):
return True
def has_brother(self, account, jid):
for account in self._metacontacts_tags:
tag = self.get_metacontacts_tag(account, jid)
if tag and len(self._metacontacts_tags[account][tag]) > 1:
return True
return False
def has_children(self, account, contact):
jid = contact.jid
if jid in self._children_meta_contacts[account]:
for c in self._children_meta_contacts[account][jid]:
if self._contacts[account].has_key(c):
return True
def get_metacontacts_jids(self, tag):
'''Returns all jid for the given tag in the form {acct: [jid1, jid2],.}'''
answers = {}
for account in self._metacontacts_tags:
if self._metacontacts_tags[account].has_key(tag):
answers[account] = []
for data in self._metacontacts_tags[account][tag]:
answers[account].append(data['jid'])
return answers
def get_children_contacts(self, account, contact):
'''Returns the children contacts of contact if it's a parent-contact,
else []'''
jid = contact.jid
if jid not in self._children_meta_contacts[account]:
def get_metacontacts_family(self, account, jid):
'''return the family of the given jid, including jid in the form:
[{'account': acct, 'jid': jid, 'priority': prio}, ]
'priority' is optional'''
tag = self.get_metacontacts_tag(account, jid)
if not tag:
return []
contacts = []
for j in self._children_meta_contacts[account][jid]:
c = self.get_contact_with_highest_priority(account, j)
if c:
contacts.append(c)
return contacts
answers = []
for account in self._metacontacts_tags:
if self._metacontacts_tags[account].has_key(tag):
for data in self._metacontacts_tags[account][tag]:
data['account'] = account
answers.append(data)
return answers
def get_parent_contact(self, account, contact):
'''Returns the parent contact of contact if it's a sub-contact,
else contact'''
if self.is_subcontact(account, contact):
parent_jid = self._parent_meta_contacts[account][contact.jid]
return self.get_contact_with_highest_priority(account, parent_jid)
return contact
def _get_data_score(self, data):
'''compute thescore of a gived data
data is {'jid': jid, 'account': account, 'priority': priority}
priority is optional
score = meta_priority*10000 + is_jabber*priority*10 + status'''
jid = data['jid']
account = data['account']
priority = 0
if data.has_key('priority'):
priority = data['priority']
contact = self.get_contact_with_highest_priority(account, jid)
score = priority*10000
if not common.gajim.jid_is_transport(jid):
score += contact.priority*10
score += ['offline', 'invisible', 'dnd', 'xa', 'away', 'chat',
'online'].index(contact.show)
return score
def get_master_contact(self, account, contact):
'''Returns the master contact of contact (parent of parent...) if it's a
sub-contact, else contact'''
while self.is_subcontact(account, contact):
parent_jid = self._parent_meta_contacts[account][contact.jid]
contact = self.get_contact_with_highest_priority(account, parent_jid)
return contact
def get_metacontacts_big_brother(self, family):
'''which of the family will be the big brother under wich all
others will be ?'''
max_score = 0
max_data = family[0]
for data in family:
score = self._get_data_score(data)
if score > max_score:
max_score = score
max_data = data
return max_data
def is_pm_from_jid(self, account, jid):
'''Returns True if the given jid is a private message jid'''

View File

@ -1244,8 +1244,8 @@ class Interface:
password = gajim.gc_passwords[room_jid]
gajim.connections[account].join_gc(nick, room, server, password)
def handle_event_meta_contacts(self, account, children_list):
gajim.contacts.define_meta_contacts(account, children_list)
def handle_event_metacontacts(self, account, tags_list):
gajim.contacts.define_metacontacts(account, tags_list)
def read_sleepy(self):
'''Check idle status and change that status if needed'''
@ -1505,7 +1505,7 @@ class Interface:
'VCARD_NOT_PUBLISHED': self.handle_event_vcard_not_published,
'ASK_NEW_NICK': self.handle_event_ask_new_nick,
'SIGNED_IN': self.handle_event_signed_in,
'META_CONTACTS': self.handle_event_meta_contacts,
'METACONTACTS': self.handle_event_metacontacts,
}
gajim.handlers = self.handlers

View File

@ -169,49 +169,24 @@ class RosterWindow:
gajim.newly_added[account].remove(jid)
self.draw_contact(jid, account)
def add_contact_to_roster(self, jid, account, force = False,
add_children = False):
def add_contact_to_roster(self, jid, account):
'''Add a contact to the roster and add groups if they aren't in roster
force is about force to add it, even if it is offline and show offline
is False, because it has online children, so we need to show it.
If add_children is True, we also add all children, even if they were not
already drawn'''
showOffline = gajim.config.get('showoffline')
model = self.tree.get_model()
contact = gajim.contacts.get_first_contact_from_jid(account, jid)
if not contact:
return
# If contact already in roster, do not add it
if len(self.get_contact_iter(contact.jid, account)):
if len(self.get_contact_iter(jid, account)):
return
if contact.jid.find('@') <= 0:
# if not '@' or '@' starts the jid ==> agent
contact.groups = [_('Transports')]
model = self.tree.get_model()
if gajim.contacts.is_subcontact(account, contact):
if contact.show in ('offline', 'error') and \
not showOffline and not gajim.awaiting_events[account].has_key(jid):
return
parent_contact = gajim.contacts.get_parent_contact(account, contact)
# is parent shown ?
parent_iters = self.get_contact_iter(parent_contact.jid, account)
if not len(parent_iters):
# Add parent and children
self.add_contact_to_roster(parent_contact.jid, account, True)
parent_iters = self.get_contact_iter(parent_contact.jid, account)
name = contact.get_shown_name()
for i in parent_iters:
# we add some values here. see draw_contact for more
model.append(i, (None, name, 'contact', contact.jid, account,
False, None))
if add_children:
for cc in gajim.contacts.get_children_contacts(account, contact):
self.add_contact_to_roster(cc.jid, account)
self.draw_contact(contact.jid, account)
self.draw_avatar(contact.jid, account)
# Redraw parent to change icon
self.draw_contact(parent_contact.jid, account)
return
# JEP-0162
hide = True
if contact.sub in ('both', 'to'):
@ -228,21 +203,61 @@ class RosterWindow:
else:
return
if observer:
# if he has a tag, remove it
tag = gajim.contacts.get_metacontacts_tag(account, jid)
if tag:
gajim.contacts.remove_metacontact(account, jid)
# family is [{'account': acct, 'jid': jid, 'priority': prio}, ]
# 'priority' is optional
family = gajim.contacts.get_metacontacts_family(account, jid)
shown_family = [] # family members that are in roster.
if family:
for data in family:
_jid = data['jid']
_account = data['account']
if self.get_contact_iter(_jid, _account):
shown_family.append(data)
if _jid == jid:
our_data = data
shown_family.append(our_data)
big_brother_data = gajim.contacts.get_metacontacts_big_brother(
shown_family)
big_brother_jid = big_brother_data['jid']
big_brother_account = big_brother_data['account']
if big_brother_jid != jid:
# We are adding a child contact
if contact.show in ('offline', 'error') and \
not showOffline and not gajim.awaiting_events[account].has_key(jid):
return
parent_iters = self.get_contact_iter(big_brother_jid,
big_brother_account)
name = contact.get_shown_name()
for i in parent_iters:
# we add some values here. see draw_contact for more
model.append(i, (None, name, 'contact', jid, account,
False, None))
self.draw_contact(jid, account)
self.draw_avatar(jid, account)
# Redraw parent to change icon
self.draw_contact(big_brother_jid, big_brother_account)
return
if (contact.show in ('offline', 'error') or hide) and \
not showOffline and (not _('Transports') in contact.groups or \
gajim.connections[account].connected < 2) and \
not gajim.awaiting_events[account].has_key(jid) and not force:
not gajim.awaiting_events[account].has_key(jid):
return
# Remove child contacts that are already in roster to add them
# Remove brother contacts that are already in roster to add them
# under this iter
children_contacts = gajim.contacts.get_children_contacts(account,
contact)
ccs = [] # children contacts that were relly in roster
for cc in children_contacts:
if self.get_contact_iter(cc.jid, account) or add_children:
self.remove_contact(cc, account)
ccs.append(cc)
for data in shown_family:
contacts = gajim.contacts.get_contact(data['account'],
data['jid'])
for c in contacts:
self.remove_contact(c, data['account'])
groups = contact.groups
if observer:
groups = [_('Observers')]
@ -256,7 +271,7 @@ class RosterWindow:
self.jabber_state_images['16']['closed'],
gtkgui_helpers.escape_for_pango_markup(g), 'group', g, account,
False, None])
if not gajim.groups[account].has_key(g): #It can probably never append
if not gajim.groups[account].has_key(g): # It can probably never append
if account + g in self.collapsed_rows:
ishidden = False
else:
@ -279,8 +294,10 @@ class RosterWindow:
self.draw_contact(jid, account)
self.draw_avatar(jid, account)
# put the children under this iter
for cc in ccs:
self.add_contact_to_roster(cc.jid, account)
for data in shown_family:
contacts = gajim.contacts.get_contact(data['account'],
data['jid'])
self.add_contact_to_roster(data['jid'], data['account'])
def add_transport_to_roster(self, account, transport):
c = gajim.contacts.create_contact(jid = transport, name = transport,
@ -292,20 +309,11 @@ class RosterWindow:
def really_remove_contact(self, contact, account):
if contact.jid in gajim.newly_added[account]:
return
if contact.jid.find('@') < 1 and gajim.connections[account].connected > 1: # It's an agent
if contact.jid.find('@') < 1 and gajim.connections[account].connected > 1:
# It's an agent
return
if contact.jid in gajim.to_be_removed[account]:
gajim.to_be_removed[account].remove(contact.jid)
has_connected_children = False
children_contacts = gajim.contacts.get_children_contacts(account,
contact)
for cc in children_contacts:
if cc.show not in ('offline', 'error'):
has_connected_children = True
break
if gajim.config.get('showoffline') or has_connected_children:
self.draw_contact(contact.jid, account)
return
self.remove_contact(contact, account)
def remove_contact(self, contact, account):
@ -313,36 +321,45 @@ class RosterWindow:
if contact.jid in gajim.to_be_removed[account]:
return
model = self.tree.get_model()
for i in self.get_contact_iter(contact.jid, account):
iters = self.get_contact_iter(contact.jid, account)
if not iters:
return
parent_iter = model.iter_parent(iters[0])
parent_type = model[parent_iter][C_TYPE]
# remember children to re-add them
children = []
child_iter = model.iter_children(iters[0])
while child_iter:
c_jid = model[child_iter][C_JID].decode('utf-8')
c_account = model[child_iter][C_ACCOUNT].decode('utf-8')
children.append((c_jid, c_account))
child_iter = model.iter_next(child_iter)
# Remove iters and group iter if they are empty
for i in iters:
parent_i = model.iter_parent(i)
model.remove(i)
if gajim.contacts.is_subcontact(account, contact):
# Is it the last subcontact with offline parent?
parent_contact = gajim.contacts.get_parent_contact(account, contact)
if parent_contact.show in ('offline', 'error'):
has_another_child = False
children_contacts = gajim.contacts.get_children_contacts(account,
contact)
for cc in children_contacts:
if len(self.get_contact_iter(cc.jid, account)):
has_another_child = True
if parent_type == 'group':
group = model[parent_i][C_JID].decode('utf-8')
if model.iter_n_children(parent_i) == 0:
model.remove(parent_i)
# We need to check all contacts, even offline contacts
for jid in gajim.contacts.get_jid_list(account):
if group in gajim.contacts.get_contact_with_highest_priority(
account, jid).groups:
break
if not has_another_child:
# Remove parent contact
self.remove_contact(parent_contact, account)
self.draw_contact(parent_contact.jid, account)
return
group = model[parent_i][C_JID].decode('utf-8')
if model.iter_n_children(parent_i) == 0:
model.remove(parent_i)
# We need to check all contacts, even offline contacts
for jid in gajim.contacts.get_jid_list(account):
if group in gajim.contacts.get_contact_with_highest_priority(
account, jid).groups:
break
else:
if gajim.groups[account].has_key(group):
del gajim.groups[account][group]
else:
if gajim.groups[account].has_key(group):
del gajim.groups[account][group]
# re-add children
for child in children:
self.add_contact_to_roster(child[0], child[1])
# redraw parent
if parent_type == 'contact':
parent_jid = model[parent_iter][C_JID].decode('utf-8')
parent_account = model[parent_iter][C_ACCOUNT].decode('utf-8')
self.draw_contact(parent_jid, parent_account)
def get_appropriate_state_images(self, jid, size = '16',
icon_name = 'online'):
@ -431,9 +448,7 @@ class RosterWindow:
size = 'closed', icon_name = icon_name)
else:
# redraw parent
if gajim.contacts.is_subcontact(account, contact):
parent_jid = gajim.contacts.get_parent_contact(account, contact).jid
self.draw_contact(parent_jid, account)
self.draw_parent_contact(jid, account)
state_images = self.get_appropriate_state_images(jid,
icon_name = icon_name)
@ -443,6 +458,18 @@ class RosterWindow:
model[iter][C_IMG] = img
model[iter][C_NAME] = name
def draw_parent_contact(self, jid, account):
model = self.tree.get_model()
iters = self.get_contact_iter(jid, account)
if not len(iters):
return
parent_iter = model.iter_parent(iters[0])
if model[parent_iter][C_TYPE] != 'contact':
# parent is not a contact
return
parent_jid = model[parent_iter][C_JID].decode('utf-8')
self.draw_contact(parent_jid, account)
def draw_avatar(self, jid, account):
'''draw the avatar'''
model = self.tree.get_model()
@ -884,16 +911,8 @@ class RosterWindow:
if len(contact_instances) > 1:
# if multiple resources
gajim.contacts.remove_contact(account, contact)
self.draw_contact(contact.jid, account)
elif not showOffline:
# we don't show offline contacts
self.remove_contact(contact, account)
else:
self.draw_contact(contact.jid, account)
else:
if not self.get_contact_iter(contact.jid, account):
self.add_contact_to_roster(contact.jid, account)
self.draw_contact(contact.jid, account)
self.remove_contact(contact, account)
self.add_contact_to_roster(contact.jid, account)
# print status in chat window and update status/GPG image
for j in (contact.jid, contact.get_full_jid()):
if gajim.interface.msg_win_mgr.has_window(j, account):
@ -1599,7 +1618,6 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
iter = model.get_iter(path)
type = model[iter][C_TYPE]
if type in ('agent', 'contact'):
#TODO
account = model[iter][C_ACCOUNT].decode('utf-8')
jid = model[iter][C_JID].decode('utf-8')
win = None
@ -1665,11 +1683,7 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
gajim.connections[account].unsubscribe(contact.jid, remove_auth)
for u in gajim.contacts.get_contact(account, contact.jid):
self.remove_contact(u, account)
ccs = gajim.contacts.get_children_contacts(account, contact)
gajim.contacts.remove_jid(account, u.jid)
for cc in ccs:
cc.groups = contact.groups
self.add_contact_to_roster(cc.jid, account)
if not remove_auth:
contact.name = ''
contact.groups = []
@ -2065,10 +2079,7 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
if no_queue: # We didn't have a queue: we change icons
self.draw_contact(jid, account)
# Redraw parent too
if gajim.contacts.is_subcontact(account, contact):
parent_contact = gajim.contacts.get_parent_contact(account,
contact)
self.draw_contact(parent_contact.jid, account)
self.draw_parent_contact(jid, account)
if gajim.interface.systray_enabled:
gajim.interface.systray.add_jid(jid, account, kind)
self.show_title() # we show the * or [n]
@ -2774,8 +2785,7 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
# We first compare by show if sort_by_show is True or if it's a child
# contact
if type1 == 'contact' and type2 == 'contact' and \
(gajim.config.get('sort_by_show') or gajim.contacts.is_subcontact(
account1, contact1)):
gajim.config.get('sort_by_show'):
cshow = {'online':0, 'chat': 1, 'away': 2, 'xa': 3, 'dnd': 4,
'invisible': 5, 'offline': 6, 'not in roster': 7, 'error': 8}
s = self.get_show(lcontact1)
@ -2823,25 +2833,12 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
etime):
# remove the source row
model = self.tree.get_model()
for iter in self.get_contact_iter(c_source.jid, account):
# get group iter
iter_group = iter
while model[iter_group][C_TYPE] == 'contact':
iter_group = model.iter_parent(iter_group)
group = model[iter_group][C_JID].decode('utf-8')
model.remove(iter)
if model.iter_n_children(iter_group) == 0:
# this was the only child
model.remove(iter_group)
# delete the group if it is empty (need to look for offline users
# too)
for jid in gajim.contacts.get_jid_list(account):
if group in gajim.contacts.get_contact_with_highest_priority(
account, jid).groups:
break
else:
del gajim.groups[account][group]
gajim.contacts.add_subcontact(account, c_dest.jid, c_source.jid)
self.remove_contact(c_source, account)
# brother inherite big brother groups
c_source.groups = []
for g in c_dest.groups:
c_source.groups.append(g)
gajim.contacts.add_metacontact(account, c_dest.jid, account, c_source.jid)
# Add it under parent contact
self.add_contact_to_roster(c_source.jid, account)
self.draw_contact(c_dest.jid, account)
@ -2851,6 +2848,8 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
etime, grp_source = None):
if grp_source:
self.remove_contact_from_group(account, c_source, grp_source)
# remove tag
gajim.contacts.remove_metacontact(account, c_source.jid)
self.add_contact_to_group(account, c_source, grp_dest)
if context.action in (gtk.gdk.ACTION_MOVE, gtk.gdk.ACTION_COPY):
context.finish(True, True, etime)
@ -2873,17 +2872,7 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
model = self.tree.get_model()
# Make sure contact was in the group
contact.groups.remove(group)
group_iter = self.get_group_iter(group, account)
if model.iter_n_children(group_iter) == 1:
# this was the only child
model.remove(group_iter)
# delete the group if it is empty (need to look for offline users too)
for jid in gajim.contacts.get_jid_list(account):
if group in gajim.contacts.get_contact_with_highest_priority(
account, jid).groups:
break
else:
del gajim.groups[account][group]
self.remove_contact(contact, account)
def drag_data_received_data(self, treeview, context, x, y, selection, info,
etime):
@ -2919,6 +2908,7 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
gajim.interface.instances['file_transfers'].send_file(account,
c_dest, path)
return
if position == gtk.TREE_VIEW_DROP_BEFORE and len(path_dest) == 2:
# dropped before a group : we drop it in the previous group
path_dest = (path_dest[0], path_dest[1]-1)
@ -2949,14 +2939,13 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
grp_dest = model[iter_dest][C_JID].decode('utf-8')
if grp_dest == _('Transports') or grp_dest == _('Not in Roster'):
return
if not gajim.contacts.is_subcontact(account, c_source):
if context.action == gtk.gdk.ACTION_COPY:
self.on_drop_in_group(None, account, c_source, grp_dest, context,
etime)
return
if context.action == gtk.gdk.ACTION_COPY:
self.on_drop_in_group(None, account, c_source, grp_dest, context,
etime, grp_source)
etime)
return
self.on_drop_in_group(None, account, c_source, grp_dest, context,
etime, grp_source)
return
else:
it = iter_dest
while model[it][C_TYPE] != 'group':
@ -2975,20 +2964,6 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
self.on_drop_in_group(None, account, c_source, grp_dest, context,
etime, grp_source)
return
if gajim.contacts.is_subcontact(account, c_source):
# Remove meta contact
#FIXME: doesn't work under windows: http://bugzilla.gnome.org/show_bug.cgi?id=329797
# if context.action == gtk.gdk.ACTION_COPY:
# return
c_source.groups = [grp_dest]
gajim.connections[account].update_contact(jid_source, c_source.name,
c_source.groups)
parent_jid = gajim.contacts.get_parent_contact(account, c_source).jid
gajim.contacts.remove_subcontact(account, jid_source)
context.finish(True, True, etime)
self.add_contact_to_roster(jid_source, account, add_children = True)
self.draw_contact(parent_jid, account)
return
if grp_source == grp_dest:
# Add meta contact
#FIXME: doesn't work under windows: http://bugzilla.gnome.org/show_bug.cgi?id=329797
@ -2997,15 +2972,15 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
# return
c_dest = gajim.contacts.get_contact_with_highest_priority(account,
jid_dest)
# are we creating a loop (child is parent and parent is child)?
if gajim.contacts.is_subcontact(account, c_dest) and \
gajim.contacts.get_parent_contact(account, c_dest).jid == jid_source:
return
gajim.contacts.add_subcontact(account, jid_dest, jid_source)
# brother inherite big brother groups
c_source.groups = []
for g in c_dest.groups:
c_source.groups.append(g)
gajim.contacts.add_metacontact(account, jid_dest, account, jid_source)
# remove the source row
context.finish(True, True, etime)
# Add it under parent contact
self.add_contact_to_roster(jid_source, account, add_children = True)
self.add_contact_to_roster(jid_source, account)
self.draw_contact(jid_dest, account)
return
# We upgrade only the first user because user2.groups is a pointer to
@ -3022,7 +2997,7 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
menu.append(item)
c_dest = gajim.contacts.get_contact_with_highest_priority(account,
jid_dest)
item = gtk.MenuItem(_('Make %s as subcontact of %s') % (c_source.name,
item = gtk.MenuItem(_('Make %s and %s metacontacts') % (c_source.name,
c_dest.name))
item.connect('activate', self.on_drop_in_contact, account, c_source,
c_dest, context, etime)
@ -3077,14 +3052,13 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
if selected_iter is None:
self._last_selected_contact = None
return
contact = model[selected_iter]
self._last_selected_contact = (contact[C_JID].decode('utf-8'),
contact[C_ACCOUNT].decode('utf-8'))
# FIXME: we first set last selected contact and then test if contact??
if contact[C_TYPE] != 'contact':
contact_row = model[selected_iter]
if contact_row[C_TYPE] != 'contact':
return
self.draw_contact(contact[C_JID].decode('utf-8'),
contact[C_ACCOUNT].decode('utf-8'), selected = True)
jid = contact_row[C_JID].decode('utf-8')
account = contact_row[C_ACCOUNT].decode('utf-8')
self._last_selected_contact = (jid, account)
self.draw_contact(jid, account, selected = True)
def __init__(self):
self.xml = gtk.glade.XML(GTKGUI_GLADE, 'roster_window', APP)