[Sugar-devel] [PATCH Speak] Migrating from the early toolbarbox-toolkit modules to Sugar Toolkit

Rafael Ortiz rafael at activitycentral.com
Tue Jul 3 01:40:55 EDT 2012


Thanks Daniel applied as:

http://git.sugarlabs.org/speak/mainline/commit/6b9ff449e17cc7ac7327138234a72b1066202c18



On 7/1/12, Daniel Francis <francis at sugarlabs.org> wrote:
> This little patch is the second step in the Gtk3 migration.
> Here I remove some few unnecesary files always when it was possible, and use
> Sugar Toolkit.
> The purpose is to prevent a headache at the time of porting to Gtk3 the
> activity, and of course remove some useless kilobytes and not having written
> the same code twice.
>
> I also modified the .gitignore file, I didn't type 'git add .gitignore'
> previous than my commit so I didn't expect it would appear in my patch, I
> think git has its own life :) , but anyway, is better having a correct
> .gitignore .
>
> Signed-off-by: Daniel Francis <francis at sugarlabs.org>
> ---
>  .gitignore                         |    6 +-
>  activity.py                        |   86 +++-
>  brain.py                           |    4 +-
>  combobox.py                        |  201 ++++++++
>  shared_activity.py                 |  115 +++++
>  toolitem.py                        |   77 +++
>  toolkit/__init__.py                |   16 -
>  toolkit/activity.py                |  331 ------------
>  toolkit/activity_widgets.py        |  397 ---------------
>  toolkit/chooser.py                 |   69 ---
>  toolkit/combobox.py                |  201 --------
>  toolkit/internals/__init__.py      |   16 -
>  toolkit/internals/palettewindow.py |  976
> ------------------------------------
>  toolkit/json.py                    |   35 --
>  toolkit/pixbuf.py                  |  116 -----
>  toolkit/radiopalette.py            |  109 ----
>  toolkit/scrolledbox.py             |  191 -------
>  toolkit/tarball.py                 |  125 -----
>  toolkit/temposlider.py             |  211 --------
>  toolkit/toolbarbox.py              |  333 ------------
>  toolkit/toolitem.py                |   79 ---
>  21 files changed, 479 insertions(+), 3215 deletions(-)
>  create mode 100644 combobox.py
>  create mode 100644 shared_activity.py
>  create mode 100644 toolitem.py
>  delete mode 100644 toolkit/__init__.py
>  delete mode 100644 toolkit/activity.py
>  delete mode 100644 toolkit/activity_widgets.py
>  delete mode 100644 toolkit/chooser.py
>  delete mode 100644 toolkit/combobox.py
>  delete mode 100644 toolkit/internals/__init__.py
>  delete mode 100644 toolkit/internals/palettewindow.py
>  delete mode 100644 toolkit/json.py
>  delete mode 100644 toolkit/pixbuf.py
>  delete mode 100644 toolkit/radiopalette.py
>  delete mode 100644 toolkit/scrolledbox.py
>  delete mode 100644 toolkit/tarball.py
>  delete mode 100644 toolkit/temposlider.py
>  delete mode 100644 toolkit/toolbarbox.py
>  delete mode 100644 toolkit/toolitem.py
>
> diff --git a/.gitignore b/.gitignore
> index b9cb894..1e4c0c4 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -1,2 +1,4 @@
> -dist
> -.0sugar
> +*.pyc
> +*.pyo
> +*.mo
> +*~
> diff --git a/activity.py b/activity.py
> index a044423..a3f01ac 100644
> --- a/activity.py
> +++ b/activity.py
> @@ -31,16 +31,17 @@ import pango
>  import cjson
>  from gettext import gettext as _
>
> -from sugar.graphics.toolbutton import ToolButton
> +from sugar.graphics.toolbarbox import ToolbarButton
>  from sugar.graphics.toggletoolbutton import ToggleToolButton
>  from sugar.graphics.radiotoolbutton import RadioToolButton
>
> -from toolkit.toolitem import ToolWidget
> -from toolkit.combobox import ComboBox
> -from toolkit.toolbarbox import ToolbarBox
> -from toolkit.activity import SharedActivity
> -from toolkit.activity_widgets import *
> +from combobox import ComboBox
> +from sugar.graphics.toolbarbox import ToolbarBox
> +from shared_activity import SharedActivity
> +from sugar.activity.widgets import ActivityToolbarButton
> +from sugar.activity.widgets import StopButton
>
> +from toolitem import ToolWidget
>  import eye
>  import glasses
>  import mouth
> @@ -59,13 +60,39 @@ MODE_TYPE = 1
>  MODE_BOT = 2
>  MODE_CHAT = 3
>
> +_NEW_INSTANCE = 0
> +_NEW_INSTANCE = 1
> +_PRE_INSTANCE = 2
> +_POST_INSTANCE = 3
> +
> +
> +class CursorFactory:
> +
> +    __shared_state = {"cursors": {}}
> +
> +    def __init__(self):
> +        self.__dict__ = self.__shared_state
> +
> +    def get_cursor(self, cur_type):
> +        if not cur_type in self.cursors:
> +            cur = gtk.gdk.Cursor(cur_type)
> +            self.cursors[cur_type] = cur
> +        return self.cursors[cur_type]
> +
>
>  class SpeakActivity(SharedActivity):
>      def __init__(self, handle):
>          self.notebook = gtk.Notebook()
> +        self.notebook.connect_after('map', self.__map_canvasactivity_cb)
>
>          SharedActivity.__init__(self, self.notebook, SERVICE, handle)
>
> +        self._cursor = None
> +        self.set_cursor(gtk.gdk.LEFT_PTR)
> +        self.__resume_filename = None
> +        self.__postponed_share = []
> +        self.__on_save_instance = []
> +        self.__state = _NEW_INSTANCE
>          self._mode = MODE_TYPE
>          self.numeyesadj = None
>
> @@ -176,6 +203,53 @@ class SpeakActivity(SharedActivity):
>          toolbox.show_all()
>          self.toolbar_box = toolbox
>
> +    def set_cursor(self, cursor):
> +        if not isinstance(cursor, gtk.gdk.Cursor):
> +            cursor = CursorFactory().get_cursor(cursor)
> +
> +        if self._cursor != cursor:
> +            self._cursor = cursor
> +            self.window.set_cursor(self._cursor)
> +
> +    def __map_canvasactivity_cb(self, widget):
> +        logging.debug('Activity.__map_canvasactivity_cb state=%s' % \
> +                self.__state)
> +
> +        if self.__state == _NEW_INSTANCE:
> +            self.__instance()
> +        elif self.__state == _NEW_INSTANCE:
> +            self.__state = _PRE_INSTANCE
> +        elif self.__state == _PRE_INSTANCE:
> +            self.__instance()
> +
> +        return False
> +
> +    def __instance(self):
> +        logging.debug('Activity.__instance')
> +
> +        if self.__resume_filename:
> +            self.resume_instance(self.__resume_filename)
> +        else:
> +            self.new_instance()
> +
> +        for i in self.__postponed_share:
> +            self.share_instance(*i)
> +        self.__postponed_share = []
> +
> +        self.__state = _POST_INSTANCE
> +
> +    def read_file(self, file_path):
> +        self.__resume_filename = file_path
> +        if self.__state == _NEW_INSTANCE:
> +            self.__state = _PRE_INSTANCE
> +        elif self.__state == _PRE_INSTANCE:
> +            self.__instance()
> +
> +    def write_file(self, file_path):
> +        for cb, args in self.__on_save_instance:
> +            cb(*args)
> +        self.save_instance(file_path)
> +
>      def new_instance(self):
>          self.voices.connect('changed', self.__changed_voices_cb)
>          self.pitchadj.connect("value_changed", self.pitch_adjusted_cb,
> diff --git a/brain.py b/brain.py
> index 8a7d5e7..d98578f 100644
> --- a/brain.py
> +++ b/brain.py
> @@ -26,7 +26,7 @@ from gettext import gettext as _
>  import logging
>  logger = logging.getLogger('speak')
>
> -from toolkit.combobox import ComboBox
> +from combobox import ComboBox
>
>  import aiml
>  import voice
> @@ -86,7 +86,7 @@ def load(activity, voice, sorry=None):
>      if voice == _kernel_voice:
>          return False
>
> -    old_cursor = activity.get_cursor()
> +    old_cursor = activity._cursor
>      activity.set_cursor(gtk.gdk.WATCH)
>
>      def load_brain():
> diff --git a/combobox.py b/combobox.py
> new file mode 100644
> index 0000000..d021106
> --- /dev/null
> +++ b/combobox.py
> @@ -0,0 +1,201 @@
> +# Copyright (C) 2007, One Laptop Per Child
> +# Copyright (C) 2009, Aleksey Lim
> +#
> +# 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.
> +
> +"""
> +STABLE.
> +"""
> +
> +import gobject
> +import gtk
> +
> +
> +class ComboBox(gtk.ComboBox):
> +
> +    def __init__(self):
> +        gtk.ComboBox.__init__(self)
> +
> +        self._text_renderer = None
> +        self._icon_renderer = None
> +
> +        model = gtk.ListStore(gobject.TYPE_PYOBJECT,
> +                                    gobject.TYPE_STRING,
> +                                    gtk.gdk.Pixbuf,
> +                                    gobject.TYPE_BOOLEAN)
> +        self.set_model(model)
> +
> +        self.set_row_separator_func(self._is_separator)
> +
> +    def get_value(self):
> +        """
> +        Parameters
> +        ----------
> +        None :
> +
> +        Returns:
> +        --------
> +        value :
> +
> +        """
> +        row = self.get_active_item()
> +        if not row:
> +            return None
> +        return row[0]
> +
> +    value = gobject.property(
> +        type=object, getter=get_value, setter=None)
> +
> +    def _get_real_name_from_theme(self, name, size):
> +        icon_theme = gtk.icon_theme_get_default()
> +        width, height = gtk.icon_size_lookup(size)
> +        info = icon_theme.lookup_icon(name, max(width, height), 0)
> +        if not info:
> +            raise ValueError("Icon '" + name + "' not found.")
> +        fname = info.get_filename()
> +        del info
> +        return fname
> +
> +    def append_item(self, action_id, text, icon_name=None,
> file_name=None):
> +        """
> +        Parameters
> +        ----------
> +        action_id :
> +
> +        text :
> +
> +        icon_name=None :
> +
> +        file_name=None :
> +
> +        Returns
> +        -------
> +        None
> +
> +        """
> +        item = self._item_new(action_id, text, icon_name, file_name)
> +        self.get_model().append(item)
> +
> +    def set_item(self, action_id, text=None, icon_name=None,
> file_name=None):
> +        for i, value in enumerate(self.get_model()):
> +            if value[0] == action_id:
> +                item = self._item_new(action_id, text, icon_name,
> file_name)
> +                iter = self.get_model().iter_nth_child(None, i)
> +                if text is not None:
> +                    self.get_model().set(iter, 1, item[1])
> +                if icon_name is not None or file_name is not None:
> +                    self.get_model().set(iter, 2, item[2])
> +                return True
> +        return False
> +
> +    def select(self, action_id=None, text=None):
> +        if action_id is not None:
> +            column = 0
> +            value = action_id
> +        elif text is not None:
> +            column = 1
> +            value = text
> +        else:
> +            return
> +
> +        for i, item in enumerate(self.get_model()):
> +            if item[column] != value:
> +                continue
> +            self.set_active(i)
> +            break
> +
> +    def _item_new(self, action_id, text, icon_name, file_name):
> +        if not self._icon_renderer and (icon_name or file_name):
> +            self._icon_renderer = gtk.CellRendererPixbuf()
> +
> +            settings = self.get_settings()
> +            w, h = gtk.icon_size_lookup_for_settings(
> +                                            settings, gtk.ICON_SIZE_MENU)
> +            self._icon_renderer.props.stock_size = max(w, h)
> +
> +            self.pack_start(self._icon_renderer, False)
> +            self.add_attribute(self._icon_renderer, 'pixbuf', 2)
> +
> +        if not self._text_renderer and text:
> +            self._text_renderer = gtk.CellRendererText()
> +            self.pack_end(self._text_renderer, True)
> +            self.add_attribute(self._text_renderer, 'text', 1)
> +
> +        if icon_name or file_name:
> +            if text:
> +                size = gtk.ICON_SIZE_MENU
> +            else:
> +                size = gtk.ICON_SIZE_LARGE_TOOLBAR
> +            width, height = gtk.icon_size_lookup(size)
> +
> +            if icon_name:
> +                file_name = self._get_real_name_from_theme(icon_name,
> size)
> +
> +            pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(
> +                                                file_name, width, height)
> +        else:
> +            pixbuf = None
> +
> +        return (action_id, text, pixbuf, False)
> +
> +    def append_separator(self):
> +        """
> +        Parameters
> +        ----------
> +        None
> +
> +        Returns
> +        -------
> +        None
> +
> +        """
> +        self.get_model().append([0, None, None, True])
> +
> +    def get_active_item(self):
> +        """
> +        Parameters
> +        ----------
> +        None
> +
> +        Returns
> +        -------
> +        Active_item :
> +
> +        """
> +        index = self.get_active()
> +        if index == -1:
> +            index = 0
> +
> +        row = self.get_model().iter_nth_child(None, index)
> +        if not row:
> +            return None
> +        return self.get_model()[row]
> +
> +    def remove_all(self):
> +        """
> +        Parameters
> +        ----------
> +        None
> +
> +        Returns
> +        -------
> +        None
> +
> +        """
> +        self.get_model().clear()
> +
> +    def _is_separator(self, model, row):
> +        return model[row][3]
> diff --git a/shared_activity.py b/shared_activity.py
> new file mode 100644
> index 0000000..a537958
> --- /dev/null
> +++ b/shared_activity.py
> @@ -0,0 +1,115 @@
> +# Copyright (C) 2009, Aleksey Lim
> +#
> +# 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
> +
> +"""Extend sugar-toolkit activity class"""
> +
> +import logging
> +import telepathy
> +
> +from sugar.activity import activity
> +from sugar.presence.sugartubeconn import SugarTubeConnection
> +
> +
> +class SharedActivity(activity.Activity):
> +    """Basic activity class with sharing features"""
> +
> +    def __init__(self, canvas, service, handle):
> +        """
> +        Initialise the Activity.
> +
> +        canvas -- gtk.Widget
> +            root widget for activity content
> +
> +        service -- string
> +            dbus service for activity
> +
> +        handle -- sugar.activity.activityhandle.ActivityHandle
> +            instance providing the activity id and access to the
> +            presence service which *may* provide sharing for this
> +            application
> +
> +        """
> +        activity.Activity.__init__(self, handle)
> +        self.set_canvas(canvas)
> +        self.service = service
> +
> +        self.connect('shared', self._shared_cb)
> +
> +        # Owner.props.key
> +        if self._shared_activity:
> +            # We are joining the activity
> +            self.connect('joined', self._joined_cb)
> +            if self.get_shared():
> +                # We've already joined
> +                self._joined_cb()
> +
> +    def _shared_cb(self, activity):
> +        logging.debug('My activity was shared')
> +        self.__initiator = True
> +        self._sharing_setup()
> +
> +        logging.debug('This is my activity: making a tube...')
> +        self._tubes_chan[telepathy.CHANNEL_TYPE_TUBES].OfferDBusTube(
> +                                                            self.service,
> {})
> +
> +    def _joined_cb(self, activity):
> +        if not self._shared_activity:
> +            return
> +
> +        logging.debug('Joined an existing shared activity')
> +
> +        self.__initiator = False
> +        self._sharing_setup()
> +
> +        logging.debug('This is not my activity: waiting for a tube...')
> +        self._tubes_chan[telepathy.CHANNEL_TYPE_TUBES].ListTubes(
> +            reply_handler=self._list_tubes_reply_cb,
> +            error_handler=self._list_tubes_error_cb)
> +
> +    def _sharing_setup(self):
> +        if self._shared_activity is None:
> +            logging.error('Failed to share or join activity')
> +            return
> +        self._conn = self._shared_activity.telepathy_conn
> +        self._tubes_chan = self._shared_activity.telepathy_tubes_chan
> +        self._text_chan = self._shared_activity.telepathy_text_chan
> +
> +        self._tubes_chan[telepathy.CHANNEL_TYPE_TUBES].connect_to_signal(
> +                'NewTube', self._new_tube_cb)
> +
> +    def _list_tubes_reply_cb(self, tubes):
> +        for tube_info in tubes:
> +            self._new_tube_cb(*tube_info)
> +
> +    def _list_tubes_error_cb(self, e):
> +        logging.error('ListTubes() failed: %s', e)
> +
> +    def _new_tube_cb(self, id, initiator, type, service, params, state):
> +        logging.debug('New tube: ID=%d initator=%d type=%d service=%s '
> +                     'params=%r state=%d', id, initiator, type, service,
> +                     params, state)
> +
> +        if (type == telepathy.TUBE_TYPE_DBUS and
> +                service == self.service):
> +            if state == telepathy.TUBE_STATE_LOCAL_PENDING:
> +                self._tubes_chan[telepathy.CHANNEL_TYPE_TUBES] \
> +                        .AcceptDBusTube(id)
> +
> +            tube_conn = SugarTubeConnection(self._conn,
> +                self._tubes_chan[telepathy.CHANNEL_TYPE_TUBES], id,
> +
> group_iface=self._text_chan[telepathy.CHANNEL_INTERFACE_GROUP])
> +
> +            self._share(tube_conn, self.__initiator)
> diff --git a/toolitem.py b/toolitem.py
> new file mode 100644
> index 0000000..1f4ee49
> --- /dev/null
> +++ b/toolitem.py
> @@ -0,0 +1,77 @@
> +# Copyright (C) 2009, Aleksey Lim
> +#
> +# 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.
> +
> +"""A set of toolitem widets"""
> +
> +import gtk
> +import gobject
> +
> +from sugar.graphics import style
> +
> +
> +class ToolWidget(gtk.ToolItem):
> +
> +    def __init__(self, **kwargs):
> +        self._widget = None
> +        self._label = None
> +        self._label_text = None
> +        self._box = gtk.HBox(False, style.DEFAULT_SPACING)
> +
> +        gobject.GObject.__init__(self, **kwargs)
> +        self.props.border_width = style.DEFAULT_PADDING
> +
> +        self._box.show()
> +        self.add(self._box)
> +
> +        if self.label is None:
> +            self.label = gtk.Label()
> +
> +    def get_label_text(self):
> +        return self._label_text
> +
> +    def set_label_text(self, value):
> +        self._label_text = value
> +        if self.label is not None and value:
> +            self.label.set_text(self._label_text)
> +
> +    label_text = gobject.property(getter=get_label_text,
> setter=set_label_text)
> +
> +    def get_label(self):
> +        return self._label
> +
> +    def set_label(self, label):
> +        if self._label is not None:
> +            self._box.remove(self._label)
> +        self._label = label
> +        self._box.pack_start(label, False)
> +        self._box.reorder_child(label, 0)
> +        label.show()
> +        self.set_label_text(self._label_text)
> +
> +    label = gobject.property(getter=get_label, setter=set_label)
> +
> +    def get_widget(self):
> +        return self._widget
> +
> +    def set_widget(self, widget):
> +        if self._widget is not None:
> +            self._box.remove(self._widget)
> +        self._widget = widget
> +        self._box.pack_end(widget)
> +        widget.show()
> +
> +    widget = gobject.property(getter=get_widget, setter=set_widget)
> diff --git a/toolkit/__init__.py b/toolkit/__init__.py
> deleted file mode 100644
> index 17a92ac..0000000
> --- a/toolkit/__init__.py
> +++ /dev/null
> @@ -1,16 +0,0 @@
> -# Copyright (C) 2009, Aleksey Lim
> -#
> -# 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.
> diff --git a/toolkit/activity.py b/toolkit/activity.py
> deleted file mode 100644
> index 1512610..0000000
> --- a/toolkit/activity.py
> +++ /dev/null
> @@ -1,331 +0,0 @@
> -# Copyright (C) 2009, Aleksey Lim
> -#
> -# 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
> -
> -"""Extend sugar-toolkit activity class"""
> -
> -import gtk
> -import logging
> -import telepathy
> -import gobject
> -
> -from sugar.activity import activity
> -from sugar.presence.sugartubeconn import SugarTubeConnection
> -from sugar.graphics.alert import ConfirmationAlert, NotifyAlert
> -
> -
> -_NEW_INSTANCE   = 0
> -_NEW_INSTANCE   = 1
> -_PRE_INSTANCE   = 2
> -_POST_INSTANCE  = 3
> -
> -
> -class CursorFactory:
> -
> -    __shared_state = {"cursors": {}}
> -
> -    def __init__(self):
> -        self.__dict__ = self.__shared_state
> -
> -    def get_cursor(self, cur_type):
> -        if not self.cursors.has_key(cur_type):
> -            cur = gtk.gdk.Cursor(cur_type)
> -            self.cursors[cur_type] = cur
> -        return self.cursors[cur_type]
> -
> -
> -class Activity(activity.Activity):
> -
> -    """Basic activity class"""
> -
> -    def new_instance(self):
> -        """
> -        New instance was created.
> -
> -        Will be invoked after __init__() instead of resume_instance().
> -        Subclass should implement this method to catch creation stage.
> -        """
> -        pass
> -
> -    def resume_instance(self, filepath):
> -        """
> -        Instance was resumed.
> -
> -        Will be invoked after __init__() instead of new_instance().
> -        Subclass should implement this method to catch resuming stage.
> -
> -        """
> -        pass
> -
> -    def save_instance(self, filepath):
> -        """
> -        Save activity instance.
> -
> -        Subclass should implement this method to save activity data.
> -        """
> -        raise NotImplementedError
> -
> -    def on_save_instance(self, cb, *args):
> -        """ Register callback which will be invoked before save_instance
> """
> -        self.__on_save_instance.append((cb, args))
> -
> -    def share_instance(self, connection, is_initiator):
> -        """
> -        Activity was shared/joined.
> -
> -        connection -- SugarTubeConnection object
> -            wich represents telepathy connection
> -
> -        is_initiator -- boolean
> -            if True activity was shared and
> -            (current activity is an initiator of sharing)
> -            otherwise activity was joined(to existed sharing session)
> -
> -        Will be invoked after __init__() and {new,resume}_instance().
> -        Subclass should implement this method to catch sharing stage.
> -        """
> -        pass
> -
> -    def set_toolbar_box(self, toolbox):
> -        if hasattr(activity.Activity, 'set_toolbar_box'):
> -            activity.Activity.set_toolbar_box(self, toolbox)
> -        else:
> -            self.set_toolbox(toolbox)
> -
> -    def get_toolbar_box(self):
> -        if hasattr(activity.Activity, 'get_toolbar_box'):
> -            return activity.Activity.get_toolbar_box(self)
> -        else:
> -            return self.get_toolbox()
> -
> -    toolbar_box = property(get_toolbar_box, set_toolbar_box)
> -
> -    def get_shared_activity(self):
> -        if hasattr(activity.Activity, 'get_shared_activity'):
> -            return activity.Activity.get_shared_activity(self)
> -        else:
> -            return self._shared_activity
> -
> -    def notify_alert(self, title, msg):
> -        """Raise standard notify alert"""
> -        alert = NotifyAlert(title=title, msg=msg)
> -
> -        def response(alert, response_id, self):
> -            self.remove_alert(alert)
> -
> -        alert.connect('response', response, self)
> -        alert.show_all()
> -        self.add_alert(alert)
> -
> -    def confirmation_alert(self, title, msg, cb, *cb_args):
> -        """Raise standard confirmation alert"""
> -        alert = ConfirmationAlert(title=title, msg=msg)
> -
> -        def response(alert, response_id, self, cb, *cb_args):
> -            self.remove_alert(alert)
> -            if response_id is gtk.RESPONSE_OK:
> -                cb(*cb_args)
> -
> -        alert.connect('response', response, self, cb, *cb_args)
> -        alert.show_all()
> -        self.add_alert(alert)
> -
> -    def get_cursor(self):
> -        return self._cursor
> -
> -    def set_cursor(self, cursor):
> -        if not isinstance(cursor, gtk.gdk.Cursor):
> -            cursor = CursorFactory().get_cursor(cursor)
> -
> -        if self._cursor != cursor:
> -            self._cursor = cursor
> -            self.window.set_cursor(self._cursor)
> -
> -    def __init__(self, canvas, handle):
> -        """
> -        Initialise the Activity.
> -
> -        canvas -- gtk.Widget
> -            root widget for activity content
> -
> -        handle -- sugar.activity.activityhandle.ActivityHandle
> -            instance providing the activity id and access to the
> -
> -        """
> -        activity.Activity.__init__(self, handle)
> -
> -        if handle.object_id:
> -            self.__state = _NEW_INSTANCE
> -        else:
> -            self.__state = _NEW_INSTANCE
> -
> -        self.__resume_filename = None
> -        self.__postponed_share = []
> -        self.__on_save_instance = []
> -
> -        self._cursor = None
> -        self.set_cursor(gtk.gdk.LEFT_PTR)
> -
> -        # XXX do it after(possible) read_file() invoking
> -        # have to rely on calling read_file() from map_cb in sugar-toolkit
> -        canvas.connect_after('map', self.__map_canvasactivity_cb)
> -        self.set_canvas(canvas)
> -
> -    def __instance(self):
> -        logging.debug('Activity.__instance')
> -
> -        if self.__resume_filename:
> -            self.resume_instance(self.__resume_filename)
> -        else:
> -            self.new_instance()
> -
> -        for i in self.__postponed_share:
> -            self.share_instance(*i)
> -        self.__postponed_share = []
> -
> -        self.__state = _POST_INSTANCE
> -
> -    def read_file(self, filepath):
> -        """Subclass should not override this method"""
> -        logging.debug('Activity.read_file state=%s' % self.__state)
> -
> -        self.__resume_filename = filepath
> -
> -        if self.__state == _NEW_INSTANCE:
> -            self.__state = _PRE_INSTANCE
> -        elif self.__state == _PRE_INSTANCE:
> -            self.__instance();
> -
> -    def write_file(self, filepath):
> -        """Subclass should not override this method"""
> -        for cb, args in self.__on_save_instance:
> -            cb(*args)
> -        self.save_instance(filepath)
> -
> -    def __map_canvasactivity_cb(self, widget):
> -        logging.debug('Activity.__map_canvasactivity_cb state=%s' % \
> -                self.__state)
> -
> -        if self.__state == _NEW_INSTANCE:
> -            self.__instance()
> -        elif self.__state == _NEW_INSTANCE:
> -            self.__state = _PRE_INSTANCE
> -        elif self.__state == _PRE_INSTANCE:
> -            self.__instance();
> -
> -        return False
> -
> -    def _share(self, tube_conn, initiator):
> -        logging.debug('Activity._share state=%s' % self.__state)
> -
> -        if self.__state == _NEW_INSTANCE:
> -            self.__postponed_share.append((tube_conn, initiator))
> -            self.__state = _PRE_INSTANCE
> -        elif self.__state == _PRE_INSTANCE:
> -            self.__postponed_share.append((tube_conn, initiator))
> -            self.__instance();
> -        elif self.__state == _POST_INSTANCE:
> -            self.share_instance(tube_conn, initiator)
> -
> -
> -class SharedActivity(Activity):
> -    """Basic activity class with sharing features"""
> -
> -    def __init__(self, canvas, service, handle):
> -        """
> -        Initialise the Activity.
> -
> -        canvas -- gtk.Widget
> -            root widget for activity content
> -
> -        service -- string
> -            dbus service for activity
> -
> -        handle -- sugar.activity.activityhandle.ActivityHandle
> -            instance providing the activity id and access to the
> -            presence service which *may* provide sharing for this
> -            application
> -
> -        """
> -        Activity.__init__(self, canvas, handle)
> -        self.service = service
> -
> -        self.connect('shared', self._shared_cb)
> -
> -        # Owner.props.key
> -        if self._shared_activity:
> -            # We are joining the activity
> -            self.connect('joined', self._joined_cb)
> -            if self.get_shared():
> -                # We've already joined
> -                self._joined_cb()
> -
> -    def _shared_cb(self, activity):
> -        logging.debug('My activity was shared')
> -        self.__initiator = True
> -        self._sharing_setup()
> -
> -        logging.debug('This is my activity: making a tube...')
> -        id = self._tubes_chan[telepathy.CHANNEL_TYPE_TUBES].OfferDBusTube(
> -            self.service, {})
> -
> -    def _joined_cb(self, activity):
> -        if not self._shared_activity:
> -            return
> -
> -        logging.debug('Joined an existing shared activity')
> -
> -        self.__initiator = False
> -        self._sharing_setup()
> -
> -        logging.debug('This is not my activity: waiting for a tube...')
> -        self._tubes_chan[telepathy.CHANNEL_TYPE_TUBES].ListTubes(
> -            reply_handler=self._list_tubes_reply_cb,
> -            error_handler=self._list_tubes_error_cb)
> -
> -    def _sharing_setup(self):
> -        if self._shared_activity is None:
> -            logging.error('Failed to share or join activity')
> -            return
> -        self._conn = self._shared_activity.telepathy_conn
> -        self._tubes_chan = self._shared_activity.telepathy_tubes_chan
> -        self._text_chan = self._shared_activity.telepathy_text_chan
> -
> -        self._tubes_chan[telepathy.CHANNEL_TYPE_TUBES].connect_to_signal(
> -                'NewTube', self._new_tube_cb)
> -
> -    def _list_tubes_reply_cb(self, tubes):
> -        for tube_info in tubes:
> -            self._new_tube_cb(*tube_info)
> -
> -    def _list_tubes_error_cb(self, e):
> -        logging.error('ListTubes() failed: %s', e)
> -
> -    def _new_tube_cb(self, id, initiator, type, service, params, state):
> -        logging.debug('New tube: ID=%d initator=%d type=%d service=%s '
> -                     'params=%r state=%d', id, initiator, type, service,
> -                     params, state)
> -
> -        if (type == telepathy.TUBE_TYPE_DBUS and
> -                service == self.service):
> -            if state == telepathy.TUBE_STATE_LOCAL_PENDING:
> -                self._tubes_chan[telepathy.CHANNEL_TYPE_TUBES] \
> -                        .AcceptDBusTube(id)
> -
> -            tube_conn = SugarTubeConnection(self._conn,
> -                self._tubes_chan[telepathy.CHANNEL_TYPE_TUBES], id,
> -
> group_iface=self._text_chan[telepathy.CHANNEL_INTERFACE_GROUP])
> -
> -            self._share(tube_conn, self.__initiator)
> diff --git a/toolkit/activity_widgets.py b/toolkit/activity_widgets.py
> deleted file mode 100644
> index 9195af5..0000000
> --- a/toolkit/activity_widgets.py
> +++ /dev/null
> @@ -1,397 +0,0 @@
> -# Copyright (C) 2009, Aleksey Lim, Simon Schampijer
> -#
> -# 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 gtk
> -import gobject
> -import gettext
> -
> -from sugar import profile
> -from sugar.graphics.toolbutton import ToolButton
> -from sugar.graphics.radiotoolbutton import RadioToolButton
> -from sugar.graphics.toolbox import Toolbox
> -from sugar.graphics.xocolor import XoColor
> -from sugar.graphics.icon import Icon
> -from sugar.bundle.activitybundle import ActivityBundle
> -
> -from toolkit.toolbarbox import ToolbarButton
> -from toolkit.radiopalette import RadioPalette
> -from toolkit.radiopalette import RadioMenuButton
> -from sugar.graphics import style
> -
> -_ = lambda msg: gettext.dgettext('sugar-toolkit', msg)
> -
> -
> -def _create_activity_icon(metadata):
> -    if metadata.get('icon-color', ''):
> -        color = XoColor(metadata['icon-color'])
> -    else:
> -        color = profile.get_color()
> -
> -    from sugar.activity.activity import get_bundle_path
> -    bundle = ActivityBundle(get_bundle_path())
> -    icon = Icon(file=bundle.get_icon(), xo_color=color)
> -
> -    return icon
> -
> -
> -class ActivityButton(ToolButton):
> -
> -    def __init__(self, activity, **kwargs):
> -        ToolButton.__init__(self, **kwargs)
> -
> -        icon = _create_activity_icon(activity.metadata)
> -        self.set_icon_widget(icon)
> -        icon.show()
> -
> -        self.props.tooltip = activity.metadata['title']
> -        activity.metadata.connect('updated', self.__jobject_updated_cb)
> -
> -    def __jobject_updated_cb(self, jobject):
> -        self.props.tooltip = jobject['title']
> -
> -
> -class ActivityToolbarButton(ToolbarButton):
> -
> -    def __init__(self, activity, **kwargs):
> -        toolbar = ActivityToolbar(activity, orientation_left=True)
> -        toolbar.stop.hide()
> -
> -        ToolbarButton.__init__(self, page=toolbar, **kwargs)
> -
> -        icon = _create_activity_icon(activity.metadata)
> -        self.set_icon_widget(icon)
> -        icon.show()
> -
> -
> -class StopButton(ToolButton):
> -
> -    def __init__(self, activity, **kwargs):
> -        ToolButton.__init__(self, 'activity-stop', **kwargs)
> -        self.props.tooltip = _('Stop')
> -        self.props.accelerator = '<Ctrl>Q'
> -        self.connect('clicked', self.__stop_button_clicked_cb, activity)
> -
> -    def __stop_button_clicked_cb(self, button, activity):
> -        activity.close()
> -
> -
> -class UndoButton(ToolButton):
> -
> -    def __init__(self, **kwargs):
> -        ToolButton.__init__(self, 'edit-undo', **kwargs)
> -        self.props.tooltip = _('Undo')
> -        self.props.accelerator = '<Ctrl>Z'
> -
> -
> -class RedoButton(ToolButton):
> -
> -    def __init__(self, **kwargs):
> -        ToolButton.__init__(self, 'edit-redo', **kwargs)
> -        self.props.tooltip = _('Redo')
> -
> -
> -class CopyButton(ToolButton):
> -
> -    def __init__(self, **kwargs):
> -        ToolButton.__init__(self, 'edit-copy', **kwargs)
> -        self.props.tooltip = _('Copy')
> -
> -
> -class PasteButton(ToolButton):
> -
> -    def __init__(self, **kwargs):
> -        ToolButton.__init__(self, 'edit-paste', **kwargs)
> -        self.props.tooltip = _('Paste')
> -
> -
> -class ShareButton(RadioMenuButton):
> -
> -    def __init__(self, activity, **kwargs):
> -        palette = RadioPalette()
> -
> -        self.private = RadioToolButton(
> -                icon_name='zoom-home')
> -        palette.append(self.private, _('Private'))
> -
> -        self.neighborhood = RadioToolButton(
> -                icon_name='zoom-neighborhood',
> -                group=self.private)
> -        self._neighborhood_handle = self.neighborhood.connect(
> -                'clicked', self.__neighborhood_clicked_cb, activity)
> -        palette.append(self.neighborhood, _('My Neighborhood'))
> -
> -        activity.connect('shared', self.__update_share_cb)
> -        activity.connect('joined', self.__update_share_cb)
> -
> -        RadioMenuButton.__init__(self, **kwargs)
> -        self.props.palette = palette
> -        if activity.props.max_participants == 1:
> -            self.props.sensitive = False
> -
> -    def __neighborhood_clicked_cb(self, button, activity):
> -        activity.share()
> -
> -    def __update_share_cb(self, activity):
> -        self.neighborhood.handler_block(self._neighborhood_handle)
> -        try:
> -            if activity.get_shared():
> -                self.private.props.sensitive = False
> -                self.neighborhood.props.sensitive = False
> -                self.neighborhood.props.active = True
> -            else:
> -                self.private.props.sensitive = True
> -                self.neighborhood.props.sensitive = True
> -                self.private.props.active = True
> -        finally:
> -            self.neighborhood.handler_unblock(self._neighborhood_handle)
> -
> -
> -class TitleEntry(gtk.ToolItem):
> -
> -    def __init__(self, activity, **kwargs):
> -        gtk.ToolItem.__init__(self)
> -        self.set_expand(False)
> -        self._update_title_sid = None
> -
> -        self.entry = gtk.Entry(**kwargs)
> -        self.entry.set_size_request(int(gtk.gdk.screen_width() / 3), -1)
> -        self.entry.set_text(activity.metadata['title'])
> -        self.entry.connect('changed', self.__title_changed_cb, activity)
> -        self.entry.show()
> -        self.add(self.entry)
> -
> -        activity.metadata.connect('updated', self.__jobject_updated_cb)
> -
> -    def modify_bg(self, state, color):
> -        gtk.ToolItem.modify_bg(self, state, color)
> -        self.entry.modify_bg(state, color)
> -
> -    def __jobject_updated_cb(self, jobject):
> -        self.entry.set_text(jobject['title'])
> -
> -    def __title_changed_cb(self, entry, activity):
> -        if not self._update_title_sid:
> -            self._update_title_sid = gobject.timeout_add_seconds(
> -                    1, self.__update_title_cb, activity)
> -
> -    def __update_title_cb(self, activity):
> -        title = self.entry.get_text()
> -
> -        activity.metadata['title'] = title
> -        activity.metadata['title_set_by_user'] = '1'
> -        activity.save()
> -
> -        shared_activity = activity.get_shared_activity()
> -        if shared_activity is not None:
> -            shared_activity.props.name = title
> -
> -        self._update_title_sid = None
> -        return False
> -
> -
> -class DescriptionItem(gtk.ToolItem):
> -
> -    def __init__(self, activity, **kwargs):
> -        gtk.ToolItem.__init__(self)
> -
> -        description_button = ToolButton('edit-description')
> -        description_button.show()
> -        description_button.set_tooltip(_('Description'))
> -        self._palette = description_button.get_palette()
> -
> -        description_box = gtk.HBox()
> -        sw = gtk.ScrolledWindow()
> -        sw.set_size_request(int(gtk.gdk.screen_width() / 2),
> -                            2 * style.GRID_CELL_SIZE)
> -        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
> -        self._text_view = gtk.TextView()
> -        self._text_view.set_left_margin(style.DEFAULT_PADDING)
> -        self._text_view.set_right_margin(style.DEFAULT_PADDING)
> -        text_buffer = gtk.TextBuffer()
> -        if 'description' in activity.metadata:
> -            text_buffer.set_text(activity.metadata['description'])
> -        self._text_view.set_buffer(text_buffer)
> -        self._text_view.connect('focus-out-event',
> -                               self.__description_changed_cb, activity)
> -        sw.add(self._text_view)
> -        description_box.pack_start(sw, False, True, 0)
> -        self._palette.set_content(description_box)
> -        description_box.show_all()
> -
> -        self.add(description_button)
> -        description_button.connect('clicked',
> -                                   self.__description_button_clicked_cb)
> -
> -        activity.metadata.connect('updated', self.__jobject_updated_cb)
> -
> -    def _get_text_from_buffer(self):
> -        buf = self._text_view.get_buffer()
> -        start_iter = buf.get_start_iter()
> -        end_iter = buf.get_end_iter()
> -        return buf.get_text(start_iter, end_iter, False)
> -
> -    def __jobject_updated_cb(self, jobject):
> -        if self._text_view.has_focus():
> -            return
> -        if 'description' not in jobject:
> -            return
> -        if self._get_text_from_buffer() == jobject['description']:
> -            return
> -        buf = self._text_view.get_buffer()
> -        buf.set_text(jobject['description'])
> -
> -    def __description_button_clicked_cb(self, button):
> -        self._palette.popup(immediate=True, state=1)
> -
> -    def __description_changed_cb(self, widget, event, activity):
> -        description = self._get_text_from_buffer()
> -        if 'description' in activity.metadata and \
> -                description == activity.metadata['description']:
> -            return
> -
> -        activity.metadata['description'] = description
> -        activity.save()
> -        return False
> -
> -
> -class ActivityToolbar(gtk.Toolbar):
> -    """The Activity toolbar with the Journal entry title, sharing,
> -       and Stop buttons
> -
> -    All activities should have this toolbar. It is easiest to add it to
> your
> -    Activity by using the ActivityToolbox.
> -    """
> -
> -    def __init__(self, activity, orientation_left=False):
> -        gtk.Toolbar.__init__(self)
> -
> -        self._activity = activity
> -
> -        if activity.metadata:
> -            title_button = TitleEntry(activity)
> -            title_button.show()
> -            self.insert(title_button, -1)
> -            self.title = title_button.entry
> -
> -        if orientation_left == False:
> -            separator = gtk.SeparatorToolItem()
> -            separator.props.draw = False
> -            separator.set_expand(True)
> -            self.insert(separator, -1)
> -            separator.show()
> -
> -        if activity.metadata:
> -            description_item = DescriptionItem(activity)
> -            description_item.show()
> -            self.insert(description_item, -1)
> -
> -        self.share = ShareButton(activity)
> -        self.share.show()
> -        self.insert(self.share, -1)
> -
> -        self.stop = StopButton(activity)
> -        self.insert(self.stop, -1)
> -        self.stop.show()
> -
> -
> -class EditToolbar(gtk.Toolbar):
> -    """Provides the standard edit toolbar for Activities.
> -
> -    Members:
> -        undo  -- the undo button
> -        redo  -- the redo button
> -        copy  -- the copy button
> -        paste -- the paste button
> -        separator -- A separator between undo/redo and copy/paste
> -
> -    This class only provides the 'edit' buttons in a standard layout,
> -    your activity will need to either hide buttons which make no sense for
> your
> -    Activity, or you need to connect the button events to your own
> callbacks:
> -
> -        ## Example from Read.activity:
> -        # Create the edit toolbar:
> -        self._edit_toolbar = EditToolbar(self._view)
> -        # Hide undo and redo, they're not needed
> -        self._edit_toolbar.undo.props.visible = False
> -        self._edit_toolbar.redo.props.visible = False
> -        # Hide the separator too:
> -        self._edit_toolbar.separator.props.visible = False
> -
> -        # As long as nothing is selected, copy needs to be insensitive:
> -        self._edit_toolbar.copy.set_sensitive(False)
> -        # When the user clicks the button, call _edit_toolbar_copy_cb()
> -        self._edit_toolbar.copy.connect('clicked',
> self._edit_toolbar_copy_cb)
> -
> -        # Add the edit toolbar:
> -        toolbox.add_toolbar(_('Edit'), self._edit_toolbar)
> -        # And make it visible:
> -        self._edit_toolbar.show()
> -    """
> -
> -    def __init__(self):
> -        gtk.Toolbar.__init__(self)
> -
> -        self.undo = UndoButton()
> -        self.insert(self.undo, -1)
> -        self.undo.show()
> -
> -        self.redo = RedoButton()
> -        self.insert(self.redo, -1)
> -        self.redo.show()
> -
> -        self.separator = gtk.SeparatorToolItem()
> -        self.separator.set_draw(True)
> -        self.insert(self.separator, -1)
> -        self.separator.show()
> -
> -        self.copy = CopyButton()
> -        self.insert(self.copy, -1)
> -        self.copy.show()
> -
> -        self.paste = PasteButton()
> -        self.insert(self.paste, -1)
> -        self.paste.show()
> -
> -
> -class ActivityToolbox(Toolbox):
> -    """Creates the Toolbox for the Activity
> -
> -    By default, the toolbox contains only the ActivityToolbar. After
> creating
> -    the toolbox, you can add your activity specific toolbars, for example
> the
> -    EditToolbar.
> -
> -    To add the ActivityToolbox to your Activity in MyActivity.__init__()
> do:
> -
> -        # Create the Toolbar with the ActivityToolbar:
> -        toolbox = activity.ActivityToolbox(self)
> -        ... your code, inserting all other toolbars you need, like
> EditToolbar
> -
> -        # Add the toolbox to the activity frame:
> -        self.set_toolbox(toolbox)
> -        # And make it visible:
> -        toolbox.show()
> -    """
> -
> -    def __init__(self, activity):
> -        Toolbox.__init__(self)
> -
> -        self._activity_toolbar = ActivityToolbar(activity)
> -        self.add_toolbar(_('Activity'), self._activity_toolbar)
> -        self._activity_toolbar.show()
> -
> -    def get_activity_toolbar(self):
> -        return self._activity_toolbar
> diff --git a/toolkit/chooser.py b/toolkit/chooser.py
> deleted file mode 100644
> index e957fd7..0000000
> --- a/toolkit/chooser.py
> +++ /dev/null
> @@ -1,69 +0,0 @@
> -# Copyright (C) 2009, Aleksey Lim
> -#
> -# 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
> -
> -"""Object chooser method"""
> -
> -import gtk
> -import logging
> -
> -from sugar import mime
> -from sugar.graphics.objectchooser import ObjectChooser
> -
> -TEXT  = hasattr(mime, 'GENERIC_TYPE_TEXT') and mime.GENERIC_TYPE_TEXT or
> None
> -IMAGE = hasattr(mime, 'GENERIC_TYPE_IMAGE') and mime.GENERIC_TYPE_IMAGE or
> None
> -AUDIO = hasattr(mime, 'GENERIC_TYPE_AUDIO') and mime.GENERIC_TYPE_AUDIO or
> None
> -VIDEO = hasattr(mime, 'GENERIC_TYPE_VIDEO') and mime.GENERIC_TYPE_VIDEO or
> None
> -LINK  = hasattr(mime, 'GENERIC_TYPE_LINK') and mime.GENERIC_TYPE_LINK or
> None
> -
> -
> -def pick(cb=None, default=None, parent=None, what=None):
> -    """
> -    Opens object chooser.
> -
> -    Method returns:
> -
> -        * cb(jobject), if object was choosen and cb is not None
> -        * jobject, if object was choosen and cb is None
> -        * default, otherwise
> -
> -    NOTE: 'what' makes sense only for sugar >= 0.84
> -    """
> -    what = what and {'what_filter': what} or {}
> -    chooser = ObjectChooser(parent=parent, **what)
> -
> -    jobject = None
> -    out = None
> -
> -    try:
> -        if chooser.run() == gtk.RESPONSE_ACCEPT:
> -            jobject = chooser.get_selected_object()
> -            logging.debug('ObjectChooser: %r' % jobject)
> -
> -            if jobject and jobject.file_path:
> -                if cb:
> -                    out = cb(jobject)
> -                else:
> -                    out = jobject
> -    finally:
> -        if jobject and id(jobject) != id(out):
> -            jobject.destroy()
> -        chooser.destroy()
> -        del chooser
> -
> -    if out:
> -        return out
> -    else:
> -        return default
> diff --git a/toolkit/combobox.py b/toolkit/combobox.py
> deleted file mode 100644
> index d021106..0000000
> --- a/toolkit/combobox.py
> +++ /dev/null
> @@ -1,201 +0,0 @@
> -# Copyright (C) 2007, One Laptop Per Child
> -# Copyright (C) 2009, Aleksey Lim
> -#
> -# 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.
> -
> -"""
> -STABLE.
> -"""
> -
> -import gobject
> -import gtk
> -
> -
> -class ComboBox(gtk.ComboBox):
> -
> -    def __init__(self):
> -        gtk.ComboBox.__init__(self)
> -
> -        self._text_renderer = None
> -        self._icon_renderer = None
> -
> -        model = gtk.ListStore(gobject.TYPE_PYOBJECT,
> -                                    gobject.TYPE_STRING,
> -                                    gtk.gdk.Pixbuf,
> -                                    gobject.TYPE_BOOLEAN)
> -        self.set_model(model)
> -
> -        self.set_row_separator_func(self._is_separator)
> -
> -    def get_value(self):
> -        """
> -        Parameters
> -        ----------
> -        None :
> -
> -        Returns:
> -        --------
> -        value :
> -
> -        """
> -        row = self.get_active_item()
> -        if not row:
> -            return None
> -        return row[0]
> -
> -    value = gobject.property(
> -        type=object, getter=get_value, setter=None)
> -
> -    def _get_real_name_from_theme(self, name, size):
> -        icon_theme = gtk.icon_theme_get_default()
> -        width, height = gtk.icon_size_lookup(size)
> -        info = icon_theme.lookup_icon(name, max(width, height), 0)
> -        if not info:
> -            raise ValueError("Icon '" + name + "' not found.")
> -        fname = info.get_filename()
> -        del info
> -        return fname
> -
> -    def append_item(self, action_id, text, icon_name=None,
> file_name=None):
> -        """
> -        Parameters
> -        ----------
> -        action_id :
> -
> -        text :
> -
> -        icon_name=None :
> -
> -        file_name=None :
> -
> -        Returns
> -        -------
> -        None
> -
> -        """
> -        item = self._item_new(action_id, text, icon_name, file_name)
> -        self.get_model().append(item)
> -
> -    def set_item(self, action_id, text=None, icon_name=None,
> file_name=None):
> -        for i, value in enumerate(self.get_model()):
> -            if value[0] == action_id:
> -                item = self._item_new(action_id, text, icon_name,
> file_name)
> -                iter = self.get_model().iter_nth_child(None, i)
> -                if text is not None:
> -                    self.get_model().set(iter, 1, item[1])
> -                if icon_name is not None or file_name is not None:
> -                    self.get_model().set(iter, 2, item[2])
> -                return True
> -        return False
> -
> -    def select(self, action_id=None, text=None):
> -        if action_id is not None:
> -            column = 0
> -            value = action_id
> -        elif text is not None:
> -            column = 1
> -            value = text
> -        else:
> -            return
> -
> -        for i, item in enumerate(self.get_model()):
> -            if item[column] != value:
> -                continue
> -            self.set_active(i)
> -            break
> -
> -    def _item_new(self, action_id, text, icon_name, file_name):
> -        if not self._icon_renderer and (icon_name or file_name):
> -            self._icon_renderer = gtk.CellRendererPixbuf()
> -
> -            settings = self.get_settings()
> -            w, h = gtk.icon_size_lookup_for_settings(
> -                                            settings, gtk.ICON_SIZE_MENU)
> -            self._icon_renderer.props.stock_size = max(w, h)
> -
> -            self.pack_start(self._icon_renderer, False)
> -            self.add_attribute(self._icon_renderer, 'pixbuf', 2)
> -
> -        if not self._text_renderer and text:
> -            self._text_renderer = gtk.CellRendererText()
> -            self.pack_end(self._text_renderer, True)
> -            self.add_attribute(self._text_renderer, 'text', 1)
> -
> -        if icon_name or file_name:
> -            if text:
> -                size = gtk.ICON_SIZE_MENU
> -            else:
> -                size = gtk.ICON_SIZE_LARGE_TOOLBAR
> -            width, height = gtk.icon_size_lookup(size)
> -
> -            if icon_name:
> -                file_name = self._get_real_name_from_theme(icon_name,
> size)
> -
> -            pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(
> -                                                file_name, width, height)
> -        else:
> -            pixbuf = None
> -
> -        return (action_id, text, pixbuf, False)
> -
> -    def append_separator(self):
> -        """
> -        Parameters
> -        ----------
> -        None
> -
> -        Returns
> -        -------
> -        None
> -
> -        """
> -        self.get_model().append([0, None, None, True])
> -
> -    def get_active_item(self):
> -        """
> -        Parameters
> -        ----------
> -        None
> -
> -        Returns
> -        -------
> -        Active_item :
> -
> -        """
> -        index = self.get_active()
> -        if index == -1:
> -            index = 0
> -
> -        row = self.get_model().iter_nth_child(None, index)
> -        if not row:
> -            return None
> -        return self.get_model()[row]
> -
> -    def remove_all(self):
> -        """
> -        Parameters
> -        ----------
> -        None
> -
> -        Returns
> -        -------
> -        None
> -
> -        """
> -        self.get_model().clear()
> -
> -    def _is_separator(self, model, row):
> -        return model[row][3]
> diff --git a/toolkit/internals/__init__.py b/toolkit/internals/__init__.py
> deleted file mode 100644
> index 17a92ac..0000000
> --- a/toolkit/internals/__init__.py
> +++ /dev/null
> @@ -1,16 +0,0 @@
> -# Copyright (C) 2009, Aleksey Lim
> -#
> -# 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.
> diff --git a/toolkit/internals/palettewindow.py
> b/toolkit/internals/palettewindow.py
> deleted file mode 100644
> index d8c4326..0000000
> --- a/toolkit/internals/palettewindow.py
> +++ /dev/null
> @@ -1,976 +0,0 @@
> -# Copyright (C) 2007, Eduardo Silva <edsiper at gmail.com>
> -# Copyright (C) 2008, One Laptop Per Child
> -# Copyright (C) 2009, Tomeu Vizoso
> -#
> -# 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.
> -
> -"""
> -STABLE.
> -"""
> -
> -import logging
> -
> -import gtk
> -import gobject
> -import hippo
> -
> -from sugar.graphics import palettegroup
> -from sugar.graphics import animator
> -from sugar.graphics import style
> -
> -
> -def _calculate_gap(a, b):
> -    """Helper function to find the gap position and size of widget a"""
> -    # Test for each side if the palette and invoker are
> -    # adjacent to each other.
> -    gap = True
> -
> -    if a.y + a.height == b.y:
> -        gap_side = gtk.POS_BOTTOM
> -    elif a.x + a.width == b.x:
> -        gap_side = gtk.POS_RIGHT
> -    elif a.x == b.x + b.width:
> -        gap_side = gtk.POS_LEFT
> -    elif a.y == b.y + b.height:
> -        gap_side = gtk.POS_TOP
> -    else:
> -        gap = False
> -
> -    if gap:
> -        if gap_side == gtk.POS_BOTTOM or gap_side == gtk.POS_TOP:
> -            gap_start = min(a.width, max(0, b.x - a.x))
> -            gap_size = max(0, min(a.width,
> -                                  (b.x + b.width) - a.x) - gap_start)
> -        elif gap_side == gtk.POS_RIGHT or gap_side == gtk.POS_LEFT:
> -            gap_start = min(a.height, max(0, b.y - a.y))
> -            gap_size = max(0, min(a.height,
> -                                  (b.y + b.height) - a.y) - gap_start)
> -
> -    if gap and gap_size > 0:
> -        return (gap_side, gap_start, gap_size)
> -    else:
> -        return False
> -
> -
> -class MouseSpeedDetector(gobject.GObject):
> -
> -    __gsignals__ = {
> -        'motion-slow': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
> ([])),
> -        'motion-fast': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
> ([])),
> -    }
> -
> -    _MOTION_SLOW = 1
> -    _MOTION_FAST = 2
> -
> -    def __init__(self, parent, delay, thresh):
> -        """Create MouseSpeedDetector object,
> -            delay in msec
> -            threshold in pixels (per tick of 'delay' msec)"""
> -
> -        gobject.GObject.__init__(self)
> -
> -        self._threshold = thresh
> -        self._parent = parent
> -        self._delay = delay
> -        self._state = None
> -        self._timeout_hid = None
> -        self._mouse_pos = None
> -
> -    def start(self):
> -        self.stop()
> -
> -        self._mouse_pos = self._get_mouse_position()
> -        self._timeout_hid = gobject.timeout_add(self._delay,
> self._timer_cb)
> -
> -    def stop(self):
> -        if self._timeout_hid is not None:
> -            gobject.source_remove(self._timeout_hid)
> -        self._state = None
> -
> -    def _get_mouse_position(self):
> -        display = gtk.gdk.display_get_default()
> -        screen_, x, y, mask_ = display.get_pointer()
> -        return (x, y)
> -
> -    def _detect_motion(self):
> -        oldx, oldy = self._mouse_pos
> -        (x, y) = self._get_mouse_position()
> -        self._mouse_pos = (x, y)
> -
> -        dist2 = (oldx - x)**2 + (oldy - y)**2
> -        if dist2 > self._threshold**2:
> -            return True
> -        else:
> -            return False
> -
> -    def _timer_cb(self):
> -        motion = self._detect_motion()
> -        if motion and self._state != self._MOTION_FAST:
> -            self.emit('motion-fast')
> -            self._state = self._MOTION_FAST
> -        elif not motion and self._state != self._MOTION_SLOW:
> -            self.emit('motion-slow')
> -            self._state = self._MOTION_SLOW
> -
> -        return True
> -
> -
> -class PaletteWindow(gtk.Window):
> -
> -    __gsignals__ = {
> -        'popup': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
> -        'popdown': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
> -        'activate': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
> -    }
> -
> -    def __init__(self, **kwargs):
> -        self._group_id = None
> -        self._invoker = None
> -        self._invoker_hids = []
> -        self._cursor_x = 0
> -        self._cursor_y = 0
> -        self._alignment = None
> -        self._up = False
> -        self._old_alloc = None
> -
> -        self._popup_anim = animator.Animator(.5, 10)
> -        self._popup_anim.add(_PopupAnimation(self))
> -
> -        self._popdown_anim = animator.Animator(0.6, 10)
> -        self._popdown_anim.add(_PopdownAnimation(self))
> -
> -        gobject.GObject.__init__(self, **kwargs)
> -
> -        self.set_decorated(False)
> -        self.set_resizable(False)
> -        # Just assume xthickness and ythickness are the same
> -        self.set_border_width(self.get_style().xthickness)
> -
> -        accel_group = gtk.AccelGroup()
> -        self.set_data('sugar-accel-group', accel_group)
> -        self.add_accel_group(accel_group)
> -
> -        self.set_group_id("default")
> -
> -        self.connect('show', self.__show_cb)
> -        self.connect('hide', self.__hide_cb)
> -        self.connect('realize', self.__realize_cb)
> -        self.connect('destroy', self.__destroy_cb)
> -        self.connect('enter-notify-event', self.__enter_notify_event_cb)
> -        self.connect('leave-notify-event', self.__leave_notify_event_cb)
> -
> -        self._mouse_detector = MouseSpeedDetector(self, 200, 5)
> -        self._mouse_detector.connect('motion-slow', self._mouse_slow_cb)
> -
> -    def __destroy_cb(self, palette):
> -        self.set_group_id(None)
> -
> -    def set_invoker(self, invoker):
> -        for hid in self._invoker_hids[:]:
> -            self._invoker.disconnect(hid)
> -            self._invoker_hids.remove(hid)
> -
> -        self._invoker = invoker
> -        if invoker is not None:
> -            self._invoker_hids.append(self._invoker.connect(
> -                'mouse-enter', self._invoker_mouse_enter_cb))
> -            self._invoker_hids.append(self._invoker.connect(
> -                'mouse-leave', self._invoker_mouse_leave_cb))
> -            self._invoker_hids.append(self._invoker.connect(
> -                'right-click', self._invoker_right_click_cb))
> -
> -    def get_invoker(self):
> -        return self._invoker
> -
> -    invoker = gobject.property(type=object,
> -                               getter=get_invoker,
> -                               setter=set_invoker)
> -
> -    def __realize_cb(self, widget):
> -        self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
> -
> -    def _mouse_slow_cb(self, widget):
> -        self._mouse_detector.stop()
> -        self._palette_do_popup()
> -
> -    def _palette_do_popup(self):
> -        immediate = False
> -
> -        if self.is_up():
> -            self._popdown_anim.stop()
> -            return
> -
> -        if self._group_id:
> -            group = palettegroup.get_group(self._group_id)
> -            if group and group.is_up():
> -                immediate = True
> -                group.popdown()
> -
> -        self.popup(immediate=immediate)
> -
> -    def is_up(self):
> -        return self._up
> -
> -    def set_group_id(self, group_id):
> -        if self._group_id:
> -            group = palettegroup.get_group(self._group_id)
> -            group.remove(self)
> -        if group_id:
> -            self._group_id = group_id
> -            group = palettegroup.get_group(group_id)
> -            group.add(self)
> -
> -    def get_group_id(self):
> -        return self._group_id
> -
> -    group_id = gobject.property(type=str,
> -                                getter=get_group_id,
> -                                setter=set_group_id)
> -
> -    def do_size_request(self, requisition):
> -        gtk.Window.do_size_request(self, requisition)
> -        requisition.width = max(requisition.width, style.GRID_CELL_SIZE *
> 2)
> -
> -    def do_size_allocate(self, allocation):
> -        gtk.Window.do_size_allocate(self, allocation)
> -
> -        if self._old_alloc is None or \
> -           self._old_alloc.x != allocation.x or \
> -           self._old_alloc.y != allocation.y or \
> -           self._old_alloc.width != allocation.width or \
> -           self._old_alloc.height != allocation.height:
> -            self.queue_draw()
> -
> -        # We need to store old allocation because when size_allocate
> -        # is called widget.allocation is already updated.
> -        # gtk.Window resizing is different from normal containers:
> -        # the X window is resized, widget.allocation is updated from
> -        # the configure request handler and finally size_allocate is
> called.
> -        self._old_alloc = allocation
> -
> -    def do_expose_event(self, event):
> -        # We want to draw a border with a beautiful gap
> -        if self._invoker is not None and
> self._invoker.has_rectangle_gap():
> -            invoker = self._invoker.get_rect()
> -            palette = self.get_rect()
> -
> -            gap = _calculate_gap(palette, invoker)
> -        else:
> -            gap = False
> -
> -        allocation = self.get_allocation()
> -        wstyle = self.get_style()
> -
> -        if gap:
> -            wstyle.paint_box_gap(event.window, gtk.STATE_PRELIGHT,
> -                                 gtk.SHADOW_IN, event.area, self,
> "palette",
> -                                 0, 0, allocation.width,
> allocation.height,
> -                                 gap[0], gap[1], gap[2])
> -        else:
> -            wstyle.paint_box(event.window, gtk.STATE_PRELIGHT,
> -                             gtk.SHADOW_IN, event.area, self, "palette",
> -                             0, 0, allocation.width, allocation.height)
> -
> -        # Fall trough to the container expose handler.
> -        # (Leaving out the window expose handler which redraws everything)
> -        gtk.Bin.do_expose_event(self, event)
> -
> -    def update_position(self):
> -        invoker = self._invoker
> -        if invoker is None or self._alignment is None:
> -            logging.error('Cannot update the palette position.')
> -            return
> -
> -        rect = self.size_request()
> -        position = invoker.get_position_for_alignment(self._alignment,
> rect)
> -        if position is None:
> -            position = invoker.get_position(rect)
> -
> -        self.move(position.x, position.y)
> -
> -    def get_full_size_request(self):
> -        return self.size_request()
> -
> -    def popup(self, immediate=False):
> -        if self._invoker is not None:
> -            full_size_request = self.get_full_size_request()
> -            self._alignment =
> self._invoker.get_alignment(full_size_request)
> -
> -            self.update_position()
> -            self.set_transient_for(self._invoker.get_toplevel())
> -
> -        self._popdown_anim.stop()
> -
> -        if not immediate:
> -            self._popup_anim.start()
> -        else:
> -            self._popup_anim.stop()
> -            self.show()
> -            # we have to invoke update_position() twice
> -            # since WM could ignore first move() request
> -            self.update_position()
> -
> -    def popdown(self, immediate=False):
> -        logging.debug('PaletteWindow.popdown immediate %r', immediate)
> -
> -        self._popup_anim.stop()
> -        self._mouse_detector.stop()
> -
> -        if not immediate:
> -            self._popdown_anim.start()
> -        else:
> -            self._popdown_anim.stop()
> -            self.size_request()
> -            self.hide()
> -
> -    def on_invoker_enter(self):
> -        self._popdown_anim.stop()
> -        self._mouse_detector.start()
> -
> -    def on_invoker_leave(self):
> -        self._mouse_detector.stop()
> -        self.popdown()
> -
> -    def on_enter(self, event):
> -        self._popdown_anim.stop()
> -
> -    def on_leave(self, event):
> -        self.popdown()
> -
> -    def _invoker_mouse_enter_cb(self, invoker):
> -        self.on_invoker_enter()
> -
> -    def _invoker_mouse_leave_cb(self, invoker):
> -        self.on_invoker_leave()
> -
> -    def _invoker_right_click_cb(self, invoker):
> -        self.popup(immediate=True)
> -
> -    def __enter_notify_event_cb(self, widget, event):
> -        if event.detail != gtk.gdk.NOTIFY_INFERIOR and \
> -                event.mode == gtk.gdk.CROSSING_NORMAL:
> -            self.on_enter(event)
> -
> -    def __leave_notify_event_cb(self, widget, event):
> -        if event.detail != gtk.gdk.NOTIFY_INFERIOR and \
> -                event.mode == gtk.gdk.CROSSING_NORMAL:
> -            self.on_leave(event)
> -
> -    def __show_cb(self, widget):
> -        if self._invoker is not None:
> -            self._invoker.notify_popup()
> -
> -        self._up = True
> -        self.emit('popup')
> -
> -    def __hide_cb(self, widget):
> -        logging.debug('__hide_cb')
> -
> -        if self._invoker:
> -            self._invoker.notify_popdown()
> -
> -        self._up = False
> -        self.emit('popdown')
> -
> -    def get_rect(self):
> -        win_x, win_y = self.window.get_origin()
> -        rectangle = self.get_allocation()
> -
> -        x = win_x + rectangle.x
> -        y = win_y + rectangle.y
> -        width, height = self.size_request()
> -
> -        return gtk.gdk.Rectangle(x, y, width, height)
> -
> -    def get_palette_state(self):
> -        return self._palette_state
> -
> -    def _set_palette_state(self, state):
> -        self._palette_state = state
> -
> -    def set_palette_state(self, state):
> -        self._set_palette_state(state)
> -
> -    palette_state = property(get_palette_state)
> -
> -
> -class _PopupAnimation(animator.Animation):
> -
> -    def __init__(self, palette):
> -        animator.Animation.__init__(self, 0.0, 1.0)
> -        self._palette = palette
> -
> -    def next_frame(self, current):
> -        if current == 1.0:
> -            self._palette.popup(immediate=True)
> -
> -
> -class _PopdownAnimation(animator.Animation):
> -
> -    def __init__(self, palette):
> -        animator.Animation.__init__(self, 0.0, 1.0)
> -        self._palette = palette
> -
> -    def next_frame(self, current):
> -        if current == 1.0:
> -            self._palette.popdown(immediate=True)
> -
> -
> -class Invoker(gobject.GObject):
> -
> -    __gsignals__ = {
> -        'mouse-enter': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
> ([])),
> -        'mouse-leave': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
> ([])),
> -        'right-click': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
> ([])),
> -        'focus-out': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
> -    }
> -
> -    ANCHORED = 0
> -    AT_CURSOR = 1
> -
> -    BOTTOM = [(0.0, 0.0, 0.0, 1.0), (-1.0, 0.0, 1.0, 1.0)]
> -    RIGHT = [(0.0, 0.0, 1.0, 0.0), (0.0, -1.0, 1.0, 1.0)]
> -    TOP = [(0.0, -1.0, 0.0, 0.0), (-1.0, -1.0, 1.0, 0.0)]
> -    LEFT = [(-1.0, 0.0, 0.0, 0.0), (-1.0, -1.0, 0.0, 1.0)]
> -
> -    def __init__(self):
> -        gobject.GObject.__init__(self)
> -
> -        self.parent = None
> -
> -        self._screen_area = gtk.gdk.Rectangle(0, 0,
> gtk.gdk.screen_width(),
> -                                              gtk.gdk.screen_height())
> -        self._position_hint = self.ANCHORED
> -        self._cursor_x = -1
> -        self._cursor_y = -1
> -        self._palette = None
> -
> -    def attach(self, parent):
> -        self.parent = parent
> -
> -    def detach(self):
> -        self.parent = None
> -        if self._palette is not None:
> -            self._palette.destroy()
> -            self._palette = None
> -
> -    def _get_position_for_alignment(self, alignment, palette_dim):
> -        palette_halign = alignment[0]
> -        palette_valign = alignment[1]
> -        invoker_halign = alignment[2]
> -        invoker_valign = alignment[3]
> -
> -        if self._cursor_x == -1 or self._cursor_y == -1:
> -            display = gtk.gdk.display_get_default()
> -            screen_, x, y, mask_ = display.get_pointer()
> -            self._cursor_x = x
> -            self._cursor_y = y
> -
> -        if self._position_hint is self.ANCHORED:
> -            rect = self.get_rect()
> -        else:
> -            dist = style.PALETTE_CURSOR_DISTANCE
> -            rect = gtk.gdk.Rectangle(self._cursor_x - dist,
> -                                     self._cursor_y - dist,
> -                                     dist * 2, dist * 2)
> -
> -        palette_width, palette_height = palette_dim
> -
> -        x = rect.x + rect.width * invoker_halign + \
> -            palette_width * palette_halign
> -
> -        y = rect.y + rect.height * invoker_valign + \
> -            palette_height * palette_valign
> -
> -        return gtk.gdk.Rectangle(int(x), int(y),
> -                                 palette_width, palette_height)
> -
> -    def _in_screen(self, rect):
> -        return rect.x >= self._screen_area.x and \
> -               rect.y >= self._screen_area.y and \
> -               rect.x + rect.width <= self._screen_area.width and \
> -               rect.y + rect.height <= self._screen_area.height
> -
> -    def _get_area_in_screen(self, rect):
> -        """Return area of rectangle visible in the screen"""
> -
> -        x1 = max(rect.x, self._screen_area.x)
> -        y1 = max(rect.y, self._screen_area.y)
> -        x2 = min(rect.x + rect.width,
> -                self._screen_area.x + self._screen_area.width)
> -        y2 = min(rect.y + rect.height,
> -                self._screen_area.y + self._screen_area.height)
> -
> -        return (x2 - x1) * (y2 - y1)
> -
> -    def _get_alignments(self):
> -        if self._position_hint is self.AT_CURSOR:
> -            return [(0.0, 0.0, 1.0, 1.0),
> -                    (0.0, -1.0, 1.0, 0.0),
> -                    (-1.0, -1.0, 0.0, 0.0),
> -                    (-1.0, 0.0, 0.0, 1.0)]
> -        else:
> -            return self.BOTTOM + self.RIGHT + self.TOP + self.LEFT
> -
> -    def get_position_for_alignment(self, alignment, palette_dim):
> -        rect = self._get_position_for_alignment(alignment, palette_dim)
> -        if self._in_screen(rect):
> -            return rect
> -        else:
> -            return None
> -
> -    def get_position(self, palette_dim):
> -        alignment = self.get_alignment(palette_dim)
> -        rect = self._get_position_for_alignment(alignment, palette_dim)
> -
> -        # In case our efforts to find an optimum place inside the screen
> -        # failed, just make sure the palette fits inside the screen if at
> all
> -        # possible.
> -        rect.x = max(0, rect.x)
> -        rect.y = max(0, rect.y)
> -
> -        rect.x = min(rect.x, self._screen_area.width - rect.width)
> -        rect.y = min(rect.y, self._screen_area.height - rect.height)
> -
> -        return rect
> -
> -    def get_alignment(self, palette_dim):
> -        best_alignment = None
> -        best_area = -1
> -        for alignment in self._get_alignments():
> -            pos = self._get_position_for_alignment(alignment, palette_dim)
> -            if self._in_screen(pos):
> -                return alignment
> -
> -            area = self._get_area_in_screen(pos)
> -            if area > best_area:
> -                best_alignment = alignment
> -                best_area = area
> -
> -        # Palette horiz/vert alignment
> -        ph = best_alignment[0]
> -        pv = best_alignment[1]
> -
> -        # Invoker horiz/vert alignment
> -        ih = best_alignment[2]
> -        iv = best_alignment[3]
> -
> -        rect = self.get_rect()
> -        screen_area = self._screen_area
> -
> -        if best_alignment in self.LEFT or best_alignment in self.RIGHT:
> -            dtop = rect.y - screen_area.y
> -            dbottom = screen_area.y + screen_area.height - rect.y -
> rect.width
> -
> -            iv = 0
> -
> -            # Set palette_valign to align to screen on the top
> -            if dtop > dbottom:
> -                pv = -float(dtop) / palette_dim[1]
> -
> -            # Set palette_valign to align to screen on the bottom
> -            else:
> -                pv = -float(palette_dim[1] - dbottom - rect.height) \
> -                        / palette_dim[1]
> -
> -        elif best_alignment in self.TOP or best_alignment in self.BOTTOM:
> -            dleft = rect.x - screen_area.x
> -            dright = screen_area.x + screen_area.width - rect.x -
> rect.width
> -
> -            ih = 0
> -
> -            # Set palette_halign to align to screen on left
> -            if dleft > dright:
> -                ph = -float(dleft) / palette_dim[0]
> -
> -            # Set palette_halign to align to screen on right
> -            else:
> -                ph = -float(palette_dim[0] - dright - rect.width) \
> -                        / palette_dim[0]
> -
> -        return (ph, pv, ih, iv)
> -
> -    def has_rectangle_gap(self):
> -        return False
> -
> -    def draw_rectangle(self, event, palette):
> -        pass
> -
> -    def notify_popup(self):
> -        pass
> -
> -    def notify_popdown(self):
> -        self._cursor_x = -1
> -        self._cursor_y = -1
> -
> -    def _ensure_palette_exists(self):
> -        if self.parent and self.palette is None:
> -            palette = self.parent.create_palette()
> -            if palette is not None:
> -                self.palette = palette
> -
> -    def notify_mouse_enter(self):
> -        self._ensure_palette_exists()
> -        self.emit('mouse-enter')
> -
> -    def notify_mouse_leave(self):
> -        self.emit('mouse-leave')
> -
> -    def notify_right_click(self):
> -        self._ensure_palette_exists()
> -        self.emit('right-click')
> -
> -    def get_palette(self):
> -        return self._palette
> -
> -    def set_palette(self, palette):
> -        if self._palette is not None:
> -            self._palette.popdown(immediate=True)
> -
> -        if self._palette:
> -            self._palette.props.invoker = None
> -
> -        self._palette = palette
> -
> -        if self._palette:
> -            self._palette.props.invoker = self
> -
> -    palette = gobject.property(
> -        type=object, setter=set_palette, getter=get_palette)
> -
> -
> -class WidgetInvoker(Invoker):
> -
> -    def __init__(self, parent=None, widget=None):
> -        Invoker.__init__(self)
> -
> -        self._widget = None
> -        self._enter_hid = None
> -        self._leave_hid = None
> -        self._release_hid = None
> -
> -        if parent or widget:
> -            self.attach_widget(parent, widget)
> -
> -    def attach_widget(self, parent, widget=None):
> -        if widget:
> -            self._widget = widget
> -        else:
> -            self._widget = parent
> -
> -        self.notify('widget')
> -
> -        self._enter_hid = self._widget.connect('enter-notify-event',
> -            self.__enter_notify_event_cb)
> -        self._leave_hid = self._widget.connect('leave-notify-event',
> -            self.__leave_notify_event_cb)
> -        self._release_hid = self._widget.connect('button-release-event',
> -            self.__button_release_event_cb)
> -
> -        self.attach(parent)
> -
> -    def detach(self):
> -        Invoker.detach(self)
> -        self._widget.disconnect(self._enter_hid)
> -        self._widget.disconnect(self._leave_hid)
> -        self._widget.disconnect(self._release_hid)
> -
> -    def get_rect(self):
> -        allocation = self._widget.get_allocation()
> -        if self._widget.window is not None:
> -            x, y = self._widget.window.get_origin()
> -        else:
> -            logging.warning(
> -                "Trying to position palette with invoker that's not
> realized.")
> -            x = 0
> -            y = 0
> -
> -        if self._widget.flags() & gtk.NO_WINDOW:
> -            x += allocation.x
> -            y += allocation.y
> -
> -        width = allocation.width
> -        height = allocation.height
> -
> -        return gtk.gdk.Rectangle(x, y, width, height)
> -
> -    def has_rectangle_gap(self):
> -        return True
> -
> -    def draw_rectangle(self, event, palette):
> -        if self._widget.flags() & gtk.NO_WINDOW:
> -            x, y = self._widget.allocation.x, self._widget.allocation.y
> -        else:
> -            x = y = 0
> -
> -        wstyle = self._widget.get_style()
> -        gap = _calculate_gap(self.get_rect(), palette.get_rect())
> -
> -        if gap:
> -            wstyle.paint_box_gap(event.window, gtk.STATE_PRELIGHT,
> -                                 gtk.SHADOW_IN, event.area, self._widget,
> -                                 "palette-invoker", x, y,
> -                                 self._widget.allocation.width,
> -                                 self._widget.allocation.height,
> -                                 gap[0], gap[1], gap[2])
> -        else:
> -            wstyle.paint_box(event.window, gtk.STATE_PRELIGHT,
> -                             gtk.SHADOW_IN, event.area, self._widget,
> -                             "palette-invoker", x, y,
> -                             self._widget.allocation.width,
> -                             self._widget.allocation.height)
> -
> -    def __enter_notify_event_cb(self, widget, event):
> -        self.notify_mouse_enter()
> -
> -    def __leave_notify_event_cb(self, widget, event):
> -        self.notify_mouse_leave()
> -
> -    def __button_release_event_cb(self, widget, event):
> -        if event.button == 3:
> -            self.notify_right_click()
> -            return True
> -        else:
> -            return False
> -
> -    def get_toplevel(self):
> -        return self._widget.get_toplevel()
> -
> -    def notify_popup(self):
> -        Invoker.notify_popup(self)
> -        self._widget.queue_draw()
> -
> -    def notify_popdown(self):
> -        Invoker.notify_popdown(self)
> -        self._widget.queue_draw()
> -
> -    def _get_widget(self):
> -        return self._widget
> -    widget = gobject.property(type=object, getter=_get_widget,
> setter=None)
> -
> -
> -class CanvasInvoker(Invoker):
> -
> -    def __init__(self, parent=None):
> -        Invoker.__init__(self)
> -
> -        self._position_hint = self.AT_CURSOR
> -        self._motion_hid = None
> -        self._release_hid = None
> -        self._item = None
> -
> -        if parent:
> -            self.attach(parent)
> -
> -    def attach(self, parent):
> -        Invoker.attach(self, parent)
> -
> -        self._item = parent
> -        self._motion_hid = self._item.connect('motion-notify-event',
> -
> self.__motion_notify_event_cb)
> -        self._release_hid = self._item.connect('button-release-event',
> -
> self.__button_release_event_cb)
> -
> -    def detach(self):
> -        Invoker.detach(self)
> -        self._item.disconnect(self._motion_hid)
> -        self._item.disconnect(self._release_hid)
> -
> -    def get_default_position(self):
> -        return self.AT_CURSOR
> -
> -    def get_rect(self):
> -        context = self._item.get_context()
> -        if context:
> -            x, y = context.translate_to_screen(self._item)
> -            width, height = self._item.get_allocation()
> -            return gtk.gdk.Rectangle(x, y, width, height)
> -        else:
> -            return gtk.gdk.Rectangle()
> -
> -    def __motion_notify_event_cb(self, button, event):
> -        if event.detail == hippo.MOTION_DETAIL_ENTER:
> -            self.notify_mouse_enter()
> -        elif event.detail == hippo.MOTION_DETAIL_LEAVE:
> -            self.notify_mouse_leave()
> -
> -        return False
> -
> -    def __button_release_event_cb(self, button, event):
> -        if event.button == 3:
> -            self.notify_right_click()
> -            return True
> -        else:
> -            return False
> -
> -    def get_toplevel(self):
> -        return hippo.get_canvas_for_item(self._item).get_toplevel()
> -
> -
> -class ToolInvoker(WidgetInvoker):
> -
> -    def __init__(self, parent=None):
> -        WidgetInvoker.__init__(self)
> -
> -        if parent:
> -            self.attach_tool(parent)
> -
> -    def attach_tool(self, widget):
> -        self.attach_widget(widget, widget.child)
> -
> -    def _get_alignments(self):
> -        parent = self._widget.get_parent()
> -        if parent is None:
> -            return WidgetInvoker._get_alignments()
> -
> -        if parent.get_orientation() is gtk.ORIENTATION_HORIZONTAL:
> -            return self.BOTTOM + self.TOP
> -        else:
> -            return self.LEFT + self.RIGHT
> -
> -
> -class CellRendererInvoker(Invoker):
> -
> -    def __init__(self):
> -        Invoker.__init__(self)
> -
> -        self._position_hint = self.AT_CURSOR
> -        self._tree_view = None
> -        self._cell_renderer = None
> -        self._motion_hid = None
> -        self._leave_hid = None
> -        self._release_hid = None
> -        self.path = None
> -
> -    def attach_cell_renderer(self, tree_view, cell_renderer):
> -        self._tree_view = tree_view
> -        self._cell_renderer = cell_renderer
> -
> -        self._motion_hid = tree_view.connect('motion-notify-event',
> -
> self.__motion_notify_event_cb)
> -        self._leave_hid = tree_view.connect('leave-notify-event',
> -                                            self.__leave_notify_event_cb)
> -        self._release_hid = tree_view.connect('button-release-event',
> -
> self.__button_release_event_cb)
> -
> -        self.attach(cell_renderer)
> -
> -    def detach(self):
> -        Invoker.detach(self)
> -        self._tree_view.disconnect(self._motion_hid)
> -        self._tree_view.disconnect(self._leave_hid)
> -        self._tree_view.disconnect(self._release_hid)
> -
> -    def get_rect(self):
> -        allocation = self._tree_view.get_allocation()
> -        if self._tree_view.window is not None:
> -            x, y = self._tree_view.window.get_origin()
> -        else:
> -            logging.warning(
> -                "Trying to position palette with invoker that's not
> realized.")
> -            x = 0
> -            y = 0
> -
> -        if self._tree_view.flags() & gtk.NO_WINDOW:
> -            x += allocation.x
> -            y += allocation.y
> -
> -        width = allocation.width
> -        height = allocation.height
> -
> -        return gtk.gdk.Rectangle(x, y, width, height)
> -
> -    def __motion_notify_event_cb(self, widget, event):
> -        if event.window != widget.get_bin_window():
> -            return
> -        if self._point_in_cell_renderer(event.x, event.y):
> -
> -            tree_view = self._tree_view
> -            path, column_, x_, y_ =
> tree_view.get_path_at_pos(int(event.x),
> -
> int(event.y))
> -            if path != self.path:
> -                if self.path is not None:
> -                    self._redraw_path(self.path)
> -                if path is not None:
> -                    self._redraw_path(path)
> -                if self.palette is not None:
> -                    self.palette.popdown(immediate=True)
> -                    self.palette = None
> -                self.path = path
> -
> -            self.notify_mouse_enter()
> -        else:
> -            if self.path is not None:
> -                self._redraw_path(self.path)
> -            self.path = None
> -            self.notify_mouse_leave()
> -
> -    def _redraw_path(self, path):
> -        for column in self._tree_view.get_columns():
> -            if self._cell_renderer in column.get_cell_renderers():
> -                break
> -        area = self._tree_view.get_background_area(path, column)
> -        x, y = \
> -            self._tree_view.convert_bin_window_to_widget_coords(area.x,
> area.y)
> -        self._tree_view.queue_draw_area(x, y, area.width, area.height)
> -
> -    def __leave_notify_event_cb(self, widget, event):
> -        self.notify_mouse_leave()
> -
> -    def __button_release_event_cb(self, widget, event):
> -        if event.button == 1 and self._point_in_cell_renderer(event.x,
> -            event.y):
> -            tree_view = self._tree_view
> -            path, column_, x_, y_ =
> tree_view.get_path_at_pos(int(event.x),
> -
> int(event.y))
> -            self._cell_renderer.emit('clicked', path)
> -            # So the treeview receives it and knows a drag isn't going on
> -            return False
> -        if event.button == 3 and self._point_in_cell_renderer(event.x,
> -            event.y):
> -            self.notify_right_click()
> -            return True
> -        else:
> -            return False
> -
> -    def _point_in_cell_renderer(self, event_x, event_y):
> -        pos = self._tree_view.get_path_at_pos(int(event_x), int(event_y))
> -        if pos is None:
> -            return False
> -
> -        path_, column, x, y_ = pos
> -
> -        for cell_renderer in column.get_cell_renderers():
> -            if cell_renderer == self._cell_renderer:
> -                cell_x, cell_width =
> column.cell_get_position(cell_renderer)
> -                if x > cell_x and x < (cell_x + cell_width):
> -                    return True
> -                return False
> -
> -        return False
> -
> -    def get_toplevel(self):
> -        return self._tree_view.get_toplevel()
> -
> -    def notify_popup(self):
> -        Invoker.notify_popup(self)
> -
> -    def notify_popdown(self):
> -        Invoker.notify_popdown(self)
> -        self.palette = None
> -
> -    def get_default_position(self):
> -        return self.AT_CURSOR
> diff --git a/toolkit/json.py b/toolkit/json.py
> deleted file mode 100644
> index a8cbcbd..0000000
> --- a/toolkit/json.py
> +++ /dev/null
> @@ -1,35 +0,0 @@
> -# Copyright (C) 2009, Aleksey Lim
> -#
> -# 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
> -
> -"""
> -Unify usage of simplejson in Python 2.5/2.6
> -
> -In Python 2.5 it imports simplejson module, in 2.6 native json module.
> -
> -Usage:
> -
> -    import toolkit.json as json
> -
> -    # and using regular simplejson interface with module json
> -    json.dumps([])
> -
> -"""
> -
> -try:
> -    from json import *
> -    dumps
> -except (ImportError, NameError):
> -    from simplejson import *
> diff --git a/toolkit/pixbuf.py b/toolkit/pixbuf.py
> deleted file mode 100644
> index c3bb7d1..0000000
> --- a/toolkit/pixbuf.py
> +++ /dev/null
> @@ -1,116 +0,0 @@
> -# Copyright (C) 2009, Aleksey Lim
> -#
> -# 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
> -
> -"""gtk.gdk.Pixbuf extensions"""
> -
> -import re
> -import cStringIO
> -import gtk
> -import rsvg
> -import cairo
> -import logging
> -
> -from sugar.graphics import style
> -from sugar.graphics.xocolor import XoColor, is_valid
> -from sugar.util import LRU
> -
> -
> -def to_file(pixbuf):
> -    """Convert pixbuf object to file object"""
> -
> -    def push(pixbuf, buffer):
> -        buffer.write(pixbuf)
> -
> -    buffer = cStringIO.StringIO()
> -    pixbuf.save_to_callback(push, 'png', user_data=buffer)
> -    buffer.seek(0)
> -
> -    return buffer
> -
> -def to_str(pixbuf):
> -    """Convert pixbuf object to string"""
> -    return to_file(pixbuf).getvalue()
> -
> -def from_str(str):
> -    """Convert string to pixbuf object"""
> -
> -    loader = gtk.gdk.pixbuf_loader_new_with_mime_type('image/png')
> -
> -    try:
> -        loader.write(str)
> -    except Exception, e:
> -        logging.error('pixbuf.from_str: %s' % e)
> -        return None
> -    finally:
> -        loader.close()
> -
> -    return loader.get_pixbuf()
> -
> -
> -def at_size_with_ratio(pixbuf, width, height,
> type=gtk.gdk.INTERP_BILINEAR):
> -    image_width = pixbuf.get_width()
> -    image_height = pixbuf.get_height()
> -
> -    ratio_width = float(width) / image_width
> -    ratio_height = float(height) / image_height
> -    ratio = min(ratio_width, ratio_height)
> -
> -    if ratio_width != ratio:
> -        ratio_width = ratio
> -        width = int(image_width * ratio)
> -    elif ratio_height != ratio:
> -        ratio_height = ratio
> -        height = int(image_height * ratio)
> -
> -    return pixbuf.scale_simple(width, height, type)
> -
> -def from_svg_at_size(filename=None, width=None, height=None, handle=None,
> -        keep_ratio=True):
> -    """Scale and load SVG into pixbuf"""
> -
> -    if not handle:
> -        handle = rsvg.Handle(filename)
> -
> -    dimensions = handle.get_dimension_data()
> -    icon_width = dimensions[0]
> -    icon_height = dimensions[1]
> -
> -    if icon_width != width or icon_height != height:
> -        ratio_width = float(width) / icon_width
> -        ratio_height = float(height) / icon_height
> -
> -        if keep_ratio:
> -            ratio = min(ratio_width, ratio_height)
> -            if ratio_width != ratio:
> -                ratio_width = ratio
> -                width = int(icon_width * ratio)
> -            elif ratio_height != ratio:
> -                ratio_height = ratio
> -                height = int(icon_height * ratio)
> -    else:
> -        ratio_width = 1
> -        ratio_height = 1
> -
> -    surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
> -    context = cairo.Context(surface)
> -    context.scale(ratio_width, ratio_height)
> -    handle.render_cairo(context)
> -
> -    loader = gtk.gdk.pixbuf_loader_new_with_mime_type('image/png')
> -    surface.write_to_png(loader)
> -    loader.close()
> -
> -    return loader.get_pixbuf()
> diff --git a/toolkit/radiopalette.py b/toolkit/radiopalette.py
> deleted file mode 100644
> index 9c902b1..0000000
> --- a/toolkit/radiopalette.py
> +++ /dev/null
> @@ -1,109 +0,0 @@
> -# Copyright (C) 2009, Aleksey Lim
> -#
> -# 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 gtk
> -
> -from sugar.graphics.toolbutton import ToolButton
> -from sugar.graphics.palette import Palette
> -
> -
> -class RadioMenuButton(ToolButton):
> -
> -    def __init__(self, **kwargs):
> -        ToolButton.__init__(self, **kwargs)
> -        self.selected_button = None
> -
> -        if self.props.palette:
> -            self.__palette_cb(None, None)
> -
> -        self.connect('clicked', self.__clicked_cb)
> -        self.connect('notify::palette', self.__palette_cb)
> -
> -    def _do_clicked(self):
> -        if self.palette is None:
> -            return
> -        if self.palette.is_up() and \
> -                self.palette.palette_state == Palette.SECONDARY:
> -            self.palette.popdown(immediate=True)
> -        else:
> -            self.palette.popup(immediate=True)
> -            self.palette.props.invoker.emit('right-click')
> -
> -    def __palette_cb(self, widget, pspec):
> -        if not isinstance(self.props.palette, RadioPalette):
> -            return
> -        self.props.palette.update_button()
> -
> -    def __clicked_cb(self, button):
> -        self._do_clicked()
> -
> -
> -class RadioToolsButton(RadioMenuButton):
> -
> -    def __init__(self, **kwargs):
> -        RadioMenuButton.__init__(self, **kwargs)
> -
> -    def _do_clicked(self):
> -        if not self.selected_button:
> -            return
> -        self.selected_button.emit('clicked')
> -
> -
> -class RadioPalette(Palette):
> -
> -    def __init__(self, **kwargs):
> -        Palette.__init__(self, **kwargs)
> -
> -        self.button_box = gtk.HBox()
> -        self.button_box.show()
> -        self.set_content(self.button_box)
> -
> -    def append(self, button, label):
> -        children = self.button_box.get_children()
> -
> -        if button.palette is not None:
> -            raise RuntimeError("Palette's button should not have
> sub-palettes")
> -
> -        button.show()
> -        button.connect('clicked', self.__clicked_cb)
> -        self.button_box.pack_start(button, fill=False)
> -        button.palette_label = label
> -
> -        if not children:
> -            self.__clicked_cb(button)
> -
> -    def update_button(self):
> -        for i in self.button_box.get_children():
> -            self.__clicked_cb(i)
> -
> -    def __clicked_cb(self, button):
> -        if not button.get_active():
> -            return
> -
> -        self.set_primary_text(button.palette_label)
> -        self.popdown(immediate=True)
> -
> -        if self.props.invoker is not None:
> -            parent = self.props.invoker.parent
> -        else:
> -            parent = None
> -        if not isinstance(parent, RadioMenuButton):
> -            return
> -
> -        parent.props.label = button.palette_label
> -        parent.set_icon(button.props.icon_name)
> -        parent.selected_button = button
> diff --git a/toolkit/scrolledbox.py b/toolkit/scrolledbox.py
> deleted file mode 100644
> index ead071e..0000000
> --- a/toolkit/scrolledbox.py
> +++ /dev/null
> @@ -1,191 +0,0 @@
> -# Copyright (C) 2009, Aleksey Lim
> -#
> -# 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.icon import Icon
> -
> -class ScrollButton(gtk.ToolButton):
> -    def __init__(self, icon_name):
> -        gtk.ToolButton.__init__(self)
> -
> -        icon = Icon(icon_name = icon_name,
> -                icon_size=gtk.ICON_SIZE_SMALL_TOOLBAR)
> -        # The alignment is a hack to work around gtk.ToolButton code
> -        # that sets the icon_size when the icon_widget is a gtk.Image
> -        alignment = gtk.Alignment(0.5, 0.5)
> -        alignment.add(icon)
> -        self.set_icon_widget(alignment)
> -
> -class ScrolledBox(gtk.EventBox):
> -    def __init__(self, orientation,
> -            arrows_policy=gtk.POLICY_AUTOMATIC,
> -            scroll_policy=gtk.POLICY_AUTOMATIC):
> -
> -        gtk.EventBox.__init__(self)
> -        self.orientation = orientation
> -        self._viewport = None
> -        self._abox = None
> -        self._aviewport = None
> -        self._aviewport_sig = None
> -        self._arrows_policy = arrows_policy
> -        self._scroll_policy = scroll_policy
> -        self._left = None
> -        self._right = None
> -
> -        if orientation == gtk.ORIENTATION_HORIZONTAL:
> -            box = gtk.HBox()
> -        else:
> -            box = gtk.VBox()
> -        if self._arrows_policy == gtk.POLICY_AUTOMATIC:
> -            box.connect("size-allocate", self._box_allocate_cb)
> -        self.add(box)
> -
> -        if self._arrows_policy != gtk.POLICY_NEVER:
> -            if orientation == gtk.ORIENTATION_HORIZONTAL:
> -                self._left = ScrollButton('go-left')
> -            else:
> -                self._left = ScrollButton('go-up')
> -            self._left.connect('clicked', self._scroll_cb,
> -                    gtk.gdk.SCROLL_LEFT)
> -            box.pack_start(self._left, False, False, 0)
> -
> -        self._scrolled = gtk.ScrolledWindow()
> -        if orientation == gtk.ORIENTATION_HORIZONTAL:
> -            self._scrolled.set_policy(scroll_policy, gtk.POLICY_NEVER)
> -        else:
> -            self._scrolled.set_policy(gtk.POLICY_NEVER, scroll_policy)
> -        self._scrolled.connect('scroll-event', self._scroll_event_cb)
> -        box.pack_start(self._scrolled, True, True, 0)
> -
> -        if orientation == gtk.ORIENTATION_HORIZONTAL:
> -            self._adj = self._scrolled.get_hadjustment()
> -        else:
> -            self._adj = self._scrolled.get_vadjustment()
> -        self._adj.connect('changed', self._scroll_changed_cb)
> -        self._adj.connect('value-changed', self._scroll_changed_cb)
> -
> -        if self._arrows_policy != gtk.POLICY_NEVER:
> -            if orientation == gtk.ORIENTATION_HORIZONTAL:
> -                self._right = ScrollButton('go-right')
> -            else:
> -                self._right = ScrollButton('go-down')
> -            self._right.connect('clicked', self._scroll_cb,
> -                    gtk.gdk.SCROLL_RIGHT)
> -            box.pack_start(self._right, False, False, 0)
> -
> -    def modify_fg(self, state, bg):
> -        gtk.EventBox.modify_fg(self, state, bg)
> -        self._viewport.get_parent().modify_fg(state, bg)
> -
> -    def modify_bg(self, state, bg):
> -        gtk.EventBox.modify_bg(self, state, bg)
> -        self._viewport.get_parent().modify_bg(state, bg)
> -
> -    def set_viewport(self, widget):
> -        if widget == self._viewport: return
> -        if self._viewport and self._aviewport_sig:
> -            self._viewport.disconnect(self._aviewport_sig)
> -        self._viewport = widget
> -
> -        if self._arrows_policy == gtk.POLICY_AUTOMATIC:
> -            self._aviewport_sig = self._viewport.connect('size-allocate',
> -                    self._viewport_allocate_cb)
> -
> -        self._scrolled.add_with_viewport(widget)
> -
> -    def get_viewport_allocation(self):
> -        alloc = self._scrolled.get_allocation()
> -        alloc.x -= self._adj.get_value()
> -        return alloc
> -
> -    def get_adjustment(self):
> -        return self._adj
> -
> -    def _box_allocate_cb(self, w, a):
> -        self._abox = a
> -        self._update_arrows()
> -
> -    def _viewport_allocate_cb(self, w, a):
> -        self._aviewport = a
> -        self._update_arrows()
> -
> -    def _update_arrows(self):
> -        if not self._abox or not self._aviewport: return
> -
> -        if self.orientation == gtk.ORIENTATION_HORIZONTAL:
> -            show_flag = self._abox.width < self._aviewport.width
> -        else:
> -            show_flag = self._abox.height < self._aviewport.height
> -
> -        if show_flag:
> -            self._left.show()
> -            self._right.show()
> -        else:
> -            self._left.hide()
> -            self._right.hide()
> -
> -    def _scroll_event_cb(self, widget, event):
> -        if self.orientation == gtk.ORIENTATION_HORIZONTAL:
> -            if event.direction == gtk.gdk.SCROLL_UP:
> -                event.direction = gtk.gdk.SCROLL_LEFT
> -            if event.direction == gtk.gdk.SCROLL_DOWN:
> -                event.direction = gtk.gdk.SCROLL_RIGHT
> -        else:
> -            if event.direction == gtk.gdk.SCROLL_LEFT:
> -                event.direction = gtk.gdk.SCROLL_UP
> -            if event.direction == gtk.gdk.SCROLL_RIGHT:
> -                event.direction = gtk.gdk.SCROLL_DOWN
> -
> -        if self._scroll_policy == gtk.POLICY_NEVER:
> -            self._scroll_cb(None, event.direction)
> -
> -        return False
> -
> -    def _scroll_cb(self, widget, direction):
> -        if direction in (gtk.gdk.SCROLL_LEFT, gtk.gdk.SCROLL_UP):
> -            val = max(self._adj.get_property('lower'),
> self._adj.get_value()
> -                    - self._adj.get_property('page_increment'))
> -        else:
> -            val = min(self._adj.get_property('upper')
> -                    - self._adj.get_property('page_size'),
> -                    self._adj.get_value()
> -                    + self._adj.get_property('page_increment'))
> -
> -        self._adj.set_value(val)
> -
> -    def _scroll_changed_cb(self, widget):
> -        val = self._adj.get_value()
> -        if self._left:
> -            if val == 0:
> -                self._left.set_sensitive(False)
> -            else:
> -                self._left.set_sensitive(True)
> -
> -        if self._right:
> -            if val >= self._adj.get_property('upper') - \
> -                    self._adj.get_property('page_size'):
> -                self._right.set_sensitive(False)
> -            else:
> -                self._right.set_sensitive(True)
> -
> -class HScrolledBox(ScrolledBox):
> -    def __init__(self, **kwargs):
> -        ScrolledBox.__init__(self, gtk.ORIENTATION_HORIZONTAL, **kwargs)
> -
> -class VScrolledBox(ScrolledBox):
> -    def __init__(self, **kwargs):
> -        ScrolledBox.__init__(self, gtk.ORIENTATION_VERTICAL, **kwargs)
> diff --git a/toolkit/tarball.py b/toolkit/tarball.py
> deleted file mode 100644
> index 0a4a1b2..0000000
> --- a/toolkit/tarball.py
> +++ /dev/null
> @@ -1,125 +0,0 @@
> -# Copyright (C) 2009, Aleksey Lim
> -#
> -# 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
> -
> -"""Simplify tarfile module usage"""
> -
> -import os
> -import time
> -import tarfile
> -import cStringIO
> -import gtk
> -import zipfile
> -import tempfile
> -import shutil
> -
> -
> -class TarballError(Exception):
> -    """Base Tarball exception."""
> -    pass
> -
> -
> -class BadDataTypeError(TarballError):
> -    """Exception for unsupported data type in read/write methods."""
> -    pass
> -
> -
> -class Tarball:
> -    """
> -    Wrap standart tarfile module to simplify read/write operations.
> -    In read mode Tarball can load zip files as well.
> -
> -    Write usage:
> -
> -        # create Tarball object
> -        # to see all supported modes use
> -        # http://docs.python.org/library/tarfile.html#tarfile.open
> -        tar = Tarball(tarfile, 'w')
> -
> -        # write string to file in tarball
> -        tar.write('name within tarball', 'string to write')
> -
> -        # save and close tarball file
> -        tar.close()
> -
> -    Read usage:
> -
> -        # create Tarball object
> -        tar = Tarball(tarfile)
> -
> -        # read content of file in tarball to string
> -        str_content = tar.read('name within tarball')
> -    """
> -
> -    def __init__(self, name=None, mode='r', mtime=None):
> -        if not mode.startswith('r') or tarfile.is_tarfile(name):
> -            self.__tar = tarfile.TarFile(name=name, mode=mode)
> -        else:
> -            # convert for tar
> -
> -            if not zipfile.is_zipfile(name):
> -                raise tarfile.ReadError()
> -
> -            try:
> -                tmp_dir = tempfile.mkdtemp()
> -                tmp_fd, tmp_name = tempfile.mkstemp()
> -                tmp_fo = os.fdopen(tmp_fd, 'w')
> -
> -                zip = zipfile.ZipFile(name)
> -                zip.extractall(tmp_dir)
> -
> -                tar = tarfile.TarFile(fileobj=tmp_fo, mode='w')
> -                tar.add(tmp_dir, arcname='')
> -                tar.close()
> -
> -                self.__tar = tarfile.TarFile(name=tmp_name, mode=mode)
> -            finally:
> -                tmp_fo.close()
> -                os.unlink(tmp_name)
> -                shutil.rmtree(tmp_dir)
> -
> -        if mtime:
> -            self.mtime = mtime
> -        else:
> -            self.mtime = time.time()
> -
> -    def close(self):
> -        """Save(if 'r' mode was given) and close tarball file."""
> -        self.__tar.close()
> -
> -    def getnames(self):
> -        """Return names of members sorted by creation order."""
> -        return self.__tar.getnames()
> -
> -    def read(self, arcname):
> -        """Returns sring with content of given file from tarball."""
> -        file_o = self.__tar.extractfile(arcname.encode('utf8'))
> -        if not file_o:
> -            return None
> -        out = file_o.read()
> -        file_o.close()
> -        return out
> -
> -    def write(self, arcname, data, mode=0644):
> -        """
> -        Stores given object to file in tarball.
> -        Raises BadDataTypeError exception If data type isn't supported.
> -        """
> -        info = tarfile.TarInfo(arcname.encode('utf8'))
> -        info.mode = mode
> -        info.mtime = self.mtime
> -        info.size = len(data)
> -
> -        self.__tar.addfile(info, cStringIO.StringIO(data))
> diff --git a/toolkit/temposlider.py b/toolkit/temposlider.py
> deleted file mode 100644
> index 8fcf8cb..0000000
> --- a/toolkit/temposlider.py
> +++ /dev/null
> @@ -1,211 +0,0 @@
> -# Copyright (C) 2006-2008, TamTam Team
> -#
> -# 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
> -
> -# Widget was copy&pasted from TamTam activities
> -
> -import gtk
> -import rsvg
> -import cairo
> -
> -from sugar.graphics import style
> -
> -class TempoSlider(gtk.HBox):
> -    def __init__(self, min_value, max_value):
> -        gtk.HBox.__init__(self)
> -
> -        self._pixbuf = [None] * 8
> -        self._image = gtk.Image()
> -        self._image.show()
> -
> -        # used to store tempo updates while the slider is active
> -        self._delayed = 0
> -        self._active = False
> -
> -        self.adjustment = gtk.Adjustment(min_value, min_value, max_value,
> -                (max_value - min_value) / 8, (max_value - min_value) / 8,
> 0)
> -        self._adjustment_h = self.adjustment.connect('value-changed',
> -                self._changed_cb)
> -
> -        slider = gtk.HScale(adjustment = self.adjustment)
> -        slider.show()
> -        slider.set_draw_value(False)
> -        slider.connect("button-press-event", self._press_cb)
> -        slider.connect("button-release-event", self._release_cb)
> -
> -        self.pack_start(slider, True, True)
> -        self.pack_end(self._image, False, False)
> -
> -    def set_value(self, tempo, quiet = False):
> -        if self._active:
> -            self._delayed = tempo
> -        elif quiet:
> -            self.adjustment.handler_block(self._adjustment_h)
> -            self.adjustment.set_value(tempo)
> -            self._update(tempo)
> -            self.adjustment.handler_unblock(self._adjustment_h)
> -        else:
> -            self.adjustment.set_value(tempo)
> -
> -    def _changed_cb(self, widget):
> -        self._update(widget.get_value())
> -
> -    def _update(self, tempo):
> -        def map_range(value, ilower, iupper, olower, oupper):
> -            if value == iupper:
> -                return oupper
> -            return olower + int((oupper-olower+1) * (value-ilower) /
> -                    float(iupper-ilower))
> -
> -        img = map_range(tempo, self.adjustment.lower,
> -                            self.adjustment.upper, 0, 7)
> -
> -        if not self._pixbuf[img]:
> -            svg = rsvg.Handle(data=IMAGE[img])
> -            self._pixbuf[img] = _from_svg_at_size(handle=svg,
> -                    width=style.STANDARD_ICON_SIZE,
> -                    height=style.STANDARD_ICON_SIZE)
> -
> -        self._image.set_from_pixbuf(self._pixbuf[img])
> -
> -    def _press_cb(self, widget, event):
> -        self._active = True
> -
> -    def _release_cb(self, widget, event):
> -        self._active = False
> -        if self._delayed != 0:
> -            self.set_value(self._delayed, True)
> -            self._delayed = 0
> -
> -def _from_svg_at_size(filename=None, width=None, height=None, handle=None,
> -        keep_ratio=True):
> -    """ import from pixbuf.py """
> -
> -    if not handle:
> -        handle = rsvg.Handle(filename)
> -
> -    dimensions = handle.get_dimension_data()
> -    icon_width = dimensions[0]
> -    icon_height = dimensions[1]
> -
> -    if icon_width != width or icon_height != height:
> -        ratio_width = float(width) / icon_width
> -        ratio_height = float(height) / icon_height
> -
> -        if keep_ratio:
> -            ratio = min(ratio_width, ratio_height)
> -            if ratio_width != ratio:
> -                ratio_width = ratio
> -                width = int(icon_width * ratio)
> -            elif ratio_height != ratio:
> -                ratio_height = ratio
> -                height = int(icon_height * ratio)
> -    else:
> -        ratio_width = 1
> -        ratio_height = 1
> -
> -    surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
> -    context = cairo.Context(surface)
> -    context.scale(ratio_width, ratio_height)
> -    handle.render_cairo(context)
> -
> -    loader = gtk.gdk.pixbuf_loader_new_with_mime_type('image/png')
> -    surface.write_to_png(loader)
> -    loader.close()
> -
> -    return loader.get_pixbuf()
> -
> -IMAGE = [None] * 8
> -
> -IMAGE[0] = """<?xml version="1.0" encoding="utf-8"?>
> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
> "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
> -<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"
> xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
> -     width="50px" height="50px" viewBox="0 0 50 50" enable-background="new
> 0 0 50 50" xml:space="preserve">
> -<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF"
> d="M23.5,6.5c3,3,7,7,9,11c-7,5-4,6-3,26c-1,1-8,1-9,0c0,0,2,1,2-1
> -
> c0-3-2-7-2-11c0-2,1-4,1-6c0-3-2-1-2-3c0-3,3-8,3-11c0-2-1-1-2-2v-3H23.5z"/>
> -</svg>
> -"""
> -
> -IMAGE[1] = """<?xml version="1.0" encoding="utf-8"?>
> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
> "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
> -<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"
> xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
> -     width="50px" height="50px" viewBox="0 0 50 50" enable-background="new
> 0 0 50 50" xml:space="preserve">
> -<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF"
> d="M27.5,44.5v-3C28.5,42.5,28.5,43.5,27.5,44.5z M26.5,10.5
> -
> c2,2,2,6,2,8c0,4-3,11-3,13s4,7,7,10c-2,2-4,3-5,5h-6c1-1,2-3,2-5c0-3-2-9-3-14c0,0,0-1-1,0v-6c0-3,3-8,3-11c0-1-2-2-2-6h3
> -    C23.5,5.5,26.5,9.5,26.5,10.5z"/>
> -</svg>
> -"""
> -
> -IMAGE[2] = """<?xml version="1.0" encoding="utf-8"?>
> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
> "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
> -<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"
> xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
> -     width="50px" height="50px" viewBox="0 0 50 50" enable-background="new
> 0 0 50 50" xml:space="preserve">
> -<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF"
> d="M30.5,17.5c0,3-2,2-2,4c0,3,4,14,7,21c-1,0-3,1-5,1c1-1,2,0,2-3
> -
> c0-2-4-7-6-10c-3,3-5,8-7,13c-1,0-3-1-4-1c3-3,7-14,7-18s-1-3-4-4c3-2,4-8,4-14h3C23.5,9.5,30.5,14.5,30.5,17.5z"/>
> -</svg>
> -"""
> -
> -IMAGE[3] = """<?xml version="1.0" encoding="utf-8"?>
> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
> "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
> -<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"
> xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
> -     width="50px" height="50px" viewBox="0 0 50 50" enable-background="new
> 0 0 50 50" xml:space="preserve">
> -<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF"
> d="M34.5,22.5c-1-1-2-4-5-6c-1,2,0,3,0,6c0,2-3,4-3,7c0,2,4,2,4,4
> -
> c0,3-1,4-2,5c0-1,0-3-1-4c-1,3-2,7-3,10c-4-3,0-6,0-9s-3-11-4-17l-4,4c1-5,8.25-11.12,7.25-16.12c0.68,0.68,3.029,0,2.87,2.12
> -    C26.5,10.25,33.62,17.75,34.5,22.5z"/>
> -</svg>
> -"""
> -
> -IMAGE[4] = """<?xml version="1.0" encoding="utf-8"?>
> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
> "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
> -<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"
> xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
> -     width="50px" height="50px" viewBox="0 0 50 50" enable-background="new
> 0 0 50 50" xml:space="preserve">
> -<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF"
> d="M24.5,13.5c2,1,5,3,5,6c0,2-2,3-2,5c0,9,11,4,11,13c-1,0-3-2-4-3
> -
> c-3-1-9,1-10-3c-2,3-5,7-7,11c-3,0-3-1-4-1c0-2,3-3,4-6s4-8,4-10c0-3-1-3-2-5c-1,0-2,1-3,2c0-1,2-3,2-4c1-2,3-5,2-8c0,0,1-1,4-2
> -    C25.5,9.5,25.5,11.5,24.5,13.5z"/>
> -</svg>
> -"""
> -
> -IMAGE[5] = """<?xml version="1.0" encoding="utf-8"?>
> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
> "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
> -<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"
> xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
> -     width="50px" height="50px" viewBox="0 0 50 50" enable-background="new
> 0 0 50 50" xml:space="preserve">
> -<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF"
> d="M22.5,10.5c3,2,7,5,7,7c0,3-4,8-4,10c0,3,1,3,1,5h5l2-2l2,2v4
> -
> c-1,0-3-2-5-2c-3,0-5,1-8,1c-1,3-2,7-2,10h-5c1-1,3-3,3-4c1-5,1-11,1-18l-1-1c-1,1-1.75,2.88-2.75,2.88c0,0-0.25-0.63-0.25-1.63
> -
> c4-4,2-8.25,2-13.25c0-1,0.25-2.5,0.38-5.38L22.5,5.5C23.12,6.5,22.5,8.5,22.5,10.5z"/>
> -<polygon fill-rule="evenodd" clip-rule="evenodd" fill="#333333"
> stroke="#333333" stroke-linecap="round" stroke-linejoin="round" points="
> -    25,20 25.25,16.75 26.5,17.88 "/>
> -</svg>
> -"""
> -
> -IMAGE[6] = """<?xml version="1.0" encoding="utf-8"?>
> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
> "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
> -<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"
> xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
> -     width="50px" height="50px" viewBox="0 0 50 50" enable-background="new
> 0 0 50 50" xml:space="preserve">
> -<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF"
> d="M20.5,7.5c1,1,1,3,1,4c10,4,8,6,8,14c0,2,6,9,10,13c-1,2-2,4-4,5
> -
> c1.62-8.88-8.75-13.88-12-15c-1,1-1,0-1,2c0,3,2,5,3,7c-1,1-3,2-6,2c0-1,2-1,2-4c0-2-4-4-4-6c0-3,3-4,5-6c-3-8-8-2-11-6h6
> -    c0-1,1,0,1-3c0-2-1-1-2-2l1-5H20.5z"/>
> -</svg>
> -"""
> -
> -IMAGE[7] = """<?xml version="1.0" encoding="utf-8"?>
> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
> "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
> -<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"
> xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
> -     width="50px" height="50px" viewBox="0 0 50 50" enable-background="new
> 0 0 50 50" xml:space="preserve">
> -<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF"
> d="M20.5,12.5c0.67,0.4,0.4,1.9,1.75,2.25s1.05-0.38,1.5-0.37
> -
> c4.971,0,10.95-0.88,11.75,7.12c-1-2-3-4-5-5l-4,1c1,2,4,4,5,7c1,1,1,4,1,6c3,3,8-1,11,6c-2.88-0.82-4.25-2.62-12.75-2.75
> -
> c-1.561-0.02-2.34-1.561-3.75-1.87c-3.42-0.76-4.67-0.38-5.5-0.38c-3,0-8,7-11,7c-2,0-3-1-3-2c4,2,8-4,9-7c2-1,5-1,8-3c-2-4-6-5-8-3
> -    l-6-6l2-2c1,1,1,2,1,4c1,0,4.12,0.38,6.12-0.62L16.5,17.5v-5H20.5z"/>
> -</svg>
> -"""
> diff --git a/toolkit/toolbarbox.py b/toolkit/toolbarbox.py
> deleted file mode 100644
> index 7172b8b..0000000
> --- a/toolkit/toolbarbox.py
> +++ /dev/null
> @@ -1,333 +0,0 @@
> -# Copyright (C) 2009, Aleksey Lim
> -#
> -# 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 gtk
> -import gobject
> -
> -from sugar.graphics import style
> -from sugar.graphics.toolbutton import ToolButton
> -from sugar.graphics import palettegroup
> -
> -from toolkit.internals.palettewindow import PaletteWindow
> -from toolkit.internals.palettewindow import ToolInvoker
> -
> -
> -_ARROW_SIZE = style.zoom(24)
> -_LINE_WIDTH = 2
> -
> -class ToolbarButton(ToolButton):
> -
> -    def __init__(self, page=None, **kwargs):
> -        ToolButton.__init__(self, **kwargs)
> -
> -        self.page_widget = None
> -
> -        self.set_page(page)
> -
> -        self.connect('clicked',
> -                lambda widget: self.set_expanded(not self.is_expanded()))
> -        self.connect('size-allocate', self.__size_allocate_cb)
> -
> -    def get_toolbar_box(self):
> -        if not hasattr(self.parent, 'owner'):
> -            return None
> -        return self.parent.owner
> -
> -    toolbar_box = property(get_toolbar_box)
> -
> -    def get_page(self):
> -        if self.page_widget is None:
> -            return None
> -        return _get_embedded_page(self.page_widget)
> -
> -    def set_page(self, page):
> -        if page is None:
> -            self.page_widget = None
> -            return
> -
> -        self.page_widget, alignment_ = _embed_page(_Box, page)
> -        w_, h = gtk.icon_size_lookup(gtk.ICON_SIZE_LARGE_TOOLBAR)
> -        page.show()
> -
> -        if self.props.palette is None:
> -            self.props.palette =
> _ToolbarPalette(invoker=ToolInvoker(self))
> -        self._move_page_to_palette()
> -
> -    page = gobject.property(type=object, getter=get_page, setter=set_page)
> -
> -    def is_in_palette(self):
> -        return self.page is not None and \
> -                self.page_widget.parent == self.props.palette
> -
> -    def is_expanded(self):
> -        return self.page is not None and \
> -                not self.is_in_palette()
> -
> -    def popdown(self):
> -        if self.props.palette is not None:
> -            self.props.palette.popdown(immediate=True)
> -
> -    def set_expanded(self, expanded):
> -        self.popdown()
> -
> -        if self.page is None or self.is_expanded() == expanded:
> -            return
> -
> -        if not expanded:
> -            self._move_page_to_palette()
> -            return
> -
> -        box = self.toolbar_box
> -
> -        if box.expanded_button is not None:
> -            if box.expanded_button.window is not None:
> -                # need to redraw it to erase arrow
> -                box.expanded_button.window.invalidate_rect(None, True)
> -            box.expanded_button.set_expanded(False)
> -        box.expanded_button = self
> -
> -        self._unparent()
> -
> -        self.modify_bg(gtk.STATE_NORMAL, box.background)
> -        _setup_page(self.page_widget, box.background, box.props.padding)
> -        box.pack_start(self.page_widget)
> -
> -    def _move_page_to_palette(self):
> -        if self.is_in_palette():
> -            return
> -
> -        self._unparent()
> -
> -        if isinstance(self.props.palette, _ToolbarPalette):
> -            self.props.palette.add(self.page_widget)
> -
> -    def _unparent(self):
> -        if self.page_widget.parent is None:
> -            return
> -        self.page_widget.parent.remove(self.page_widget)
> -
> -    def do_expose_event(self, event):
> -        if not self.is_expanded() or self.props.palette is not None and \
> -                self.props.palette.is_up():
> -            ToolButton.do_expose_event(self, event)
> -            _paint_arrow(self, event, gtk.ARROW_DOWN)
> -            return
> -
> -        alloc = self.allocation
> -
> -        self.get_style().paint_box(event.window,
> -                gtk.STATE_NORMAL, gtk.SHADOW_IN, event.area, self,
> -                'palette-invoker', alloc.x, 0,
> -                alloc.width, alloc.height + _LINE_WIDTH)
> -
> -        if self.child.state != gtk.STATE_PRELIGHT:
> -            self.get_style().paint_box(event.window,
> -                    gtk.STATE_NORMAL, gtk.SHADOW_NONE, event.area, self,
> None,
> -                    alloc.x + _LINE_WIDTH, _LINE_WIDTH,
> -                    alloc.width - _LINE_WIDTH * 2, alloc.height)
> -
> -        gtk.ToolButton.do_expose_event(self, event)
> -        _paint_arrow(self, event, gtk.ARROW_UP)
> -
> -    def __size_allocate_cb(self, button, allocation):
> -        if self.page_widget is not None:
> -            self.page_widget.set_size_request(-1, allocation.height)
> -
> -
> -class ToolbarBox(gtk.VBox):
> -
> -    def __init__(self, padding=style.TOOLBOX_HORIZONTAL_PADDING):
> -        gtk.VBox.__init__(self)
> -        self._expanded_button_index = -1
> -        self.background = None
> -
> -        self._toolbar = gtk.Toolbar()
> -        self._toolbar.owner = self
> -        self._toolbar.connect('remove', self.__remove_cb)
> -
> -        self._toolbar_widget, self._toolbar_alignment = \
> -                _embed_page(gtk.EventBox, self._toolbar)
> -        self.pack_start(self._toolbar_widget)
> -
> -        self.props.padding = padding
> -        self.modify_bg(gtk.STATE_NORMAL,
> -                style.COLOR_TOOLBAR_GREY.get_gdk_color())
> -
> -    def get_toolbar(self):
> -        return self._toolbar
> -
> -    toolbar = property(get_toolbar)
> -
> -    def get_expanded_button(self):
> -        if self._expanded_button_index == -1:
> -            return None
> -        return self.toolbar.get_nth_item(self._expanded_button_index)
> -
> -    def set_expanded_button(self, button):
> -        if not button in self.toolbar:
> -            self._expanded_button_index = -1
> -            return
> -        self._expanded_button_index = self.toolbar.get_item_index(button)
> -
> -    expanded_button = property(get_expanded_button, set_expanded_button)
> -
> -    def get_padding(self):
> -        return self._toolbar_alignment.props.left_padding
> -
> -    def set_padding(self, pad):
> -        self._toolbar_alignment.set_padding(0, 0, pad, pad)
> -
> -    padding = gobject.property(type=object,
> -            getter=get_padding, setter=set_padding)
> -
> -    def modify_bg(self, state, color):
> -        if state == gtk.STATE_NORMAL:
> -            self.background = color
> -        self._toolbar_widget.modify_bg(state, color)
> -        self.toolbar.modify_bg(state, color)
> -
> -    def __remove_cb(self, sender, button):
> -        if not isinstance(button, ToolbarButton):
> -            return
> -        button.popdown()
> -        if button == self.expanded_button:
> -            self.remove(button.page_widget)
> -            self._expanded_button_index = -1
> -
> -
> -class _ToolbarPalette(PaletteWindow):
> -
> -    def __init__(self, **kwargs):
> -        PaletteWindow.__init__(self, **kwargs)
> -        self.set_border_width(0)
> -        self._has_focus = False
> -
> -        group = palettegroup.get_group('default')
> -        group.connect('popdown', self.__group_popdown_cb)
> -        self.set_group_id('toolbarbox')
> -
> -    def get_expanded_button(self):
> -        return self.invoker.parent
> -
> -    expanded_button = property(get_expanded_button)
> -
> -    def on_invoker_enter(self):
> -        PaletteWindow.on_invoker_enter(self)
> -        self._set_focus(True)
> -
> -    def on_invoker_leave(self):
> -        PaletteWindow.on_invoker_leave(self)
> -        self._set_focus(False)
> -
> -    def on_enter(self, event):
> -        PaletteWindow.on_enter(self, event)
> -        self._set_focus(True)
> -
> -    def on_leave(self, event):
> -        PaletteWindow.on_enter(self, event)
> -        self._set_focus(False)
> -
> -    def _set_focus(self, new_focus):
> -        self._has_focus = new_focus
> -        if not self._has_focus:
> -            group = palettegroup.get_group('default')
> -            if not group.is_up():
> -                self.popdown()
> -
> -    def do_size_request(self, requisition):
> -        gtk.Window.do_size_request(self, requisition)
> -        requisition.width = max(requisition.width,
> -                                gtk.gdk.screen_width())
> -
> -    def popup(self, immediate=False):
> -        button = self.expanded_button
> -        if button.is_expanded():
> -            return
> -        box = button.toolbar_box
> -        _setup_page(button.page_widget, style.COLOR_BLACK.get_gdk_color(),
> -                box.props.padding)
> -        PaletteWindow.popup(self, immediate)
> -
> -    def __group_popdown_cb(self, group):
> -        if not self._has_focus:
> -            self.popdown(immediate=True)
> -
> -
> -class _Box(gtk.EventBox):
> -
> -    def __init__(self):
> -        gtk.EventBox.__init__(self)
> -        self.connect('expose-event', self.do_expose_event)
> -        self.set_app_paintable(True)
> -
> -    def do_expose_event(self, widget, event):
> -        if self.parent.expanded_button is None:
> -            return
> -        alloc = self.parent.expanded_button.allocation
> -        self.get_style().paint_box(event.window,
> -                gtk.STATE_NORMAL, gtk.SHADOW_IN, event.area, self,
> -                'palette-invoker', -_LINE_WIDTH, 0,
> -                self.allocation.width + _LINE_WIDTH * 2,
> -                self.allocation.height + _LINE_WIDTH)
> -        self.get_style().paint_box(event.window,
> -                gtk.STATE_NORMAL, gtk.SHADOW_NONE, event.area, self, None,
> -                alloc.x + _LINE_WIDTH, 0,
> -                alloc.width - _LINE_WIDTH * 2, _LINE_WIDTH)
> -
> -
> -def _setup_page(page_widget, color, hpad):
> -    vpad = _LINE_WIDTH
> -    page_widget.child.set_padding(vpad, vpad, hpad, hpad)
> -
> -    page = _get_embedded_page(page_widget)
> -    page.modify_bg(gtk.STATE_NORMAL, color)
> -    if isinstance(page, gtk.Container):
> -        for i in page.get_children():
> -            i.modify_bg(gtk.STATE_INSENSITIVE, color)
> -
> -    page_widget.modify_bg(gtk.STATE_NORMAL, color)
> -    page_widget.modify_bg(gtk.STATE_PRELIGHT, color)
> -
> -
> -def _embed_page(box_class, page):
> -    page.show()
> -
> -    alignment = gtk.Alignment(0.0, 0.0, 1.0, 1.0)
> -    alignment.add(page)
> -    alignment.show()
> -
> -    page_widget = box_class()
> -    page_widget.modify_bg(gtk.STATE_ACTIVE,
> -            style.COLOR_BUTTON_GREY.get_gdk_color())
> -    page_widget.add(alignment)
> -    page_widget.show()
> -
> -    return (page_widget, alignment)
> -
> -
> -def _get_embedded_page(page_widget):
> -    return page_widget.child.child
> -
> -
> -def _paint_arrow(widget, event, arrow_type):
> -    alloc = widget.allocation
> -    x = alloc.x + alloc.width / 2 - _ARROW_SIZE / 2
> -    y = alloc.y + alloc.height - int(_ARROW_SIZE * .85)
> -
> -    widget.get_style().paint_arrow(event.window,
> -            gtk.STATE_NORMAL, gtk.SHADOW_NONE, event.area, widget,
> -            None, arrow_type, True, x, y, _ARROW_SIZE, _ARROW_SIZE)
> diff --git a/toolkit/toolitem.py b/toolkit/toolitem.py
> deleted file mode 100644
> index e490c22..0000000
> --- a/toolkit/toolitem.py
> +++ /dev/null
> @@ -1,79 +0,0 @@
> -# Copyright (C) 2009, Aleksey Lim
> -#
> -# 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.
> -
> -"""A set of toolitem widets"""
> -
> -import gtk
> -import gobject
> -
> -from sugar.graphics import style
> -
> -from toolkit.combobox import ComboBox
> -
> -
> -class ToolWidget(gtk.ToolItem):
> -
> -    def __init__(self, **kwargs):
> -        self._widget = None
> -        self._label = None
> -        self._label_text = None
> -        self._box = gtk.HBox(False, style.DEFAULT_SPACING)
> -
> -        gobject.GObject.__init__(self, **kwargs)
> -        self.props.border_width = style.DEFAULT_PADDING
> -
> -        self._box.show()
> -        self.add(self._box)
> -
> -        if self.label is None:
> -            self.label = gtk.Label()
> -
> -    def get_label_text(self):
> -        return self._label_text
> -
> -    def set_label_text(self, value):
> -        self._label_text = value
> -        if self.label is not None and value:
> -            self.label.set_text(self._label_text)
> -
> -    label_text = gobject.property(getter=get_label_text,
> setter=set_label_text)
> -
> -    def get_label(self):
> -        return self._label
> -
> -    def set_label(self, label):
> -        if self._label is not None:
> -            self._box.remove(self._label)
> -        self._label = label
> -        self._box.pack_start(label, False)
> -        self._box.reorder_child(label, 0)
> -        label.show()
> -        self.set_label_text(self._label_text)
> -
> -    label = gobject.property(getter=get_label, setter=set_label)
> -
> -    def get_widget(self):
> -        return self._widget
> -
> -    def set_widget(self, widget):
> -        if self._widget is not None:
> -            self._box.remove(self._widget)
> -        self._widget = widget
> -        self._box.pack_end(widget)
> -        widget.show()
> -
> -    widget = gobject.property(getter=get_widget, setter=set_widget)
> --
> 1.7.10.4
>
> _______________________________________________
> Sugar-devel mailing list
> Sugar-devel at lists.sugarlabs.org
> http://lists.sugarlabs.org/listinfo/sugar-devel
>


-- 
Rafael Ortiz


More information about the Sugar-devel mailing list