Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/activities
diff options
context:
space:
mode:
authorMarco Pesenti Gritti <marco@localhost.localdomain>2006-06-21 18:23:18 (GMT)
committer Marco Pesenti Gritti <marco@localhost.localdomain>2006-06-21 18:23:18 (GMT)
commitf4e2791c897651d52980d35b84115e7c7f85a249 (patch)
tree8999ddbed2a6e3cc5864e4d59f9a6320e3fc9038 /activities
parenta6974cd597b52c9782e105a38d709784f882bedf (diff)
Big refactor of the directory structure and packages to
reflect private/public
Diffstat (limited to 'activities')
-rw-r--r--activities/browser/AddressItem.py66
-rw-r--r--activities/browser/BrowserActivity.py156
-rw-r--r--activities/browser/BrowserShell.py51
-rw-r--r--activities/browser/Makefile.am25
-rw-r--r--activities/browser/NavigationToolbar.py62
-rw-r--r--activities/browser/NotificationBar.py58
-rw-r--r--activities/browser/__init__.py0
-rw-r--r--activities/browser/browser.activity2
-rwxr-xr-xactivities/browser/browser.py21
-rw-r--r--activities/browser/browser.rc7
-rw-r--r--activities/browser/fold.pngbin0 -> 156 bytes
-rw-r--r--activities/browser/unfold.pngbin0 -> 157 bytes
12 files changed, 448 insertions, 0 deletions
diff --git a/activities/browser/AddressItem.py b/activities/browser/AddressItem.py
new file mode 100644
index 0000000..df5e71c
--- /dev/null
+++ b/activities/browser/AddressItem.py
@@ -0,0 +1,66 @@
+import pygtk
+pygtk.require('2.0')
+import gtk
+
+class AddressEntry(gtk.HBox):
+ def __init__(self, callback):
+ gtk.HBox.__init__(self)
+
+ self.callback = callback
+ self.folded = True
+
+ label = gtk.Label("Open")
+ self.pack_start(label, False)
+ label.show()
+
+ self.button = gtk.Button()
+ self.button.set_relief(gtk.RELIEF_NONE)
+ self.button.connect("clicked", self.__button_clicked_cb)
+ self.pack_start(self.button, False)
+ self.button.show()
+
+ self.entry = gtk.Entry()
+ self.entry.connect("activate", self.__activate_cb)
+ self.pack_start(self.entry, False)
+ self.entry.show()
+
+ self._update_folded_state()
+
+ def _update_folded_state(self):
+ if self.folded:
+ image = gtk.Image()
+ image.set_from_icon_name('expand', gtk.ICON_SIZE_SMALL_TOOLBAR)
+ self.button.set_image(image)
+ image.show()
+
+ self.entry.hide()
+ else:
+ image = gtk.Image()
+ image.set_from_icon_name('unexpand', gtk.ICON_SIZE_SMALL_TOOLBAR)
+ self.button.set_image(image)
+ image.show()
+
+ self.entry.show()
+ self.entry.grab_focus()
+
+ def get_folded(self):
+ return self.folded
+
+ def set_folded(self, folded):
+ self.folded = folded
+ self._update_folded_state()
+
+ def __button_clicked_cb(self, button):
+ self.set_folded(not self.get_folded())
+
+ def __activate_cb(self, entry):
+ self.callback(entry.get_text())
+ self.set_folded(True)
+
+class AddressItem(gtk.ToolItem):
+ def __init__(self, callback):
+ gtk.ToolItem.__init__(self)
+
+ address_entry = AddressEntry(callback)
+ self.add(address_entry)
+ address_entry.show()
diff --git a/activities/browser/BrowserActivity.py b/activities/browser/BrowserActivity.py
new file mode 100644
index 0000000..662313f
--- /dev/null
+++ b/activities/browser/BrowserActivity.py
@@ -0,0 +1,156 @@
+import logging
+import xml.sax.saxutils
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+import geckoembed
+
+from sugar.activity import activity
+from sugar.presence.PresenceService import PresenceService
+from sugar.p2p.model.LocalModel import LocalModel
+from sugar.p2p.model.RemoteModel import RemoteModel
+
+from NotificationBar import NotificationBar
+from NavigationToolbar import NavigationToolbar
+
+_BROWSER_ACTIVITY_TYPE = "_web_olpc._udp"
+_SERVICE_URI_TAG = "URI"
+_SERVICE_TITLE_TAG = "Title"
+
+class BrowserActivity(activity.Activity):
+ SOLO = 1
+ FOLLOWING = 2
+ LEADING = 3
+
+ def __init__(self, uri, mode = SOLO):
+ activity.Activity.__init__(self, _BROWSER_ACTIVITY_TYPE)
+ self.uri = uri
+ self._mode = mode
+
+ self._share_service = None
+ self._model_service = None
+ self._notif_service = None
+ self._model = None
+
+ def _service_appeared_cb(self, pservice, buddy, service):
+ # Make sure the service is for our activity
+ if service.get_activity_uid() != self._activity_id:
+ return
+
+ if service.get_type() == _BROWSER_ACTIVITY_TYPE:
+ self._notif_service = service
+ elif service.get_type() == LocalModel.SERVICE_TYPE:
+ if self._mode != BrowserActivity.LEADING:
+ self._model_service = service
+
+ if self._notif_service and self._model_service:
+ self._model = RemoteModel(self._model_service, self._notif_service)
+ self._model.add_listener(self.__shared_location_changed_cb)
+
+ def get_default_type(self):
+ return _BROWSER_ACTIVITY_TYPE
+
+ def _update_shared_location(self):
+ address = self.embed.get_address()
+ self._model.set_value('address', address)
+ title = self.embed.get_title()
+ self._model.set_value('title', title)
+
+ def __notif_bar_action_cb(self, bar, action_id):
+ print action_id
+ if action_id == 'set_shared_location':
+ self._update_shared_location()
+ elif action_id == 'goto_shared_location':
+ address = self._model.get_value("address")
+ print address
+ self.embed.load_address(address)
+ self._notif_bar.hide()
+
+ def set_mode(self, mode):
+ self._mode = mode
+ if mode == BrowserActivity.LEADING:
+ self._notif_bar.set_text('Share this page with the group.')
+ self._notif_bar.set_action('set_shared_location', 'Share')
+ self._notif_bar.set_icon('stock_shared-by-me')
+ self._notif_bar.show()
+
+ def on_connected_to_shell(self):
+ self.set_ellipsize_tab(True)
+ self.set_can_close(True)
+ self.set_tab_text("Web Page")
+ self.set_tab_icon(name="web-browser")
+ self.set_show_tab_icon(True)
+
+ vbox = gtk.VBox()
+
+ self._notif_bar = NotificationBar()
+ vbox.pack_start(self._notif_bar, False)
+ self._notif_bar.connect('action', self.__notif_bar_action_cb)
+
+ self.embed = geckoembed.Embed()
+ self.embed.connect("title", self.__title_cb)
+ vbox.pack_start(self.embed)
+
+ self.embed.show()
+ self.embed.load_address(self.uri)
+
+ nav_toolbar = NavigationToolbar(self)
+ vbox.pack_start(nav_toolbar, False)
+ nav_toolbar.show()
+
+ plug = self.gtk_plug()
+ plug.add(vbox)
+ plug.show()
+
+ vbox.show()
+
+ logging.debug('Start presence service')
+ self._pservice = PresenceService.get_instance()
+ self._pservice.start()
+
+ logging.debug('Track browser activities')
+ self._pservice.connect('service-appeared', self._service_appeared_cb)
+ self._pservice.track_service_type(_BROWSER_ACTIVITY_TYPE)
+ self._pservice.track_service_type(LocalModel.SERVICE_TYPE)
+
+ # Join the shared activity if we were started from one
+ if self._initial_service:
+ logging.debug("BrowserActivity joining shared activity %s" % self._initial_service.get_activity_uid())
+ self._pservice.join_shared_activity(self._initial_service)
+
+ def get_embed(self):
+ return self.embed
+
+ def publish(self):
+ escaped_title = xml.sax.saxutils.escape(self.embed.get_title())
+ escaped_url = xml.sax.saxutils.escape(self.embed.get_address())
+
+ # Publish ourselves on the network
+ properties = {_SERVICE_URI_TAG: escaped_url, _SERVICE_TITLE_TAG: escaped_title}
+ self._share_service = self._pservice.share_activity(self,
+ stype=_BROWSER_ACTIVITY_TYPE, properties=properties)
+
+ # Create our activity-specific browser sharing service
+ self._model = LocalModel(self, self._pservice, self._share_service)
+ self._model.set_value('owner', self._pservice.get_owner().get_nick_name())
+ self._update_shared_location()
+
+ self.set_mode(BrowserActivity.LEADING)
+
+ def __title_cb(self, embed):
+ self.set_tab_text(embed.get_title())
+
+ def __shared_location_changed_cb(self, model, key):
+ self.set_has_changes(True)
+ self._notify_shared_location_change()
+
+ def _notify_shared_location_change(self):
+ owner = self._model.get_value('owner')
+ title = self._model.get_value('title')
+
+ text = '<b>' + owner + '</b> is reading <i>' + title + '</i>'
+ self._notif_bar.set_text(text)
+ self._notif_bar.set_action('goto_shared_location', 'Go There')
+ self._notif_bar.set_icon('stock_right')
+ self._notif_bar.show()
diff --git a/activities/browser/BrowserShell.py b/activities/browser/BrowserShell.py
new file mode 100644
index 0000000..c1e0c44
--- /dev/null
+++ b/activities/browser/BrowserShell.py
@@ -0,0 +1,51 @@
+import dbus
+import geckoembed
+import pygtk
+pygtk.require('2.0')
+import gtk
+import gobject
+
+import sugar.env
+from sugar.presence import Service
+
+from BrowserActivity import BrowserActivity
+
+class BrowserShell(dbus.service.Object):
+ def __init__(self, bus_name, object_path = '/com/redhat/Sugar/Browser'):
+ dbus.service.Object.__init__(self, bus_name, object_path)
+
+ geckoembed.set_profile_path(sugar.env.get_user_dir())
+ self.__browsers = []
+
+ def start(self):
+ gtk.main()
+
+ @dbus.service.method('com.redhat.Sugar.BrowserShell')
+ def get_links(self):
+ links = []
+ for browser in self.__browsers:
+ embed = browser.get_embed()
+ link = {}
+ link['title'] = embed.get_title()
+ link['address'] = embed.get_address()
+ links.append(link)
+ return links
+
+ def _start_browser_cb(self, browser, service):
+ browser.connect_to_shell(service)
+
+ @dbus.service.method('com.redhat.Sugar.BrowserShell')
+ def open_browser(self, uri, serialized_service=None):
+ service = None
+ if serialized_service is not None:
+ service = Service.deserialize(serialized_service)
+ browser = BrowserActivity(uri)
+ self.__browsers.append(browser)
+ gobject.idle_add(self._start_browser_cb, browser, service)
+
+ @dbus.service.method('com.redhat.Sugar.BrowserShell')
+ def open_browser_from_service_foobar(self, uri, serialized_service):
+ service = Service.deserialize(serialized_service)
+ browser = BrowserActivity(uri)
+ self.__browsers.append(browser)
+ gobject.idle_add(self._start_browser_cb, browser, service)
diff --git a/activities/browser/Makefile.am b/activities/browser/Makefile.am
new file mode 100644
index 0000000..2c66e22
--- /dev/null
+++ b/activities/browser/Makefile.am
@@ -0,0 +1,25 @@
+sugardir = $(pythondir)/sugar/browser
+sugar_PYTHON = \
+ __init__.py \
+ browser.py \
+ NotificationBar.py \
+ BrowserShell.py \
+ AddressItem.py \
+ BrowserActivity.py \
+ NavigationToolbar.py
+
+icondir = $(pkgdatadir)
+icon_DATA = \
+ fold.png \
+ unfold.png
+
+rcdir = $(pkgdatadir)
+rc_DATA = browser.rc
+
+activitydir = $(pkgdatadir)/activities
+activity_DATA = browser.activity
+
+EXTRA_DIST = \
+ $(rc_DATA) \
+ $(activity_DATA) \
+ $(icon_DATA)
diff --git a/activities/browser/NavigationToolbar.py b/activities/browser/NavigationToolbar.py
new file mode 100644
index 0000000..bf8c96b
--- /dev/null
+++ b/activities/browser/NavigationToolbar.py
@@ -0,0 +1,62 @@
+import pygtk
+pygtk.require('2.0')
+import gtk
+
+from AddressItem import AddressItem
+
+class NavigationToolbar(gtk.Toolbar):
+ def __init__(self, browser):
+ gtk.Toolbar.__init__(self)
+ self._browser = browser
+ self._embed = self._browser.get_embed()
+
+ self.set_style(gtk.TOOLBAR_BOTH_HORIZ)
+
+ self.back = gtk.ToolButton(None, 'Back')
+ self.back.set_icon_name('back')
+ self.back.connect("clicked", self.__go_back_cb)
+ self.insert(self.back, -1)
+ self.back.show()
+
+ self.forward = gtk.ToolButton(None, 'Forward')
+ self.forward.set_icon_name('forward')
+ self.forward.connect("clicked", self.__go_forward_cb)
+ self.insert(self.forward, -1)
+ self.forward.show()
+
+ self.reload = gtk.ToolButton(None, 'Reload')
+ self.reload.set_icon_name('reload')
+ self.reload.connect("clicked", self.__reload_cb)
+ self.insert(self.reload, -1)
+ self.reload.show()
+
+ separator = gtk.SeparatorToolItem()
+ self.insert(separator, -1)
+ separator.show()
+
+ address_item = AddressItem(self.__open_address_cb)
+ self.insert(address_item, -1)
+ address_item.show()
+
+ self._update_sensitivity()
+
+ self._embed.connect("location", self.__location_changed)
+
+ def _update_sensitivity(self):
+ self.back.set_sensitive(self._embed.can_go_back())
+ self.forward.set_sensitive(self._embed.can_go_forward())
+
+ def __go_back_cb(self, button):
+ self._embed.go_back()
+
+ def __go_forward_cb(self, button):
+ self._embed.go_forward()
+
+ def __reload_cb(self, button):
+ self._embed.reload()
+
+ def __location_changed(self, embed):
+ self._update_sensitivity()
+
+ def __open_address_cb(self, address):
+ self._embed.load_address(address)
diff --git a/activities/browser/NotificationBar.py b/activities/browser/NotificationBar.py
new file mode 100644
index 0000000..c9b3b8a
--- /dev/null
+++ b/activities/browser/NotificationBar.py
@@ -0,0 +1,58 @@
+import pygtk
+pygtk.require('2.0')
+import gtk
+import gobject
+
+class NotificationBar(gtk.HBox):
+ __gsignals__ = {
+ 'action': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([gobject.TYPE_STRING]))
+ }
+
+ def __init__(self):
+ gtk.HBox.__init__(self, False, 12)
+
+ self.set_name("notif bar")
+ self.set_border_width(3)
+
+ self._icon = gtk.Image()
+ self.pack_start(self._icon, False)
+
+ self._text_label = gtk.Label()
+ self._text_label.set_alignment(0.0, 0.5)
+ self.pack_start(self._text_label)
+ self._text_label.show()
+
+ self._action_button = gtk.Button()
+ self._action_button.connect('clicked', self.__button_clicked)
+ self.pack_start(self._action_button, False)
+ self._action_button.show()
+
+ self.connect('expose_event', self.expose)
+
+ def expose(self, widget, event):
+ rect = self.get_allocation()
+ ctx = widget.window.cairo_create()
+
+ ctx.new_path()
+ ctx.rectangle(rect.x, rect.y, rect.width, rect.height)
+ ctx.set_source_rgb(0.56 , 0.75 , 1)
+ ctx.fill_preserve()
+ ctx.set_source_rgb(0.16 , 0.35 , 0.6)
+ ctx.stroke()
+
+ return False
+
+ def set_icon(self, icon_name):
+ self._icon.set_from_icon_name(icon_name, gtk.ICON_SIZE_BUTTON)
+ self._icon.show()
+
+ def set_text(self, text):
+ self._text_label.set_markup(text)
+
+ def set_action(self, action_id, action_text):
+ self._action_id = action_id
+ self._action_button.set_label(action_text)
+
+ def __button_clicked(self, button):
+ self.emit("action", self._action_id)
diff --git a/activities/browser/__init__.py b/activities/browser/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/activities/browser/__init__.py
diff --git a/activities/browser/browser.activity b/activities/browser/browser.activity
new file mode 100644
index 0000000..7aba61f
--- /dev/null
+++ b/activities/browser/browser.activity
@@ -0,0 +1,2 @@
+[Activity]
+python_class = browser
diff --git a/activities/browser/browser.py b/activities/browser/browser.py
new file mode 100755
index 0000000..bdfa2bd
--- /dev/null
+++ b/activities/browser/browser.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+import dbus
+
+import sugar.env
+from sugar.session.LogWriter import LogWriter
+
+from BrowserShell import BrowserShell
+
+log_writer = LogWriter("Web")
+log_writer.start()
+
+gtk.rc_parse(sugar.env.get_data_file('browser.rc'))
+
+session_bus = dbus.SessionBus()
+bus_name = dbus.service.BusName('com.redhat.Sugar.Browser', bus=session_bus)
+shell = BrowserShell(bus_name)
+shell.start()
diff --git a/activities/browser/browser.rc b/activities/browser/browser.rc
new file mode 100644
index 0000000..69f1320
--- /dev/null
+++ b/activities/browser/browser.rc
@@ -0,0 +1,7 @@
+style "NotificationBarButton" = "button"
+{
+ xthickness = 0
+ ythickness = 0
+}
+
+widget "*.notif bar.*GtkButton*" style "NotificationBarButton"
diff --git a/activities/browser/fold.png b/activities/browser/fold.png
new file mode 100644
index 0000000..cd4169b
--- /dev/null
+++ b/activities/browser/fold.png
Binary files differ
diff --git a/activities/browser/unfold.png b/activities/browser/unfold.png
new file mode 100644
index 0000000..f3f82fa
--- /dev/null
+++ b/activities/browser/unfold.png
Binary files differ