98f8ef14ba310eefdde5e0981eca71dde5a2c8af
[hermes] / package / src / org / maemo / hermes / gui / contactview.py
1 import gtk, glib
2 import hildon
3 import gobject
4 import evolution
5 from ctypes import *
6 from pygobject import *
7
8 class ContactView(hildon.PannableArea):
9     """Widget which shows a list of contacts in a pannable area.
10          
11        Copyright (c) Andrew Flegg <andrew@bleb.org> 2009.
12        Released under the Artistic Licence."""
13     
14     
15     # -----------------------------------------------------------------------
16     def __init__(self, contacts):
17         """Constructor. Passed a list of Contacts."""
18         
19         hildon.PannableArea.__init__(self)
20         self.contacts = contacts
21         
22         columns = [gtk.gdk.Pixbuf,         # 0. Photo
23                    str,                    # 1. Name
24                    # ...                   # x. Services
25                    # gobject.TYPE_PYOBJECT # y. Actual contact
26                   ]
27
28         # -- Work out which services need to be shown...
29         #
30         self._icons    = {}
31         self._services = set([])
32         for contact in self.contacts:
33             self._services |= contact.get_mappings()
34
35         for service in sorted(self._services):
36             columns.append(gtk.gdk.Pixbuf)
37             try:
38                 self._icons[service] = gtk.gdk.pixbuf_new_from_file('/opt/hermes/share/account-%s.png' % (service))
39             except glib.GError, e:
40                 self._icons[service] = None
41                 
42         columns.append(gobject.TYPE_PYOBJECT)
43         self.treestore = gtk.ListStore(*tuple(columns))
44         self._contact_index = len(columns) -1
45
46         # -- Build the tree model...
47         #
48         for contact in sorted(self.contacts, cmp = lambda a, b: cmp(a.get_name(), b.get_name())):
49             if not contact.get_name():
50                 continue
51               
52             pi = contact.get_photo()
53             pixbuf = None
54             if pi and pi.contents.data.uri.startswith("image/"):
55                 data = string_at(pi.contents.data.inlined.data, pi.contents.data.inlined.length)
56                 pixbuf_loader = gtk.gdk.PixbufLoader()
57                 pixbuf_loader.write(data)
58                 pixbuf_loader.close()
59                 pixbuf = pixbuf_loader.get_pixbuf()
60             elif pi and pi.contents.data.uri.startswith("file://"):
61                 filename = pi.contents.data.uri[7:]
62                 pixbuf = gtk.gdk.pixbuf_new_from_file(filename)
63                   
64             if pixbuf:
65                 size = min(pixbuf.get_width(), pixbuf.get_height())
66                 pixbuf = pixbuf.subpixbuf(0, 0, size, size).scale_simple(48, 48, gtk.gdk.INTERP_BILINEAR)
67                 
68             row = [pixbuf, contact.get_name(), ]
69             for service in self._services:
70                 row.append(service in contact.get_mappings() and self._icons[service] or None)
71                 
72             row.append(contact)
73             self.treestore.append(row)
74         
75         self.treeview = gtk.TreeView(self.treestore)
76         self.treeview.append_column(gtk.TreeViewColumn('Picture', gtk.CellRendererPixbuf(), pixbuf = 0))
77
78         tvcolumn = gtk.TreeViewColumn('Name', gtk.CellRendererText(), text = 1)
79         tvcolumn.set_expand(True)
80         self.treeview.append_column(tvcolumn)
81
82         i = 2
83         for service in self._services:
84             self.treeview.append_column(gtk.TreeViewColumn('Service', gtk.CellRendererPixbuf(), pixbuf = i))
85             i += 1
86         
87         self.treeview.connect('row-activated', self._activated)
88         self.add(self.treeview)
89         self.set_size_request_policy(hildon.SIZE_REQUEST_CHILDREN)
90
91
92     # -----------------------------------------------------------------------
93     def add_mapping(self, service_id):
94         """Used to emit the `contact-activated' signal once a row has been
95            selected."""
96
97         if self._selected_iter:
98             i = 2
99             for service in self._services:
100                 if service == service_id:
101                     self.treeview.get_model().set_value(self._selected_iter, i, self._icons[service])
102                 i += 1
103       
104
105     # -----------------------------------------------------------------------
106     def _activated(self, treeview, path, column):
107         """Used to emit the `contact-activated' signal once a row has been
108            selected."""
109         
110         self._selected_iter = treeview.get_model().get_iter(path)
111         contact = treeview.get_model().get_value(self._selected_iter, self._contact_index)
112         self.emit('contact-activated', contact)
113
114
115 _contact_activated = gobject.signal_new('contact-activated', ContactView, gobject.SIGNAL_ACTION, gobject.TYPE_NONE, [gobject.TYPE_PYOBJECT])
116
117
118