# Copyright 2007 Collabora Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import dbus import hippo import gtk import pango from sugar import profile from sugar.activity.activity import Activity from sugar.graphics import font from sugar.graphics.canvasicon import CanvasIcon from sugar.graphics.roundbox import RoundBox from sugar.graphics.xocolor import XoColor from sugar.graphics.units import points_to_pixels as px from sugar.presence import presenceservice from telepathy.client import Connection, Channel from telepathy.interfaces import ( CONN_INTERFACE, PROPERTIES_INTERFACE, CHANNEL_INTERFACE_GROUP, CONN_INTERFACE_ALIASING, CHANNEL_TYPE_TEXT) CONN_INTERFACE_BUDDY_INFO = 'org.laptop.Telepathy.BuddyInfo' from telepathy.constants import ( CONNECTION_HANDLE_TYPE_NONE, CONNECTION_HANDLE_TYPE_CONTACT, CONNECTION_HANDLE_TYPE_ROOM, CHANNEL_TEXT_MESSAGE_TYPE_NORMAL, CONNECTION_STATUS_CONNECTED, CONNECTION_STATUS_DISCONNECTED, CONNECTION_STATUS_CONNECTING) room = 'chat@conference.olpc.collabora.co.uk' class Chat(Activity): def __init__(self, handle): Activity.__init__(self, handle) self.set_title('Chat') root = self.make_root() self.set_canvas(root) root.show_all() self.owner_color = profile.get_color() self.owner_nickname = profile.get_nick_name() #self.add_text(self.owner_nickname, self.make_owner_icon(), 'Hello') # test long line #self.add_text(self.owner_nickname, self.make_owner_icon(), # 'one two three four five six seven eight nine ten ' + # 'one two three four five six seven eight nine ten ' + # 'one two three four five six seven eight nine ten ' + # 'one two three four five six seven eight nine ten') pservice = presenceservice.get_instance() bus = dbus.Bus() name, path = pservice.get_preferred_connection() conn = Connection(name, path) conn[CONN_INTERFACE].connect_to_signal('StatusChanged', self.status_changed_cb) self.conn = conn self.conn_name = name self.chan = None status = conn[CONN_INTERFACE].GetStatus() if status == CONNECTION_STATUS_CONNECTED: print "connected" self.join_room () def received_cb(self, id, timestamp, sender, type, flags, text): try: # XXX: Shoule use PS instead of directly use TP alias = self.conn[CONN_INTERFACE_ALIASING].RequestAliases([sender])[0] print '%s: %s' % (alias, text) try: handle = self.chan[CHANNEL_INTERFACE_GROUP].GetHandleOwners([sender])[0] infos = self.conn[CONN_INTERFACE_BUDDY_INFO].GetProperties(handle) color = infos['color'] except dbus.DBusException, e: print "failed to query buddy infos:", e color = "#000000,#ffffff" icon = CanvasIcon( icon_name='theme:stock-buddy', xo_color=XoColor(color)) self.add_text(alias, icon, text) except Exception, e: print e def join_room(self): try: bus = dbus.Bus() chan_handle = self.conn[CONN_INTERFACE].RequestHandles(2, [room])[0] chan_path = self.conn[CONN_INTERFACE].RequestChannel(CHANNEL_TYPE_TEXT, 2, chan_handle, True) self.chan = Channel(self.conn_name, chan_path) self.chan[CHANNEL_TYPE_TEXT].connect_to_signal('Received', self.received_cb) # XXX Muc shouldn't be semianonymous by default self.chan[PROPERTIES_INTERFACE].SetProperties([(0, False)]) except Exception, e: print e def status_changed_cb(self, status, reason): if status == CONNECTION_STATUS_CONNECTED and not self.chan: self.join_room() elif status == CONNECTION_STATUS_DISCONNECTED: print 'disconnected' self.chan.Close() self.chan = None def make_root(self): text = hippo.CanvasText( text='Hello', font_desc=pango.FontDescription('Sans 64'), color=0xffffffff) conversation = hippo.CanvasBox(spacing=px(4)) self.conversation = conversation entry = gtk.Entry() # XXX make this entry unsensitive while we're not # connected. entry.connect('activate', self.entry_activate_cb) hbox = gtk.HBox() hbox.add(entry) canvas = hippo.Canvas() canvas.set_root(conversation) sw = gtk.ScrolledWindow() sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) sw.add_with_viewport(canvas) self.scrolled_window = sw widget = hippo.CanvasWidget(widget=sw) box = gtk.VBox(homogeneous=False) box.pack_start(sw) box.pack_start(hbox, expand=False) return box def make_owner_icon(self): return CanvasIcon( icon_name='theme:stock-buddy', xo_color=self.owner_color) def add_text(self, name, icon, text): text = hippo.CanvasText( text=text, size_mode=hippo.CANVAS_SIZE_WRAP_WORD, xalign=hippo.ALIGNMENT_START) name = hippo.CanvasText(text=name) vbox = hippo.CanvasBox(padding=px(5)) if icon: vbox.append(icon) vbox.append(name) rb = RoundBox(background_color=0xffffffff, padding=px(3)) rb.append(text) box = hippo.CanvasBox( orientation=hippo.ORIENTATION_HORIZONTAL, spacing=px(5)) box.append(vbox) box.append(rb) self.conversation.append(box) aw, ah = self.conversation.get_allocation() #print 'allocation = %r' % ((aw, ah),) rw, rh = self.conversation.get_height_request(aw) #print 'request = %r' % ((rw, rh),) adj = self.scrolled_window.get_vadjustment() #print 'value = %r' % adj.value #print 'upper = %r' % adj.upper #print 'page_size = %r' % adj.page_size #adj.set_value(adj.upper - adj.page_size) #adj.set_value(rh) adj.set_value(adj.upper - adj.page_size - 804) def entry_activate_cb(self, entry): text = entry.props.text print `text` if text: self.add_text(self.owner_nickname, self.make_owner_icon(), text) entry.props.text = '' if self.chan: self.chan[CHANNEL_TYPE_TEXT].Send(CHANNEL_TEXT_MESSAGE_TYPE_NORMAL, text)