From 6ae5e4111a76f9cb8f59ae6dfc9123365df39467 Mon Sep 17 00:00:00 2001 From: Simon Schampijer Date: Sat, 01 Sep 2007 09:11:36 +0000 Subject: Merge branch 'master' into json Conflicts: model.py webactivity.py --- diff --git a/NEWS b/NEWS index c564b60..4901064 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,9 @@ +* use sugar tray which enables scrolling for the links (erikos) +* only try to connect to presence service when offline (erikos) + +44 + +* new design for shared links (erikos) * start the activity with in the browser tab open when in joined a shared session or a handle.uri is given (erikos) diff --git a/activity/activity.info b/activity/activity.info index 6f145e6..3faad9d 100755 --- a/activity/activity.info +++ b/activity/activity.info @@ -1,6 +1,6 @@ [Activity] name = Browse -activity_version = 43 +activity_version = 44 service_name = org.laptop.WebActivity icon = activity-web class = webactivity.WebActivity diff --git a/linkbutton.py b/linkbutton.py index 5d6fb65..f5ad9cc 100644 --- a/linkbutton.py +++ b/linkbutton.py @@ -17,20 +17,31 @@ import gtk import os - +import gobject +from gettext import gettext as _ import rsvg import re -from sugar.graphics.palette import Palette, WidgetInvoker +from sugar.graphics.palette import Palette +from sugar.graphics.palette import WidgetInvoker +from sugar.graphics.tray import TrayButton +from sugar.graphics.icon import Icon from sugar.graphics import style -class LinkButton(gtk.RadioToolButton): - def __init__(self, buffer, color, pos, group=None): - gtk.RadioToolButton.__init__(self, group=group) - self._palette = None +class LinkButton(TrayButton, gobject.GObject): + __gtype_name__ = 'LinkButton' + __gsignals__ = { + 'remove_link': (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, ([int])) + } + def __init__(self, url, buffer, color, title, owner, index): + TrayButton.__init__(self) self.set_image(buffer, color.split(',')[1], color.split(',')[0]) - self.pos = pos + + self.index = index + info = title +'\n'+ owner + self.setup_rollover_options(info) def set_image(self, buffer, fill='#0000ff', stroke='#4d4c4f'): img = gtk.Image() @@ -54,7 +65,6 @@ class LinkButton(gtk.RadioToolButton): pixbuf.composite(pixbuf_bg, dest_x, dest_y, w, h, dest_x, dest_y, scale_x, scale_y, gtk.gdk.INTERP_BILINEAR, 255) - img.set_from_pixbuf(pixbuf_bg) self.set_icon_widget(img) img.show() @@ -75,15 +85,15 @@ class LinkButton(gtk.RadioToolButton): data_size = len(data) return rsvg.Handle(data=data).get_pixbuf() - def get_palette(self): - return self._palette - - def set_palette(self, palette): - self._palette = palette - self._palette.props.invoker = WidgetInvoker(self.child) + def setup_rollover_options(self, info): + palette = Palette(info) + self.set_palette(palette) + palette.props.invoker = WidgetInvoker(self) - def set_tooltip(self, text): - self._palette = Palette(text) - self._palette.props.invoker = WidgetInvoker(self.child) - - palette = property(get_palette, set_palette) + menu_item = gtk.MenuItem(_('Remove')) + menu_item.connect('activate', self.item_remove_cb) + palette.menu.append(menu_item) + menu_item.show() + + def item_remove_cb(self, widget): + self.emit('remove_link', self.index) diff --git a/linktoolbar.py b/linktoolbar.py deleted file mode 100644 index 3a36e6b..0000000 --- a/linktoolbar.py +++ /dev/null @@ -1,92 +0,0 @@ -# Copyright (C) 2007, One Laptop Per Child -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This library 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 -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -import logging - -import gobject -import gtk - -from gettext import gettext as _ - -from linkbutton import LinkButton -from sugar.graphics.palette import Palette - -_logger = logging.getLogger('linktoolbar') - -class LinkToolbar(gtk.Toolbar): - __gtype_name__ = 'LinkToolbar' - - __gsignals__ = { - 'link-selected': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([str])), - 'link-rm': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([int])) - } - - def __init__(self): - gtk.Toolbar.__init__(self) - self.isvisible = False - - def _add_link(self, url, buffer, color, title, owner, pos): - - if self.get_children(): - group = self.get_children()[0] - else: - group = None - - info = title +'\n' + owner - palette = Palette(info) - - link = LinkButton(buffer, color, pos, group) - link.set_palette(palette) - link.connect('clicked', self._link_clicked_cb, url) - self.insert(link, 0) - link.show() - - menu_item = gtk.MenuItem(_('Remove')) - menu_item.connect('activate', self._link_rm_palette_cb, link) - palette.menu.append(menu_item) - menu_item.show() - - if len(self.get_children()) > 0: - self.isvisible = True - self.show() - - def _link_clicked_cb(self, link, url): - if link.get_active(): - _logger.debug('link clicked=%s' %url) - self.emit('link-selected', url) - - def _rm_link(self): - childs = self.get_children() - for child in childs: - if child.get_active(): - index = child.pos - self.remove(child) - if len(self.get_children()) is 0: - self.isvisible = False - self.hide() - return index - - def _link_rm_palette_cb(self, widget, link): - self.emit('link-rm', link.pos) - self.remove(link) - if len(self.get_children()) is 0: - self.hide() - diff --git a/messenger.py b/messenger.py index 489be0e..e7edbdf 100644 --- a/messenger.py +++ b/messenger.py @@ -21,7 +21,6 @@ import os import dbus from dbus.gobject_service import ExportedGObject import base64 -import sha SERVICE = "org.laptop.WebActivity" IFACE = SERVICE @@ -30,13 +29,12 @@ PATH = "/org/laptop/WebActivity" _logger = logging.getLogger('messenger') class Messenger(ExportedGObject): - def __init__(self, tube, is_initiator, model, linkbar, owner): + def __init__(self, tube, is_initiator, model, owner): ExportedGObject.__init__(self, tube, PATH) self.tube = tube self.is_initiator = is_initiator self.members = [] self.entered = False - self.linkbar = linkbar self.model = model self.owner = owner self.tube.watch_participants(self.participant_change_cb) @@ -102,11 +100,10 @@ class Messenger(ExportedGObject): '''Send link''' _logger.debug('Received data for link.') a_ids = self.model.get_links_ids() + print a_ids if id not in a_ids: thumb = base64.b64decode(buffer) - self.model.links.append( {'hash':sha.new(url).hexdigest(), 'url':url, 'title':title, 'thumb':thumb, - 'owner':owner, 'color':color, 'deleted':0} ) - self.linkbar._add_link(url, thumb, color, title, owner, len(self.model.links)-1) + self.model.add_link(url, title, thumb, owner, color) @dbus.service.signal(IFACE, signature='sssss') def _add_link(self, url, title, color, owner, thumb): @@ -118,9 +115,6 @@ class Messenger(ExportedGObject): handle = self.tube.bus_name_to_handle[sender] if self.tube.self_handle != handle: buffer = base64.b64decode(thumb) - - self.model.links.append( {'hash':sha.new(url).hexdigest(), 'url':url, 'title':title, 'thumb':buffer, - 'owner':owner, 'color':color, 'deleted':0} ) - self.linkbar._add_link(url, buffer, color, title, owner, len(self.model.links)-1) + self.model.add_link(url, title, buffer, owner, color) _logger.debug('Added link: %s to linkbar.'%(url)) diff --git a/model.py b/model.py index 6bdb94e..fdb8ff9 100644 --- a/model.py +++ b/model.py @@ -18,22 +18,32 @@ import os import logging -import base64 import json - -from xpcom import components -from xpcom.components import interfaces +import sha +import gobject _logger = logging.getLogger('model') -class Model(object): +class Model(gobject.GObject): ''' The model of the activity which uses json to serialize its data to a file and deserelize from it. ''' + __gsignals__ = { + 'add_link': (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, ([int])) + } def __init__(self): + gobject.GObject.__init__(self) + self.data = {} self.links = [] + self.data['shared_links'] = self.links + + def add_link(self, url, title, thumb, owner, color): + self.links.append( {'hash':sha.new(url).hexdigest(), 'url':url, 'title':title, 'thumb':thumb, + 'owner':owner, 'color':color, 'deleted':0} ) + self.emit('add_link', len(self.links)-1) def serialize(self): self.get_session() diff --git a/webactivity.py b/webactivity.py index 67c5995..b0180db 100755 --- a/webactivity.py +++ b/webactivity.py @@ -29,6 +29,7 @@ import telepathy import telepathy.client from sugar import _sugarext from sugar.presence import presenceservice +from sugar.graphics.tray import HTray import hulahop hulahop.startup(os.path.join(env.get_profile_path(), 'gecko')) @@ -44,10 +45,10 @@ import progresslistener _LIBRARY_PATH = '/home/olpc/Library/index.html' -from linktoolbar import LinkToolbar from model import Model from sugar.presence.tubeconn import TubeConnection from messenger import Messenger +from linkbutton import LinkButton SERVICE = "org.laptop.WebActivity" IFACE = SERVICE @@ -82,15 +83,15 @@ class WebActivity(activity.Activity): self.set_toolbox(toolbox) toolbox.show() - self.linkbar = LinkToolbar() - self.linkbar.connect('link-selected', self._link_selected_cb) - self.linkbar.connect('link-rm', self._link_rm_cb) + self._tray = HTray() self.session_history = sessionhistory.get_instance() self.session_history.connect('session-link-changed', self._session_history_changed_cb) - self.toolbar._add_link.connect('clicked', self._add_link_button_cb) + self.toolbar._add_link.connect('clicked', self._share_link_button_cb) self._browser.connect("notify::title", self._title_changed_cb) + self.model = Model() + self.model.connect('add_link', self._add_link_model_cb) self._main_view = gtk.VBox() self.set_canvas(self._main_view) @@ -99,8 +100,8 @@ class WebActivity(activity.Activity): self._main_view.pack_start(self._browser) self._browser.show() - self._main_view.pack_start(self.linkbar, expand=False) - self.linkbar.show() + self._main_view.pack_start(self._tray, expand=False) + self._tray.show() self.current = _('blank') self.webtitle = _('blank') @@ -122,12 +123,15 @@ class WebActivity(activity.Activity): self.messenger = None self.connect('shared', self._shared_cb) - # Get the Presence Service + # Get the Presence Service self.pservice = presenceservice.get_instance() - name, path = self.pservice.get_preferred_connection() - self.tp_conn_name = name - self.tp_conn_path = path - self.conn = telepathy.client.Connection(name, path) + try: + name, path = self.pservice.get_preferred_connection() + self.tp_conn_name = name + self.tp_conn_path = path + self.conn = telepathy.client.Connection(name, path) + except TypeError: + _logger.debug('Offline') self.initiating = None if self._shared_activity is not None: @@ -144,7 +148,6 @@ class WebActivity(activity.Activity): self._joined_cb() else: _logger.debug('Created activity') - def _shared_cb(self, activity): _logger.debug('My activity was shared') @@ -154,8 +157,7 @@ class WebActivity(activity.Activity): _logger.debug('This is my activity: making a tube...') id = self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].OfferDBusTube( SERVICE, {}) - - + def _setup(self): if self._shared_activity is None: _logger.debug('Failed to share or join activity') @@ -237,7 +239,7 @@ class WebActivity(activity.Activity): id, group_iface=self.text_chan[telepathy.CHANNEL_INTERFACE_GROUP]) _logger.debug('Tube created') - self.messenger = Messenger(self.tube_conn, self.initiating, self.model, self.linkbar, self.owner) + self.messenger = Messenger(self.tube_conn, self.initiating, self.model, self.owner) def _load_homepage(self): @@ -263,9 +265,13 @@ class WebActivity(activity.Activity): self.model.deserialize(file_path) i=0 for link in self.model.links: - _logger.debug('read: url=%s title=%s d=%s' % (link['url'], link['title'], link['color'])) - if link['deleted'] == 0: - self.linkbar._add_link(link['url'], link['thumb'], link['color'], link['title'], link['owner'], i) + _logger.debug('read: url=%s title=%s d=%s' % (link['url'], + link['title'], + link['color'])) + if link['deleted'] == 0: + self._add_link_totray(link['url'], link['thumb'], + link['color'], link['title'], + link['owner'], i) i+=1 if self.model.data['history'] is not '': @@ -284,43 +290,21 @@ class WebActivity(activity.Activity): self.metadata['title'] = self._browser.props.title for link in self.model.links: - _logger.debug('write: url=%s title=%s d=%s' % (link['url'], link['title'], link['color'])) - - self.model.session_data = self._browser.get_session() - _logger.debug('Trying save session: %s.' % self.model.session_data) - self.model.write(file_path) - - def destroy(self): - if downloadmanager.can_quit(): - activity.Activity.destroy(self) - else: - downloadmanager.set_quit_callback(self._quit_callback_cb) + _logger.debug('write: url=%s title=%s d=%s' % (link['url'], + link['title'], + link['color'])) - def _quit_callback_cb(self): - _logger.debug('_quit_callback_cb') - activity.Activity.destroy(self) - - def _link_selected_cb(self, linkbar, link): - self._browser.load_uri(link) - - def _link_rm_cb(self, linkbar, index): - self.model.links[index]['deleted'] = 1 - self.model.links[index]['thumb'] = '' + self.model.data['history'] = self._browser.get_session() + # self.model.write(file_path) - def _add_link_button_cb(self, button): + def _share_link_button_cb(self, button): self._add_link() def key_press_cb(self, widget, event): if event.state & gtk.gdk.CONTROL_MASK: if gtk.gdk.keyval_name(event.keyval) == "l": self._add_link() - return True - elif gtk.gdk.keyval_name(event.keyval) == "r": - _logger.debug('keyboard: Remove link: %s.' % self.current) - current = self.linkbar._rm_link() - self.model.links[current]['deleted'] = 1 - self.model.links[current]['thumb'] = '' - return True + return True elif gtk.gdk.keyval_name(event.keyval) == "s": _logger.debug('keyboard: Toggle visibility of tray') self._toggle_visibility_tray() @@ -330,23 +314,49 @@ class WebActivity(activity.Activity): def _add_link(self): buffer = self._get_screenshot() _logger.debug('keyboard: Add link: %s.' % self.current) - self.model.links.append( {'hash':sha.new(self.current).hexdigest(), 'url':self.current, 'title':self.webtitle, - 'thumb':buffer, 'owner':self.owner.props.nick, 'color':self.owner.props.color, 'deleted':0} ) - - self.linkbar._add_link(self.current, buffer, self.owner.props.color, self.webtitle, self.owner.props.nick, - len(self.model.links)-1) + self.model.links.append( {'hash':sha.new(self.current).hexdigest(), + 'url':self.current, 'title':self.webtitle, + 'thumb':buffer, 'owner':self.owner.props.nick, + 'color':self.owner.props.color, 'deleted':0} ) + + self._add_link_totray(self.current, buffer, self.owner.props.color, + self.webtitle, self.owner.props.nick, + len(self.model.links)-1) if self.messenger is not None: import base64 - self.messenger._add_link(self.current, self.webtitle, self.owner.props.color, - self.owner.props.nick, base64.b64encode(buffer)) + self.messenger._add_link(self.current, self.webtitle, + self.owner.props.color, + self.owner.props.nick, + base64.b64encode(buffer)) + + def _add_link_model_cb(self, model, index): + link = self.model.links[index] + self._add_link_totray(link['url'], link['thumb'], + link['color'], link['title'], + link['owner'], index) + + def _add_link_totray(self, url, buffer, color, title, owner, index): + item = LinkButton(url, buffer, color, title, owner, index) + item.connect('clicked', self._link_clicked_cb, url) + item.connect('remove_link', self._link_removed_cb) + self._tray.add_item(item, 0) # add to the beginning of the tray + item.show() + + def _link_clicked_cb(self, button, url): + self._browser.load_uri(url) + def _link_removed_cb(self, button, index): + self.model.links[index]['deleted'] = 1 + self.model.links[index]['thumb'] = '' + self._tray.remove_item(button) + def _toggle_visibility_tray(self): - if self.linkbar.isvisible is True: - self.linkbar.isvisible = False - self.linkbar.hide() + if self._tray.isvisible is True: + self._tray.isvisible = False + self._tray.hide() else: - self.linkbar.isvisible = True - self.linkbar.show() + self._tray.isvisible = True + self._tray.show() def _pixbuf_save_cb(self, buf, data): data[0] += buf @@ -362,7 +372,8 @@ class WebActivity(activity.Activity): width, height = window.get_size() screenshot = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, has_alpha=False, - bits_per_sample=8, width=width, height=height) + bits_per_sample=8, width=width, + height=height) screenshot.get_from_drawable(window, window.get_colormap(), 0, 0, 0, 0, width, height) @@ -372,3 +383,13 @@ class WebActivity(activity.Activity): buffer = self.get_buffer(screenshot) return buffer + + def destroy(self): + if downloadmanager.can_quit(): + activity.Activity.destroy(self) + else: + downloadmanager.set_quit_callback(self._quit_callback_cb) + + def _quit_callback_cb(self): + _logger.debug('_quit_callback_cb') + activity.Activity.destroy(self) -- cgit v0.9.1