| 1 | # -*- coding:utf-8 -*- |
|---|
| 2 | ## src/vcard.py |
|---|
| 3 | ## |
|---|
| 4 | ## Copyright (C) 2003-2008 Yann Leboulanger <asterix AT lagaule.org> |
|---|
| 5 | ## Copyright (C) 2005 Vincent Hanquez <tab AT snarc.org> |
|---|
| 6 | ## Copyright (C) 2005-2006 Nikos Kouremenos <kourem AT gmail.com> |
|---|
| 7 | ## Copyright (C) 2006 Junglecow J <junglecow AT gmail.com> |
|---|
| 8 | ## Dimitur Kirov <dkirov AT gmail.com> |
|---|
| 9 | ## Travis Shirk <travis AT pobox.com> |
|---|
| 10 | ## Stefan Bethge <stefan AT lanpartei.de> |
|---|
| 11 | ## Copyright (C) 2006-2008 Jean-Marie Traissard <jim AT lapin.org> |
|---|
| 12 | ## Copyright (C) 2007 Lukas Petrovicky <lukas AT petrovicky.net> |
|---|
| 13 | ## Copyright (C) 2008 Brendan Taylor <whateley AT gmail.com> |
|---|
| 14 | ## Jonathan Schleifer <js-gajim AT webkeks.org> |
|---|
| 15 | ## Stephan Erb <steve-e AT h3c.de> |
|---|
| 16 | ## |
|---|
| 17 | ## This file is part of Gajim. |
|---|
| 18 | ## |
|---|
| 19 | ## Gajim is free software; you can redistribute it and/or modify |
|---|
| 20 | ## it under the terms of the GNU General Public License as published |
|---|
| 21 | ## by the Free Software Foundation; version 3 only. |
|---|
| 22 | ## |
|---|
| 23 | ## Gajim is distributed in the hope that it will be useful, |
|---|
| 24 | ## but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 25 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 26 | ## GNU General Public License for more details. |
|---|
| 27 | ## |
|---|
| 28 | ## You should have received a copy of the GNU General Public License |
|---|
| 29 | ## along with Gajim. If not, see <http://www.gnu.org/licenses/>. |
|---|
| 30 | ## |
|---|
| 31 | |
|---|
| 32 | # THIS FILE IS FOR **OTHERS'** PROFILE (when we VIEW their INFO) |
|---|
| 33 | |
|---|
| 34 | import gtk |
|---|
| 35 | import gobject |
|---|
| 36 | import base64 |
|---|
| 37 | import time |
|---|
| 38 | import locale |
|---|
| 39 | import os |
|---|
| 40 | |
|---|
| 41 | import gtkgui_helpers |
|---|
| 42 | |
|---|
| 43 | from common import helpers |
|---|
| 44 | from common import gajim |
|---|
| 45 | from common.i18n import Q_ |
|---|
| 46 | |
|---|
| 47 | def get_avatar_pixbuf_encoded_mime(photo): |
|---|
| 48 | '''return the pixbuf of the image |
|---|
| 49 | photo is a dictionary containing PHOTO information''' |
|---|
| 50 | if not isinstance(photo, dict): |
|---|
| 51 | return None, None, None |
|---|
| 52 | img_decoded = None |
|---|
| 53 | avatar_encoded = None |
|---|
| 54 | avatar_mime_type = None |
|---|
| 55 | if 'BINVAL' in photo: |
|---|
| 56 | img_encoded = photo['BINVAL'] |
|---|
| 57 | avatar_encoded = img_encoded |
|---|
| 58 | try: |
|---|
| 59 | img_decoded = base64.decodestring(img_encoded) |
|---|
| 60 | except Exception: |
|---|
| 61 | pass |
|---|
| 62 | if img_decoded: |
|---|
| 63 | if 'TYPE' in photo: |
|---|
| 64 | avatar_mime_type = photo['TYPE'] |
|---|
| 65 | pixbuf = gtkgui_helpers.get_pixbuf_from_data(img_decoded) |
|---|
| 66 | else: |
|---|
| 67 | pixbuf, avatar_mime_type = gtkgui_helpers.get_pixbuf_from_data( |
|---|
| 68 | img_decoded, want_type=True) |
|---|
| 69 | else: |
|---|
| 70 | pixbuf = None |
|---|
| 71 | return pixbuf, avatar_encoded, avatar_mime_type |
|---|
| 72 | |
|---|
| 73 | class VcardWindow: |
|---|
| 74 | '''Class for contact's information window''' |
|---|
| 75 | |
|---|
| 76 | def __init__(self, contact, account, gc_contact = None): |
|---|
| 77 | # the contact variable is the jid if vcard is true |
|---|
| 78 | self.xml = gtkgui_helpers.get_glade('vcard_information_window.glade') |
|---|
| 79 | self.window = self.xml.get_widget('vcard_information_window') |
|---|
| 80 | self.progressbar = self.xml.get_widget('progressbar') |
|---|
| 81 | |
|---|
| 82 | self.contact = contact |
|---|
| 83 | self.account = account |
|---|
| 84 | self.gc_contact = gc_contact |
|---|
| 85 | |
|---|
| 86 | # Get real jid |
|---|
| 87 | if gc_contact: |
|---|
| 88 | # Don't use real jid if room is (semi-)anonymous |
|---|
| 89 | gc_control = gajim.interface.msg_win_mgr.get_gc_control( |
|---|
| 90 | gc_contact.room_jid, account) |
|---|
| 91 | if gc_contact.jid and not gc_control.is_anonymous: |
|---|
| 92 | self.real_jid = gc_contact.jid |
|---|
| 93 | if gc_contact.resource: |
|---|
| 94 | self.real_jid += '/' + gc_contact.resource |
|---|
| 95 | else: |
|---|
| 96 | self.real_jid = gc_contact.get_full_jid() |
|---|
| 97 | else: |
|---|
| 98 | self.real_jid = contact.get_full_jid() |
|---|
| 99 | |
|---|
| 100 | puny_jid = helpers.sanitize_filename(contact.jid) |
|---|
| 101 | local_avatar_basepath = os.path.join(gajim.AVATAR_PATH, puny_jid) + \ |
|---|
| 102 | '_local' |
|---|
| 103 | for extension in ('.png', '.jpeg'): |
|---|
| 104 | local_avatar_path = local_avatar_basepath + extension |
|---|
| 105 | if os.path.isfile(local_avatar_path): |
|---|
| 106 | image = self.xml.get_widget('custom_avatar_image') |
|---|
| 107 | image.set_from_file(local_avatar_path) |
|---|
| 108 | image.show() |
|---|
| 109 | self.xml.get_widget('custom_avatar_label').show() |
|---|
| 110 | break |
|---|
| 111 | self.avatar_mime_type = None |
|---|
| 112 | self.avatar_encoded = None |
|---|
| 113 | self.vcard_arrived = False |
|---|
| 114 | self.os_info_arrived = False |
|---|
| 115 | self.update_progressbar_timeout_id = gobject.timeout_add(100, |
|---|
| 116 | self.update_progressbar) |
|---|
| 117 | |
|---|
| 118 | self.fill_jabber_page() |
|---|
| 119 | annotations = gajim.connections[self.account].annotations |
|---|
| 120 | if self.contact.jid in annotations: |
|---|
| 121 | buffer = self.xml.get_widget('textview_annotation').get_buffer() |
|---|
| 122 | buffer.set_text(annotations[self.contact.jid]) |
|---|
| 123 | |
|---|
| 124 | self.xml.signal_autoconnect(self) |
|---|
| 125 | self.window.show_all() |
|---|
| 126 | self.xml.get_widget('close_button').grab_focus() |
|---|
| 127 | |
|---|
| 128 | def update_progressbar(self): |
|---|
| 129 | self.progressbar.pulse() |
|---|
| 130 | return True # loop forever |
|---|
| 131 | |
|---|
| 132 | def on_vcard_information_window_destroy(self, widget): |
|---|
| 133 | if self.update_progressbar_timeout_id is not None: |
|---|
| 134 | gobject.source_remove(self.update_progressbar_timeout_id) |
|---|
| 135 | del gajim.interface.instances[self.account]['infos'][self.contact.jid] |
|---|
| 136 | buffer = self.xml.get_widget('textview_annotation').get_buffer() |
|---|
| 137 | annotation = buffer.get_text(buffer.get_start_iter(), |
|---|
| 138 | buffer.get_end_iter()) |
|---|
| 139 | connection = gajim.connections[self.account] |
|---|
| 140 | if annotation != connection.annotations.get(self.contact.jid, ''): |
|---|
| 141 | connection.annotations[self.contact.jid] = annotation |
|---|
| 142 | connection.store_annotations() |
|---|
| 143 | |
|---|
| 144 | def on_vcard_information_window_key_press_event(self, widget, event): |
|---|
| 145 | if event.keyval == gtk.keysyms.Escape: |
|---|
| 146 | self.window.destroy() |
|---|
| 147 | |
|---|
| 148 | def on_PHOTO_eventbox_button_press_event(self, widget, event): |
|---|
| 149 | '''If right-clicked, show popup''' |
|---|
| 150 | if event.button == 3: # right click |
|---|
| 151 | menu = gtk.Menu() |
|---|
| 152 | menuitem = gtk.ImageMenuItem(gtk.STOCK_SAVE_AS) |
|---|
| 153 | menuitem.connect('activate', |
|---|
| 154 | gtkgui_helpers.on_avatar_save_as_menuitem_activate, |
|---|
| 155 | self.contact.jid, self.account, self.contact.get_shown_name() + |
|---|
| 156 | '.jpeg') |
|---|
| 157 | menu.append(menuitem) |
|---|
| 158 | menu.connect('selection-done', lambda w:w.destroy()) |
|---|
| 159 | # show the menu |
|---|
| 160 | menu.show_all() |
|---|
| 161 | menu.popup(None, None, None, event.button, event.time) |
|---|
| 162 | |
|---|
| 163 | def set_value(self, entry_name, value): |
|---|
| 164 | try: |
|---|
| 165 | if value and entry_name == 'URL_label': |
|---|
| 166 | if gtk.pygtk_version >= (2, 10, 0) and gtk.gtk_version >= (2, 10, 0): |
|---|
| 167 | widget = gtk.LinkButton(value, value) |
|---|
| 168 | widget.set_alignment(0, 0) |
|---|
| 169 | else: |
|---|
| 170 | widget = gtk.Label(value) |
|---|
| 171 | widget.set_alignment(0, 0) |
|---|
| 172 | widget.set_selectable(True) |
|---|
| 173 | widget.show() |
|---|
| 174 | table = self.xml.get_widget('personal_info_table') |
|---|
| 175 | table.attach(widget, 1, 4, 3, 4, yoptions = 0) |
|---|
| 176 | else: |
|---|
| 177 | self.xml.get_widget(entry_name).set_text(value) |
|---|
| 178 | except AttributeError: |
|---|
| 179 | pass |
|---|
| 180 | |
|---|
| 181 | def set_values(self, vcard): |
|---|
| 182 | for i in vcard.keys(): |
|---|
| 183 | if i == 'PHOTO' and self.xml.get_widget('information_notebook').\ |
|---|
| 184 | get_n_pages() > 4: |
|---|
| 185 | pixbuf, self.avatar_encoded, self.avatar_mime_type = \ |
|---|
| 186 | get_avatar_pixbuf_encoded_mime(vcard[i]) |
|---|
| 187 | image = self.xml.get_widget('PHOTO_image') |
|---|
| 188 | image.show() |
|---|
| 189 | self.xml.get_widget('user_avatar_label').show() |
|---|
| 190 | if not pixbuf: |
|---|
| 191 | image.set_from_icon_name('stock_person', |
|---|
| 192 | gtk.ICON_SIZE_DIALOG) |
|---|
| 193 | continue |
|---|
| 194 | pixbuf = gtkgui_helpers.get_scaled_pixbuf(pixbuf, 'vcard') |
|---|
| 195 | image.set_from_pixbuf(pixbuf) |
|---|
| 196 | continue |
|---|
| 197 | if i in ('ADR', 'TEL', 'EMAIL'): |
|---|
| 198 | for entry in vcard[i]: |
|---|
| 199 | add_on = '_HOME' |
|---|
| 200 | if 'WORK' in entry: |
|---|
| 201 | add_on = '_WORK' |
|---|
| 202 | for j in entry.keys(): |
|---|
| 203 | self.set_value(i + add_on + '_' + j + '_label', entry[j]) |
|---|
| 204 | if isinstance(vcard[i], dict): |
|---|
| 205 | for j in vcard[i].keys(): |
|---|
| 206 | self.set_value(i + '_' + j + '_label', vcard[i][j]) |
|---|
| 207 | else: |
|---|
| 208 | if i == 'DESC': |
|---|
| 209 | self.xml.get_widget('DESC_textview').get_buffer().set_text( |
|---|
| 210 | vcard[i], 0) |
|---|
| 211 | elif i != 'jid': # Do not override jid_label |
|---|
| 212 | self.set_value(i + '_label', vcard[i]) |
|---|
| 213 | self.vcard_arrived = True |
|---|
| 214 | self.test_remove_progressbar() |
|---|
| 215 | |
|---|
| 216 | def test_remove_progressbar(self): |
|---|
| 217 | if self.update_progressbar_timeout_id is not None and \ |
|---|
| 218 | self.vcard_arrived and self.os_info_arrived: |
|---|
| 219 | gobject.source_remove(self.update_progressbar_timeout_id) |
|---|
| 220 | self.progressbar.hide() |
|---|
| 221 | self.update_progressbar_timeout_id = None |
|---|
| 222 | |
|---|
| 223 | def set_last_status_time(self): |
|---|
| 224 | self.fill_status_label() |
|---|
| 225 | |
|---|
| 226 | def set_os_info(self, resource, client_info, os_info): |
|---|
| 227 | if self.xml.get_widget('information_notebook').get_n_pages() < 5: |
|---|
| 228 | return |
|---|
| 229 | i = 0 |
|---|
| 230 | client = '' |
|---|
| 231 | os = '' |
|---|
| 232 | while i in self.os_info: |
|---|
| 233 | if not self.os_info[i]['resource'] or \ |
|---|
| 234 | self.os_info[i]['resource'] == resource: |
|---|
| 235 | self.os_info[i]['client'] = client_info |
|---|
| 236 | self.os_info[i]['os'] = os_info |
|---|
| 237 | if i > 0: |
|---|
| 238 | client += '\n' |
|---|
| 239 | os += '\n' |
|---|
| 240 | client += self.os_info[i]['client'] |
|---|
| 241 | os += self.os_info[i]['os'] |
|---|
| 242 | i += 1 |
|---|
| 243 | |
|---|
| 244 | if client == '': |
|---|
| 245 | client = Q_('?Client:Unknown') |
|---|
| 246 | if os == '': |
|---|
| 247 | os = Q_('?OS:Unknown') |
|---|
| 248 | self.xml.get_widget('client_name_version_label').set_text(client) |
|---|
| 249 | self.xml.get_widget('os_label').set_text(os) |
|---|
| 250 | self.os_info_arrived = True |
|---|
| 251 | self.test_remove_progressbar() |
|---|
| 252 | |
|---|
| 253 | def fill_status_label(self): |
|---|
| 254 | if self.xml.get_widget('information_notebook').get_n_pages() < 5: |
|---|
| 255 | return |
|---|
| 256 | contact_list = gajim.contacts.get_contacts(self.account, self.contact.jid) |
|---|
| 257 | connected_contact_list = [] |
|---|
| 258 | for c in contact_list: |
|---|
| 259 | if c.show not in ('offline', 'error'): |
|---|
| 260 | connected_contact_list.append(c) |
|---|
| 261 | if not connected_contact_list: |
|---|
| 262 | # no connected contact, get the offline one |
|---|
| 263 | connected_contact_list = contact_list |
|---|
| 264 | # stats holds show and status message |
|---|
| 265 | stats = '' |
|---|
| 266 | if connected_contact_list: |
|---|
| 267 | # Start with self.contact, as with resources |
|---|
| 268 | stats = helpers.get_uf_show(self.contact.show) |
|---|
| 269 | if self.contact.status: |
|---|
| 270 | stats += ': ' + self.contact.status |
|---|
| 271 | if self.contact.last_status_time: |
|---|
| 272 | stats += '\n' + _('since %s') % time.strftime('%c', |
|---|
| 273 | self.contact.last_status_time).decode( |
|---|
| 274 | locale.getpreferredencoding()) |
|---|
| 275 | for c in connected_contact_list: |
|---|
| 276 | if c.resource != self.contact.resource: |
|---|
| 277 | stats += '\n' |
|---|
| 278 | stats += helpers.get_uf_show(c.show) |
|---|
| 279 | if c.status: |
|---|
| 280 | stats += ': ' + c.status |
|---|
| 281 | if c.last_status_time: |
|---|
| 282 | stats += '\n' + _('since %s') % time.strftime('%c', |
|---|
| 283 | c.last_status_time).decode(locale.getpreferredencoding()) |
|---|
| 284 | else: # Maybe gc_vcard ? |
|---|
| 285 | stats = helpers.get_uf_show(self.contact.show) |
|---|
| 286 | if self.contact.status: |
|---|
| 287 | stats += ': ' + self.contact.status |
|---|
| 288 | status_label = self.xml.get_widget('status_label') |
|---|
| 289 | status_label.set_max_width_chars(15) |
|---|
| 290 | status_label.set_text(stats) |
|---|
| 291 | |
|---|
| 292 | tip = gtk.Tooltips() |
|---|
| 293 | status_label_eventbox = self.xml.get_widget('status_label_eventbox') |
|---|
| 294 | tip.set_tip(status_label_eventbox, stats) |
|---|
| 295 | |
|---|
| 296 | def fill_jabber_page(self): |
|---|
| 297 | tooltips = gtk.Tooltips() |
|---|
| 298 | self.xml.get_widget('nickname_label').set_markup( |
|---|
| 299 | '<b><span size="x-large">' + |
|---|
| 300 | self.contact.get_shown_name() + |
|---|
| 301 | '</span></b>') |
|---|
| 302 | self.xml.get_widget('jid_label').set_text(self.contact.jid) |
|---|
| 303 | |
|---|
| 304 | subscription_label = self.xml.get_widget('subscription_label') |
|---|
| 305 | ask_label = self.xml.get_widget('ask_label') |
|---|
| 306 | if self.gc_contact: |
|---|
| 307 | self.xml.get_widget('subscription_title_label').set_markup(_("<b>Role:</b>")) |
|---|
| 308 | uf_role = helpers.get_uf_role(self.gc_contact.role) |
|---|
| 309 | subscription_label.set_text(uf_role) |
|---|
| 310 | |
|---|
| 311 | self.xml.get_widget('ask_title_label').set_markup(_("<b>Affiliation:</b>")) |
|---|
| 312 | uf_affiliation = helpers.get_uf_affiliation(self.gc_contact.affiliation) |
|---|
| 313 | ask_label.set_text(uf_affiliation) |
|---|
| 314 | else: |
|---|
| 315 | uf_sub = helpers.get_uf_sub(self.contact.sub) |
|---|
| 316 | subscription_label.set_text(uf_sub) |
|---|
| 317 | eb = self.xml.get_widget('subscription_label_eventbox') |
|---|
| 318 | if self.contact.sub == 'from': |
|---|
| 319 | tt_text = _("This contact is interested in your presence information, but you are not interested in his/her presence") |
|---|
| 320 | elif self.contact.sub == 'to': |
|---|
| 321 | tt_text = _("You are interested in the contact's presence information, but he/she is not interested in yours") |
|---|
| 322 | elif self.contact.sub == 'both': |
|---|
| 323 | tt_text = _("You and the contact are interested in each other's presence information") |
|---|
| 324 | else: # None |
|---|
| 325 | tt_text = _("You are not interested in the contact's presence, and neither he/she is interested in yours") |
|---|
| 326 | tooltips.set_tip(eb, tt_text) |
|---|
| 327 | |
|---|
| 328 | uf_ask = helpers.get_uf_ask(self.contact.ask) |
|---|
| 329 | ask_label.set_text(uf_ask) |
|---|
| 330 | eb = self.xml.get_widget('ask_label_eventbox') |
|---|
| 331 | if self.contact.ask == 'subscribe': |
|---|
| 332 | tt_text = _("You are waiting contact's answer about your subscription request") |
|---|
| 333 | else: |
|---|
| 334 | tt_text = _("There is no pending subscription request.") |
|---|
| 335 | tooltips.set_tip(eb, tt_text) |
|---|
| 336 | |
|---|
| 337 | resources = '%s (%s)' % (self.contact.resource, unicode( |
|---|
| 338 | self.contact.priority)) |
|---|
| 339 | uf_resources = self.contact.resource + _(' resource with priority ')\ |
|---|
| 340 | + unicode(self.contact.priority) |
|---|
| 341 | if not self.contact.status: |
|---|
| 342 | self.contact.status = '' |
|---|
| 343 | |
|---|
| 344 | # Request list time status only if contact is offline |
|---|
| 345 | if self.contact.show == 'offline': |
|---|
| 346 | if self.gc_contact: |
|---|
| 347 | j, r = gajim.get_room_and_nick_from_fjid(self.real_jid) |
|---|
| 348 | gajim.connections[self.account].request_last_status_time(j, r, |
|---|
| 349 | self.contact.jid) |
|---|
| 350 | else: |
|---|
| 351 | gajim.connections[self.account].request_last_status_time( |
|---|
| 352 | self.contact.jid, self.contact.resource) |
|---|
| 353 | |
|---|
| 354 | # do not wait for os_info if contact is not connected or has error |
|---|
| 355 | # additional check for observer is needed, as show is offline for him |
|---|
| 356 | if self.contact.show in ('offline', 'error')\ |
|---|
| 357 | and not self.contact.is_observer(): |
|---|
| 358 | self.os_info_arrived = True |
|---|
| 359 | else: # Request os info if contact is connected |
|---|
| 360 | if self.gc_contact: |
|---|
| 361 | j, r = gajim.get_room_and_nick_from_fjid(self.real_jid) |
|---|
| 362 | gobject.idle_add(gajim.connections[self.account].request_os_info, |
|---|
| 363 | j, r, self.contact.jid) |
|---|
| 364 | else: |
|---|
| 365 | gobject.idle_add(gajim.connections[self.account].request_os_info, |
|---|
| 366 | self.contact.jid, self.contact.resource) |
|---|
| 367 | self.os_info = {0: {'resource': self.contact.resource, 'client': '', |
|---|
| 368 | 'os': ''}} |
|---|
| 369 | i = 1 |
|---|
| 370 | contact_list = gajim.contacts.get_contacts(self.account, self.contact.jid) |
|---|
| 371 | if contact_list: |
|---|
| 372 | for c in contact_list: |
|---|
| 373 | if c.resource != self.contact.resource: |
|---|
| 374 | resources += '\n%s (%s)' % (c.resource, |
|---|
| 375 | unicode(c.priority)) |
|---|
| 376 | uf_resources += '\n' + c.resource + \ |
|---|
| 377 | _(' resource with priority ') + unicode(c.priority) |
|---|
| 378 | if c.show not in ('offline', 'error'): |
|---|
| 379 | gobject.idle_add( |
|---|
| 380 | gajim.connections[self.account].request_os_info, c.jid, |
|---|
| 381 | c.resource) |
|---|
| 382 | gajim.connections[self.account].request_last_status_time(c.jid, |
|---|
| 383 | c.resource) |
|---|
| 384 | self.os_info[i] = {'resource': c.resource, 'client': '', |
|---|
| 385 | 'os': ''} |
|---|
| 386 | i += 1 |
|---|
| 387 | self.xml.get_widget('resource_prio_label').set_text(resources) |
|---|
| 388 | resource_prio_label_eventbox = self.xml.get_widget( |
|---|
| 389 | 'resource_prio_label_eventbox') |
|---|
| 390 | tooltips.set_tip(resource_prio_label_eventbox, uf_resources) |
|---|
| 391 | |
|---|
| 392 | self.fill_status_label() |
|---|
| 393 | |
|---|
| 394 | if self.gc_contact: |
|---|
| 395 | # If we know the real jid, remove the resource from vcard request |
|---|
| 396 | if self.gc_contact.jid: |
|---|
| 397 | jid = self.gc_contact.jid |
|---|
| 398 | else: |
|---|
| 399 | jid = self.real_jid |
|---|
| 400 | gajim.connections[self.account].request_vcard(jid, |
|---|
| 401 | self.gc_contact.get_full_jid()) |
|---|
| 402 | else: |
|---|
| 403 | gajim.connections[self.account].request_vcard(self.contact.jid) |
|---|
| 404 | |
|---|
| 405 | def on_close_button_clicked(self, widget): |
|---|
| 406 | self.window.destroy() |
|---|
| 407 | |
|---|
| 408 | |
|---|
| 409 | class ZeroconfVcardWindow: |
|---|
| 410 | def __init__(self, contact, account, is_fake = False): |
|---|
| 411 | # the contact variable is the jid if vcard is true |
|---|
| 412 | self.xml = gtkgui_helpers.get_glade('zeroconf_information_window.glade') |
|---|
| 413 | self.window = self.xml.get_widget('zeroconf_information_window') |
|---|
| 414 | |
|---|
| 415 | self.contact = contact |
|---|
| 416 | self.account = account |
|---|
| 417 | self.is_fake = is_fake |
|---|
| 418 | |
|---|
| 419 | # self.avatar_mime_type = None |
|---|
| 420 | # self.avatar_encoded = None |
|---|
| 421 | |
|---|
| 422 | self.fill_contact_page() |
|---|
| 423 | self.fill_personal_page() |
|---|
| 424 | |
|---|
| 425 | self.xml.signal_autoconnect(self) |
|---|
| 426 | self.window.show_all() |
|---|
| 427 | |
|---|
| 428 | def on_zeroconf_information_window_destroy(self, widget): |
|---|
| 429 | del gajim.interface.instances[self.account]['infos'][self.contact.jid] |
|---|
| 430 | |
|---|
| 431 | def on_zeroconf_information_window_key_press_event(self, widget, event): |
|---|
| 432 | if event.keyval == gtk.keysyms.Escape: |
|---|
| 433 | self.window.destroy() |
|---|
| 434 | |
|---|
| 435 | def on_PHOTO_eventbox_button_press_event(self, widget, event): |
|---|
| 436 | '''If right-clicked, show popup''' |
|---|
| 437 | if event.button == 3: # right click |
|---|
| 438 | menu = gtk.Menu() |
|---|
| 439 | menuitem = gtk.ImageMenuItem(gtk.STOCK_SAVE_AS) |
|---|
| 440 | menuitem.connect('activate', |
|---|
| 441 | gtkgui_helpers.on_avatar_save_as_menuitem_activate, |
|---|
| 442 | self.contact.jid, self.account, self.contact.get_shown_name() + |
|---|
| 443 | '.jpeg') |
|---|
| 444 | menu.append(menuitem) |
|---|
| 445 | menu.connect('selection-done', lambda w:w.destroy()) |
|---|
| 446 | # show the menu |
|---|
| 447 | menu.show_all() |
|---|
| 448 | menu.popup(None, None, None, event.button, event.time) |
|---|
| 449 | |
|---|
| 450 | def set_value(self, entry_name, value): |
|---|
| 451 | try: |
|---|
| 452 | if value and entry_name == 'URL_label': |
|---|
| 453 | if gtk.pygtk_version >= (2, 10, 0) and gtk.gtk_version >= (2, 10, 0): |
|---|
| 454 | widget = gtk.LinkButton(value, value) |
|---|
| 455 | widget.set_alignment(0, 0) |
|---|
| 456 | else: |
|---|
| 457 | widget = gtk.Label(value) |
|---|
| 458 | widget.set_selectable(True) |
|---|
| 459 | widget.set_alignment(0, 0) |
|---|
| 460 | table = self.xml.get_widget('personal_info_table') |
|---|
| 461 | table.attach(widget, 1, 4, 3, 4, yoptions = 0) |
|---|
| 462 | else: |
|---|
| 463 | self.xml.get_widget(entry_name).set_text(value) |
|---|
| 464 | except AttributeError: |
|---|
| 465 | pass |
|---|
| 466 | |
|---|
| 467 | def fill_status_label(self): |
|---|
| 468 | if self.xml.get_widget('information_notebook').get_n_pages() < 2: |
|---|
| 469 | return |
|---|
| 470 | contact_list = gajim.contacts.get_contacts(self.account, self.contact.jid) |
|---|
| 471 | # stats holds show and status message |
|---|
| 472 | stats = '' |
|---|
| 473 | one = True # Are we adding the first line ? |
|---|
| 474 | if contact_list: |
|---|
| 475 | for c in contact_list: |
|---|
| 476 | if not one: |
|---|
| 477 | stats += '\n' |
|---|
| 478 | stats += helpers.get_uf_show(c.show) |
|---|
| 479 | if c.status: |
|---|
| 480 | stats += ': ' + c.status |
|---|
| 481 | if c.last_status_time: |
|---|
| 482 | stats += '\n' + _('since %s') % time.strftime('%c', |
|---|
| 483 | c.last_status_time).decode(locale.getpreferredencoding()) |
|---|
| 484 | one = False |
|---|
| 485 | else: # Maybe gc_vcard ? |
|---|
| 486 | stats = helpers.get_uf_show(self.contact.show) |
|---|
| 487 | if self.contact.status: |
|---|
| 488 | stats += ': ' + self.contact.status |
|---|
| 489 | status_label = self.xml.get_widget('status_label') |
|---|
| 490 | status_label.set_max_width_chars(15) |
|---|
| 491 | status_label.set_text(stats) |
|---|
| 492 | |
|---|
| 493 | tip = gtk.Tooltips() |
|---|
| 494 | status_label_eventbox = self.xml.get_widget('status_label_eventbox') |
|---|
| 495 | tip.set_tip(status_label_eventbox, stats) |
|---|
| 496 | |
|---|
| 497 | def fill_contact_page(self): |
|---|
| 498 | tooltips = gtk.Tooltips() |
|---|
| 499 | self.xml.get_widget('nickname_label').set_markup( |
|---|
| 500 | '<b><span size="x-large">' + |
|---|
| 501 | self.contact.get_shown_name() + |
|---|
| 502 | '</span></b>') |
|---|
| 503 | self.xml.get_widget('local_jid_label').set_text(self.contact.jid) |
|---|
| 504 | |
|---|
| 505 | resources = '%s (%s)' % (self.contact.resource, unicode( |
|---|
| 506 | self.contact.priority)) |
|---|
| 507 | uf_resources = self.contact.resource + _(' resource with priority ')\ |
|---|
| 508 | + unicode(self.contact.priority) |
|---|
| 509 | if not self.contact.status: |
|---|
| 510 | self.contact.status = '' |
|---|
| 511 | |
|---|
| 512 | # Request list time status |
|---|
| 513 | # gajim.connections[self.account].request_last_status_time(self.contact.jid, |
|---|
| 514 | # self.contact.resource) |
|---|
| 515 | |
|---|
| 516 | self.xml.get_widget('resource_prio_label').set_text(resources) |
|---|
| 517 | resource_prio_label_eventbox = self.xml.get_widget( |
|---|
| 518 | 'resource_prio_label_eventbox') |
|---|
| 519 | tooltips.set_tip(resource_prio_label_eventbox, uf_resources) |
|---|
| 520 | |
|---|
| 521 | self.fill_status_label() |
|---|
| 522 | |
|---|
| 523 | # gajim.connections[self.account].request_vcard(self.contact.jid, self.is_fake) |
|---|
| 524 | |
|---|
| 525 | def fill_personal_page(self): |
|---|
| 526 | contact = gajim.connections[gajim.ZEROCONF_ACC_NAME].roster.getItem(self.contact.jid) |
|---|
| 527 | for key in ('1st', 'last', 'jid', 'email'): |
|---|
| 528 | if key not in contact['txt_dict']: |
|---|
| 529 | contact['txt_dict'][key] = '' |
|---|
| 530 | self.xml.get_widget('first_name_label').set_text(contact['txt_dict']['1st']) |
|---|
| 531 | self.xml.get_widget('last_name_label').set_text(contact['txt_dict']['last']) |
|---|
| 532 | self.xml.get_widget('jabber_id_label').set_text(contact['txt_dict']['jid']) |
|---|
| 533 | self.xml.get_widget('email_label').set_text(contact['txt_dict']['email']) |
|---|
| 534 | |
|---|
| 535 | def on_close_button_clicked(self, widget): |
|---|
| 536 | self.window.destroy() |
|---|
| 537 | |
|---|
| 538 | # vim: se ts=3: |
|---|