Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.test.py.swpbin0 -> 12288 bytes
-rw-r--r--.webbrowser.py.swpbin0 -> 12288 bytes
-rwxr-xr-xactivity/activity-web.svg21
-rwxr-xr-xactivity/activity.info8
-rwxr-xr-xlinkscontroller.py60
-rwxr-xr-xlinkscontroller.pycbin0 -> 2598 bytes
-rwxr-xr-xlinksmodel.py51
-rwxr-xr-xlinksmodel.pycbin0 -> 1688 bytes
-rwxr-xr-xlinksview.py83
-rwxr-xr-xlinksview.pycbin0 -> 2973 bytes
-rwxr-xr-xsetup.py22
-rwxr-xr-xstylesheet.py27
-rwxr-xr-xstylesheet.pycbin0 -> 376 bytes
-rwxr-xr-xtoolbar.py148
-rwxr-xr-xtoolbar.pycbin0 -> 4890 bytes
-rwxr-xr-xwebactivity.py139
-rwxr-xr-xwebactivity.pycbin0 -> 4780 bytes
-rwxr-xr-xwebbrowser.py97
18 files changed, 656 insertions, 0 deletions
diff --git a/.test.py.swp b/.test.py.swp
new file mode 100644
index 0000000..668b8c9
--- /dev/null
+++ b/.test.py.swp
Binary files differ
diff --git a/.webbrowser.py.swp b/.webbrowser.py.swp
new file mode 100644
index 0000000..b97bd6e
--- /dev/null
+++ b/.webbrowser.py.swp
Binary files differ
diff --git a/activity/activity-web.svg b/activity/activity-web.svg
new file mode 100755
index 0000000..9ddea1e
--- /dev/null
+++ b/activity/activity-web.svg
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
+ <!ENTITY ns_svg "http://www.w3.org/2000/svg">
+ <!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
+ <!ENTITY fill_color "#FFFFFF">
+ <!ENTITY stroke_color "#000000">
+]>
+<svg version="1.1" id="Icon" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="76" height="76" viewBox="0 0 76 76"
+ overflow="visible" enable-background="new 0 0 76 76" xml:space="preserve">
+
+<circle fill="&fill_color;" stroke="&stroke_color;" stroke-width="3.5" cx="38" cy="38" r="19.903"/>
+<path fill="none" stroke="&stroke_color;" stroke-width="3.5" d="M38.001,18.098c0,0-11.205,8.394-11.205,19.976
+ c0,11.583,11.205,19.829,11.205,19.829"/>
+<path fill="none" stroke="&stroke_color;" stroke-width="3.5" d="M38.001,18.098c0,0,11.066,9.141,11.066,19.976
+ c0,10.839-11.066,19.829-11.066,19.829"/>
+<line fill="none" stroke="&stroke_color;" stroke-width="3.5" x1="38.001" y1="18.098" x2="38.001" y2="57.902"/>
+<line fill="none" stroke="&stroke_color;" stroke-width="3.5" x1="38.001" y1="18.098" x2="38.001" y2="57.902"/>
+<line fill="none" stroke="&stroke_color;" stroke-width="3.5" x1="38.001" y1="18.098" x2="38.001" y2="57.902"/>
+<line fill="none" stroke="&stroke_color;" stroke-width="3.5" x1="18.097" y1="38" x2="57.903" y2="38"/>
+</svg>
diff --git a/activity/activity.info b/activity/activity.info
new file mode 100755
index 0000000..fbbb591
--- /dev/null
+++ b/activity/activity.info
@@ -0,0 +1,8 @@
+[Activity]
+name = Web
+activity_version = 1
+host_version = 1
+service_name = org.laptop.WebActivity
+icon = activity-web
+show_launcher = 1
+exec = sugar-activity-factory org.laptop.WebActivity webactivity.WebActivity
diff --git a/linkscontroller.py b/linkscontroller.py
new file mode 100755
index 0000000..bdc1296
--- /dev/null
+++ b/linkscontroller.py
@@ -0,0 +1,60 @@
+# Copyright (C) 2006, Red Hat, Inc.
+#
+# 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
+
+from sugar.p2p.Stream import Stream
+from sugar.presence import PresenceService
+
+class _Marshaller(object):
+ def __init__(self, title, address):
+ pservice = PresenceService.get_instance()
+ name = pservice.get_owner().get_name()
+ self._message = name + '\n' + title + '\n' + address
+
+ def get_message(self):
+ return self._message
+
+class _Demarshaller(object):
+ def __init__(self, message):
+ self._pservice = PresenceService.get_instance()
+ self._split_msg = message.split('\n')
+
+ def get_buddy(self):
+ return self._pservice.get_buddy_by_name(self._split_msg[0])
+
+ def get_title(self):
+ return self._split_msg[1]
+
+ def get_address(self):
+ return self._split_msg[2]
+
+class LinksController(object):
+ def __init__(self, service, model):
+ self._model = model
+
+ self._stream = Stream.new_from_service(service)
+ self._stream.set_data_listener(self._recv_message)
+ self._stream_writer = self._stream.new_writer()
+
+ def post_link(self, title, address):
+ marshaller = _Marshaller(title, address)
+ self._stream_writer.write(marshaller.get_message())
+
+ def _recv_message(self, address, msg):
+ demarshaller = _Demarshaller(msg)
+ buddy = demarshaller.get_buddy()
+ if buddy:
+ self._model.add_link(buddy, demarshaller.get_title(),
+ demarshaller.get_address())
diff --git a/linkscontroller.pyc b/linkscontroller.pyc
new file mode 100755
index 0000000..ab50724
--- /dev/null
+++ b/linkscontroller.pyc
Binary files differ
diff --git a/linksmodel.py b/linksmodel.py
new file mode 100755
index 0000000..4318bfc
--- /dev/null
+++ b/linksmodel.py
@@ -0,0 +1,51 @@
+# Copyright (C) 2006, Red Hat, Inc.
+#
+# 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 gobject
+
+class Link(object):
+ def __init__(self, buddy, title, url):
+ self.buddy = buddy
+ self.title = title
+ self.url = url
+
+class LinksModel(gobject.GObject):
+ __gsignals__ = {
+ 'link-added': (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])),
+ 'link-removed': (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])),
+ }
+
+ def __init__(self):
+ gobject.GObject.__init__(self)
+ self._links = {}
+
+ def add_link(self, buddy, title, url):
+ link = Link(buddy, title, url)
+ self._links[(buddy.get_name(), url)] = link
+
+ self.emit('link-added', link)
+
+ def remove_link(self, buddy, url):
+ key = (buddy.get_name(), url)
+ if self._links.haskey(key):
+ link = self._links[key]
+ del self._links[key]
+ self.emit('link-removed', link)
+
+ def __iter__(self):
+ return self._links.values().__iter__()
diff --git a/linksmodel.pyc b/linksmodel.pyc
new file mode 100755
index 0000000..fd84e46
--- /dev/null
+++ b/linksmodel.pyc
Binary files differ
diff --git a/linksview.py b/linksview.py
new file mode 100755
index 0000000..70af786
--- /dev/null
+++ b/linksview.py
@@ -0,0 +1,83 @@
+# Copyright (C) 2006, Red Hat, Inc.
+#
+# 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 gtk
+import hippo
+
+from sugar.graphics.menu import Menu
+from sugar.graphics.menushell import MenuShell
+from sugar.graphics.menuicon import MenuIcon
+from sugar.graphics.iconcolor import IconColor
+from sugar.graphics import style
+
+class LinkIcon(MenuIcon):
+ def __init__(self, menu_shell, link):
+ color = IconColor(link.buddy.get_color())
+ MenuIcon.__init__(self, menu_shell, color=color,
+ icon_name='activity-web')
+
+ self._link = link
+
+ def create_menu(self):
+ menu = Menu(self._link.title)
+ return menu
+
+class LinksView(hippo.Canvas):
+ def __init__(self, model, browser):
+ hippo.Canvas.__init__(self)
+
+ self._icons = {}
+ self._browser = browser
+ self._menu_shell = MenuShell(self)
+
+ self._box = hippo.CanvasBox()
+ style.apply_stylesheet(self._box, 'links.Box')
+ self.set_root(self._box)
+
+ for link in model:
+ self._add_link(link)
+
+ model.connect('link_added', self._link_added_cb)
+ model.connect('link_removed', self._link_removed_cb)
+
+ def _add_link(self, link):
+ if len(self._icons) == 0:
+ self.show()
+
+ icon = LinkIcon(self._menu_shell, link)
+ icon.connect('activated', self._link_activated_cb, link)
+ style.apply_stylesheet(icon, 'links.Icon')
+ self._box.append(icon)
+
+ self._icons[link] = icon
+
+ def _remove_link(self, link):
+ icon = self._icons[link]
+ self._box.remove(icon)
+
+ del self._icons[link]
+
+ if len(self._icons) == 0:
+ self.hide()
+
+ def _link_added_cb(self, model, link):
+ self._add_link(link)
+
+ def _link_removed_cb(self, model, link):
+ self._remove_link(link)
+
+ def _link_activated_cb(self, link_item, link):
+ self._browser.load_url(link.url)
diff --git a/linksview.pyc b/linksview.pyc
new file mode 100755
index 0000000..683179d
--- /dev/null
+++ b/linksview.pyc
Binary files differ
diff --git a/setup.py b/setup.py
new file mode 100755
index 0000000..876cd3f
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,22 @@
+#!/usr/bin/python
+
+# Copyright (C) 2006, Red Hat, Inc.
+#
+# 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
+
+from sugar.activity import bundlebuilder
+
+bundlebuilder.start()
+
diff --git a/stylesheet.py b/stylesheet.py
new file mode 100755
index 0000000..3628818
--- /dev/null
+++ b/stylesheet.py
@@ -0,0 +1,27 @@
+# Copyright (C) 2006, Red Hat, Inc.
+#
+# 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 gtk
+
+from sugar.graphics import style
+
+links_Icon = {
+ 'size' : style.standard_icon_size
+}
+
+links_Box = {
+ 'background_color' : 0x414141ff,
+}
diff --git a/stylesheet.pyc b/stylesheet.pyc
new file mode 100755
index 0000000..e8e4bd9
--- /dev/null
+++ b/stylesheet.pyc
Binary files differ
diff --git a/toolbar.py b/toolbar.py
new file mode 100755
index 0000000..a516d9f
--- /dev/null
+++ b/toolbar.py
@@ -0,0 +1,148 @@
+# Copyright (C) 2006, Red Hat, Inc.
+#
+# 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 gtk
+
+from _sugar import AddressEntry
+
+class Toolbar(gtk.Toolbar):
+ def __init__(self, embed):
+ gtk.Toolbar.__init__(self)
+
+ self.set_style(gtk.TOOLBAR_BOTH_HORIZ)
+
+ self._insert_spring()
+
+ self._back = gtk.ToolButton()
+ self._back.props.sensitive = False
+ self._back.set_icon_name('stock-back')
+ self._back.connect("clicked", self._go_back_cb)
+ self.insert(self._back, -1)
+ self._back.show()
+
+ self._forward = gtk.ToolButton()
+ self._forward.props.sensitive = False
+ self._forward.set_icon_name('stock-forward')
+ self._forward.connect("clicked", self._go_forward_cb)
+ self.insert(self._forward, -1)
+ self._forward.show()
+
+ self._stop_and_reload = gtk.ToolButton()
+ self._forward.props.sensitive = False
+ self._stop_and_reload.connect("clicked", self._stop_and_reload_cb)
+ self.insert(self._stop_and_reload, -1)
+ self._stop_and_reload.show()
+
+ separator = gtk.SeparatorToolItem()
+ separator.set_draw(False)
+ self.insert(separator, -1)
+ separator.show()
+
+ address_item = gtk.ToolItem()
+
+ self._entry = AddressEntry()
+ self._entry.connect("activate", self._entry_activate_cb)
+
+ width = int(gtk.gdk.screen_width() / 1.8)
+ self._entry.set_size_request(width, -1)
+
+ address_item.add(self._entry)
+ self._entry.show()
+
+ self.insert(address_item, -1)
+ address_item.show()
+
+ separator = gtk.SeparatorToolItem()
+ separator.set_draw(False)
+ self.insert(separator, -1)
+ separator.show()
+
+ self._post = gtk.ToolButton()
+ self._post.props.sensitive = False
+ self._post.set_icon_name('stock-add')
+ self._post.connect("clicked", self._post_cb)
+ self.insert(self._post, -1)
+ self._post.show()
+
+ self._insert_spring()
+
+ self._embed = embed
+ self._embed.connect("notify::progress", self._progress_changed_cb)
+ self._embed.connect("notify::loading", self._loading_changed_cb)
+ self._embed.connect("notify::address", self._address_changed_cb)
+ self._embed.connect("notify::title", self._title_changed_cb)
+ self._embed.connect("notify::can-go-back",
+ self._can_go_back_changed_cb)
+ self._embed.connect("notify::can-go-forward",
+ self._can_go_forward_changed_cb)
+
+ self._update_stop_and_reload_icon()
+
+ def set_links_controller(self, links_controller):
+ self._links_controller = links_controller
+ self._post.props.sensitive = True
+
+ def _update_stop_and_reload_icon(self):
+ if self._embed.props.loading:
+ self._stop_and_reload.set_icon_name('stock-close')
+ else:
+ self._stop_and_reload.set_icon_name('stock-continue')
+
+ def _progress_changed_cb(self, embed, spec):
+ self._entry.props.progress = embed.props.progress
+
+ def _loading_changed_cb(self, embed, spec):
+ self._update_stop_and_reload_icon()
+
+ def _address_changed_cb(self, embed, spec):
+ self._entry.props.address = embed.props.address
+
+ def _title_changed_cb(self, embed, spec):
+ self._entry.props.title = embed.props.title
+
+ def _can_go_back_changed_cb(self, embed, spec):
+ self._back.props.sensitive = embed.props.can_go_back
+
+ def _can_go_forward_changed_cb(self, embed, spec):
+ self._forward.props.sensitive = embed.props.can_go_forward
+
+ def _entry_activate_cb(self, entry):
+ self._embed.load_url(entry.get_text())
+ self._embed.grab_focus()
+
+ def _go_back_cb(self, button):
+ self._embed.go_back()
+
+ def _go_forward_cb(self, button):
+ self._embed.go_forward()
+
+ def _stop_and_reload_cb(self, button):
+ if self._embed.props.loading:
+ self._embed.stop_load()
+ else:
+ self._embed.reload(0)
+
+ def _post_cb(self, button):
+ title = self._embed.get_title()
+ address = self._embed.get_location()
+ self._links_controller.post_link(title, address)
+
+ def _insert_spring(self):
+ separator = gtk.SeparatorToolItem()
+ separator.set_draw(False)
+ separator.set_expand(True)
+ self.insert(separator, -1)
+ separator.show()
diff --git a/toolbar.pyc b/toolbar.pyc
new file mode 100755
index 0000000..4e2f290
--- /dev/null
+++ b/toolbar.pyc
Binary files differ
diff --git a/webactivity.py b/webactivity.py
new file mode 100755
index 0000000..64c20f9
--- /dev/null
+++ b/webactivity.py
@@ -0,0 +1,139 @@
+# Copyright (C) 2006, Red Hat, Inc.
+#
+# 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
+
+from gettext import gettext as _
+import gtk
+import gtkmozembed
+import logging
+import dbus
+
+import _sugar
+from sugar.activity import ActivityFactory
+from sugar.activity.Activity import Activity
+from sugar.clipboard import ClipboardService
+from sugar import env
+from sugar.graphics import style
+
+import stylesheet
+from webbrowser import WebBrowser
+from toolbar import Toolbar
+from linksmodel import LinksModel
+from linksview import LinksView
+from linkscontroller import LinksController
+
+_HOMEPAGE = 'http://www.google.com'
+
+class WebActivity(Activity):
+ def __init__(self, browser=None):
+ Activity.__init__(self)
+
+ logging.debug('Starting the web activity')
+
+ self.set_title(_('Web Activity'))
+
+ vbox = gtk.VBox()
+
+ if browser:
+ self._browser = browser
+ else:
+ self._browser = WebBrowser()
+ self._browser.connect('notify::title', self._title_changed_cb)
+
+ self._links_model = LinksModel()
+ links_view = LinksView(self._links_model, self._browser)
+
+ self._toolbar = Toolbar(self._browser)
+ vbox.pack_start(self._toolbar, False)
+ self._toolbar.show()
+
+ hbox = gtk.HBox()
+
+ hbox.pack_start(links_view, False)
+ hbox.pack_start(self._browser)
+ self._browser.show()
+
+ vbox.pack_start(hbox)
+ hbox.show()
+
+ self.add(vbox)
+ vbox.show()
+
+ self._browser.load_url(_HOMEPAGE)
+
+ def _setup_links_controller(self):
+ links_controller = LinksController(self._service, self._links_model)
+ self._toolbar.set_links_controller(links_controller)
+
+ def join(self, activity_ps):
+ Activity.join(self, activity_ps)
+
+ self._setup_links_controller()
+
+ url = self._service.get_published_value('URL')
+ if url:
+ self._browser.load_url(url)
+
+ def share(self):
+ Activity.share(self)
+
+ self._setup_links_controller()
+
+ url = self._browser.get_location()
+ if url:
+ self._service.set_published_value('URL', url)
+
+ def _title_changed_cb(self, embed, pspec):
+ self.set_title(embed.props.title)
+
+def start():
+ gtkmozembed.set_profile_path(env.get_profile_path(), 'gecko')
+
+ gtkmozembed.push_startup()
+ if not _sugar.startup_browser():
+ raise "Error when initializising the web activity."
+
+ style.load_stylesheet(stylesheet)
+
+ download_manager = _sugar.get_download_manager()
+ download_manager.connect('download-started', download_started_cb)
+ download_manager.connect('download-completed', download_completed_cb)
+ download_manager.connect('download-cancelled', download_started_cb)
+ download_manager.connect('download-progress', download_progress_cb)
+
+def stop():
+ gtkmozembed.pop_startup()
+
+def download_started_cb(download_manager, download):
+ name = download.get_url().rsplit('/', 1)[1]
+
+ cbService = ClipboardService.get_instance()
+ cbService.add_object(name,
+ download.get_mime_type(),
+ download.get_file_name())
+
+def download_completed_cb(download_manager, download):
+ cbService = ClipboardService.get_instance()
+ cbService.set_object_state(download.get_file_name(), 100)
+
+def download_cancelled_cb(download_manager, download):
+ #FIXME: Needs to update the state of the object to 'download stopped'.
+ #FIXME: Will do it when we complete progress on the definition of the
+ #FIXME: clipboard API.
+ raise "Cancelling downloads still not implemented."
+
+def download_progress_cb(download_manager, download):
+ cbService = ClipboardService.get_instance()
+ cbService.set_object_state(download.get_file_name(), download.get_percent())
diff --git a/webactivity.pyc b/webactivity.pyc
new file mode 100755
index 0000000..60a55ee
--- /dev/null
+++ b/webactivity.pyc
Binary files differ
diff --git a/webbrowser.py b/webbrowser.py
new file mode 100755
index 0000000..07e807b
--- /dev/null
+++ b/webbrowser.py
@@ -0,0 +1,97 @@
+# Copyright (C) 2006, Red Hat, Inc.
+#
+# 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 gobject
+import gtk
+import logging
+
+from _sugar import Browser
+from _sugar import PushScroller
+
+class _PopupCreator(gobject.GObject):
+ __gsignals__ = {
+ 'popup-created': (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, ([])),
+ }
+
+ def __init__(self, parent_window):
+ gobject.GObject.__init__(self)
+
+ logging.debug('Creating the popup widget')
+
+ self._sized_popup = False
+ self._parent_window = parent_window
+
+ self._dialog = gtk.Window()
+ self._dialog.set_resizable(True)
+
+ self._dialog.realize()
+ self._dialog.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
+
+ self._embed = Browser()
+ self._size_to_sid = self._embed.connect('size_to', self._size_to_cb)
+ self._vis_sid = self._embed.connect('visibility', self._visibility_cb)
+
+ self._dialog.add(self._embed)
+
+ def _size_to_cb(self, embed, width, height):
+ logging.debug('Resize the popup to %d %d' % (width, height))
+ self._sized_popup = True
+ self._dialog.resize(width, height)
+
+ def _visibility_cb(self, embed, visible):
+ if visible:
+ if self._sized_popup:
+ logging.debug('Show the popup')
+ self._embed.show()
+ self._dialog.set_transient_for(self._parent_window)
+ self._dialog.show()
+ else:
+ logging.debug('Open a new activity for the popup')
+ self._dialog.remove(self._embed)
+
+ # FIXME We need a better way to handle this.
+ # It seem like a pretty special case though, I doubt
+ # other activities will need something similar.
+ from webactivity import WebActivity
+ activity = WebActivity(self._embed)
+ activity.set_type('org.laptop.WebActivity')
+
+ self._embed.disconnect(self._size_to_sid)
+ self._embed.disconnect(self._vis_sid)
+
+ self.emit('popup-created')
+
+ def get_embed(self):
+ return self._embed
+
+class WebBrowser(Browser):
+ __gtype_name__ = "SugarWebBrowser"
+
+ def __init__(self):
+ Browser.__init__(self)
+ self._popup_creators = []
+
+ def do_create_window(self):
+ popup_creator = _PopupCreator(self.get_toplevel())
+ popup_creator.connect('popup-created', self._popup_created_cb)
+
+ self._popup_creators.append(popup_creator)
+
+ return popup_creator.get_embed()
+
+ def _popup_created_cb(self, creator):
+ self._popup_creators.remove(creator)