Thanks, pushed.<div><br></div><div>Gonzalo</div><div><br><div class="gmail_quote">On Mon, Jul 16, 2012 at 8:24 AM, Manuel Kaufmann <span dir="ltr"><<a href="mailto:humitos@gmail.com" target="_blank">humitos@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This commit ports completely the Jukebox Activity to Gtk3.<br>
<br>
Signed-off-by: Manuel Kaufmann <<a href="mailto:humitos@gmail.com">humitos@gmail.com</a>><br>
---<br>
 ControlToolbar.py  |   58 +++++++------<br>
 jukeboxactivity.py |  243 ++++++++++++++++++++++++----------------------------<br>
 setup.py           |    2 +-<br>
 widgets.py         |   43 +++++-----<br>
 4 files changed, 169 insertions(+), 177 deletions(-)<br>
<br>
diff --git a/ControlToolbar.py b/ControlToolbar.py<br>
index 87a9b50..2205bde 100644<br>
--- a/ControlToolbar.py<br>
+++ b/ControlToolbar.py<br>
@@ -15,29 +15,31 @@<br>
 # along with this program; if not, write to the Free Software<br>
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA<br>
<br>
+import logging<br>
+<br>
 from gettext import gettext as _<br>
<br>
-import gobject<br>
-import gtk<br>
+from gi.repository import GObject<br>
+from gi.repository import Gtk<br>
<br>
-from sugar.graphics.toolbutton import ToolButton<br>
-from sugar.graphics.toggletoolbutton import ToggleToolButton<br>
+from sugar3.graphics.toolbutton import ToolButton<br>
+from sugar3.graphics.toggletoolbutton import ToggleToolButton<br>
<br>
<br>
-class ViewToolbar(gtk.Toolbar):<br>
+class ViewToolbar(Gtk.Toolbar):<br>
     __gtype_name__ = 'ViewToolbar'<br>
<br>
     __gsignals__ = {<br>
-        'go-fullscreen': (gobject.SIGNAL_RUN_FIRST,<br>
-                          gobject.TYPE_NONE,<br>
+        'go-fullscreen': (GObject.SignalFlags.RUN_FIRST,<br>
+                          None,<br>
                          ([])),<br>
-        'toggle-playlist': (gobject.SIGNAL_RUN_FIRST,<br>
-                            gobject.TYPE_NONE,<br>
+        'toggle-playlist': (GObject.SignalFlags.RUN_FIRST,<br>
+                            None,<br>
                             ([]))<br>
     }<br>
<br>
     def __init__(self):<br>
-        gtk.Toolbar.__init__(self)<br>
+        GObject.GObject.__init__(self)<br>
<br>
         self._show_playlist = ToggleToolButton('view-list')<br>
         self._show_playlist.set_active(True)<br>
@@ -59,11 +61,11 @@ class ViewToolbar(gtk.Toolbar):<br>
         self.emit('toggle-playlist')<br>
<br>
<br>
-class Control(gobject.GObject):<br>
+class Control(GObject.GObject):<br>
     """Class to create the Control (play) toolbar"""<br>
<br>
     def __init__(self, toolbar, jukebox):<br>
-        gobject.GObject.__init__(self)<br>
+        GObject.GObject.__init__(self)<br>
<br>
         self.toolbar = toolbar<br>
         self.jukebox = jukebox<br>
@@ -80,7 +82,7 @@ class Control(gobject.GObject):<br>
                  jukebox._erase_playlist_entry_clicked_cb)<br>
         self.toolbar.insert(erase_playlist_entry_btn, -1)<br>
<br>
-        spacer = gtk.SeparatorToolItem()<br>
+        spacer = Gtk.SeparatorToolItem()<br>
         self.toolbar.insert(spacer, -1)<br>
         spacer.show()<br>
<br>
@@ -90,14 +92,14 @@ class Control(gobject.GObject):<br>
         self.prev_button.connect('clicked', self.prev_button_clicked_cb)<br>
         self.toolbar.insert(self.prev_button, -1)<br>
<br>
-        self.pause_image = gtk.image_new_from_stock(gtk.STOCK_MEDIA_PAUSE,<br>
-                                                    gtk.ICON_SIZE_BUTTON)<br>
+        self.pause_image = Gtk.Image.new_from_stock(Gtk.STOCK_MEDIA_PAUSE,<br>
+                                                    Gtk.IconSize.BUTTON)<br>
         self.pause_image.show()<br>
-        self.play_image = gtk.image_new_from_stock(gtk.STOCK_MEDIA_PLAY,<br>
-                                                   gtk.ICON_SIZE_BUTTON)<br>
+        self.play_image = Gtk.Image.new_from_stock(Gtk.STOCK_MEDIA_PLAY,<br>
+                                                   Gtk.IconSize.BUTTON)<br>
         self.play_image.show()<br>
<br>
-        self.button = gtk.ToolButton()<br>
+        self.button = Gtk.ToolButton()<br>
         self.button.set_icon_widget(self.play_image)<br>
         self.button.set_property('can-default', True)<br>
         self.button.show()<br>
@@ -111,28 +113,32 @@ class Control(gobject.GObject):<br>
         self.next_button.connect('clicked', self.next_button_clicked_cb)<br>
         self.toolbar.insert(self.next_button, -1)<br>
<br>
-        current_time = gtk.ToolItem()<br>
-        self.current_time_label = gtk.Label('')<br>
+        current_time = Gtk.ToolItem()<br>
+        self.current_time_label = Gtk.Label(label='')<br>
         current_time.add(self.current_time_label)<br>
         current_time.show()<br>
         toolbar.insert(current_time, -1)<br>
<br>
-        self.adjustment = gtk.Adjustment(0.0, 0.00, 100.0, 0.1, 1.0, 1.0)<br>
-        self.hscale = gtk.HScale(self.adjustment)<br>
+        self.adjustment = Gtk.Adjustment(0.0, 0.00, 100.0, 0.1, 1.0, 1.0)<br>
+        self.hscale = Gtk.Scale(orientation=Gtk.Orientation.HORIZONTAL,<br>
+                                adjustment=self.adjustment)<br>
         self.hscale.set_draw_value(False)<br>
-        self.hscale.set_update_policy(gtk.UPDATE_CONTINUOUS)<br>
+        # FIXME: this seems to be deprecated<br>
+        # self.hscale.set_update_policy(Gtk.UPDATE_CONTINUOUS)<br>
+        logging.debug("FIXME: AttributeError: 'Scale' object has no "<br>
+                      "attribute 'set_update_policy'")<br>
         self.hscale.connect('button-press-event',<br>
                 jukebox.scale_button_press_cb)<br>
         self.hscale.connect('button-release-event',<br>
                 jukebox.scale_button_release_cb)<br>
<br>
-        self.scale_item = gtk.ToolItem()<br>
+        self.scale_item = Gtk.ToolItem()<br>
         self.scale_item.set_expand(True)<br>
         self.scale_item.add(self.hscale)<br>
         self.toolbar.insert(self.scale_item, -1)<br>
<br>
-        total_time = gtk.ToolItem()<br>
-        self.total_time_label = gtk.Label('')<br>
+        total_time = Gtk.ToolItem()<br>
+        self.total_time_label = Gtk.Label(label='')<br>
         total_time.add(self.total_time_label)<br>
         total_time.show()<br>
         toolbar.insert(total_time, -1)<br>
diff --git a/jukeboxactivity.py b/jukeboxactivity.py<br>
index 8ad59d6..7062fc3 100644<br>
--- a/jukeboxactivity.py<br>
+++ b/jukeboxactivity.py<br>
@@ -27,31 +27,27 @@ import tempfile<br>
 from gettext import gettext as _<br>
 import os<br>
<br>
-from sugar.activity import activity<br>
-from sugar.graphics.objectchooser import ObjectChooser<br>
-from sugar import mime<br>
-from sugar.datastore import datastore<br>
+from sugar3.activity import activity<br>
+from sugar3.graphics.objectchooser import ObjectChooser<br>
+from sugar3 import mime<br>
+from sugar3.datastore import datastore<br>
<br>
-OLD_TOOLBAR = False<br>
-try:<br>
-    from sugar.graphics.toolbarbox import ToolbarBox<br>
-    from sugar.graphics.toolbarbox import ToolbarButton<br>
-    from sugar.activity.widgets import StopButton<br>
-    from sugar.activity.widgets import ActivityToolbarButton<br>
+from sugar3.graphics.toolbarbox import ToolbarBox<br>
+from sugar3.graphics.toolbarbox import ToolbarButton<br>
+from sugar3.activity.widgets import StopButton<br>
+from sugar3.activity.widgets import ActivityToolbarButton<br>
<br>
-except ImportError:<br>
-    OLD_TOOLBAR = True<br>
+import gi<br>
+gi.require_version('Gtk', '3.0')<br>
<br>
-import pygtk<br>
-pygtk.require('2.0')<br>
-<br>
-import gobject<br>
+from gi.repository import GObject<br>
+from gi.repository import Gdk<br>
<br>
 import pygst<br>
 pygst.require('0.10')<br>
 import gst<br>
 import gst.interfaces<br>
-import gtk<br>
+from gi.repository import Gtk<br>
<br>
 import urllib<br>
 from ControlToolbar import Control, ViewToolbar<br>
@@ -74,70 +70,45 @@ class JukeboxActivity(activity.Activity):<br>
         self.max_participants = 1<br>
         self._playlist_jobject = None<br>
<br>
-        if OLD_TOOLBAR:<br>
-            toolbox = activity.ActivityToolbox(self)<br>
-            self.set_toolbox(toolbox)<br>
-            toolbar = gtk.Toolbar()<br>
-            self.control = Control(toolbar, self)<br>
-            toolbox.add_toolbar(_('Play'), toolbar)<br>
-<br>
-            toolbar.show()<br>
-<br>
-            _view_toolbar = ViewToolbar()<br>
-            _view_toolbar.connect('go-fullscreen',<br>
-                    self.__go_fullscreen_cb)<br>
-            _view_toolbar.connect('toggle-playlist',<br>
-                    self.__toggle_playlist_cb)<br>
-            toolbox.add_toolbar(_('View'), _view_toolbar)<br>
-            _view_toolbar.show()<br>
-<br>
-            toolbox.show()<br>
-<br>
-            toolbar.grab_focus()<br>
-            #self.connect("shared", self._shared_cb)<br>
-            activity_toolbar = toolbox.get_activity_toolbar()<br>
-            activity_toolbar.remove(activity_toolbar.share)<br>
-            activity_toolbar.share = None<br>
-            activity_toolbar.remove(activity_toolbar.keep)<br>
-            activity_toolbar.keep = None<br>
-            self.title_entry = activity_toolbar.title<br>
+        toolbar_box = ToolbarBox()<br>
+        activity_button = ActivityToolbarButton(self)<br>
+        activity_toolbar = activity_button.page<br>
+        toolbar_box.toolbar.insert(activity_button, 0)<br>
+        self.title_entry = activity_toolbar.title<br>
+<br>
+        # FIXME: I don't know what is the mission of this line<br>
+        # activity_toolbar.stop.hide()<br>
+<br>
+        _view_toolbar = ViewToolbar()<br>
+        _view_toolbar.connect('go-fullscreen',<br>
+                              self.__go_fullscreen_cb)<br>
+        _view_toolbar.connect('toggle-playlist',<br>
+                              self.__toggle_playlist_cb)<br>
+        view_toolbar_button = ToolbarButton(<br>
+            page=_view_toolbar,<br>
+            icon_name='toolbar-view')<br>
+        _view_toolbar.show()<br>
+        toolbar_box.toolbar.insert(view_toolbar_button, -1)<br>
+        view_toolbar_button.show()<br>
+<br>
+        self.control = Control(toolbar_box.toolbar, self)<br>
+<br>
+        toolbar_box.toolbar.insert(StopButton(self), -1)<br>
+<br>
+        self.set_toolbar_box(toolbar_box)<br>
+        toolbar_box.show_all()<br>
<br>
-        else:<br>
-            toolbar_box = ToolbarBox()<br>
-            activity_button = ActivityToolbarButton(self)<br>
-            activity_toolbar = activity_button.page<br>
-            toolbar_box.toolbar.insert(activity_button, 0)<br>
-            self.title_entry = activity_toolbar.title<br>
-            activity_toolbar.stop.hide()<br>
-<br>
-            _view_toolbar = ViewToolbar()<br>
-            _view_toolbar.connect('go-fullscreen',<br>
-                    self.__go_fullscreen_cb)<br>
-            _view_toolbar.connect('toggle-playlist',<br>
-                    self.__toggle_playlist_cb)<br>
-            view_toolbar_button = ToolbarButton(<br>
-                    page=_view_toolbar,<br>
-                    icon_name='toolbar-view')<br>
-            _view_toolbar.show()<br>
-            toolbar_box.toolbar.insert(view_toolbar_button, -1)<br>
-            view_toolbar_button.show()<br>
-<br>
-            self.control = Control(toolbar_box.toolbar, self)<br>
-<br>
-            toolbar_box.toolbar.insert(StopButton(self), -1)<br>
-<br>
-            self.set_toolbar_box(toolbar_box)<br>
-            toolbar_box.show_all()<br>
         self.connect("key_press_event", self._key_press_event_cb)<br>
<br>
-        if handle.uri:<br>
-            pass<br>
-        elif self._shared_activity:<br>
-            if self.get_shared():<br>
-                pass<br>
-            else:<br>
-                # Wait for a successful join before trying to get the document<br>
-                self.connect("joined", self._joined_cb)<br>
+        # FIXME: this is related with shared activity and it doesn't work<br>
+        # if handle.uri:<br>
+        #     pass<br>
+        # elif self._shared_activity:<br>
+        #     if self.get_shared():<br>
+        #         pass<br>
+        #     else:<br>
+        #         # Wait for a successful join before trying to get the document<br>
+        #         self.connect("joined", self._joined_cb)<br>
<br>
         self.update_id = -1<br>
         self.changed_id = -1<br>
@@ -162,29 +133,36 @@ class JukeboxActivity(activity.Activity):<br>
         self.p_position = gst.CLOCK_TIME_NONE<br>
         self.p_duration = gst.CLOCK_TIME_NONE<br>
<br>
-        self.bin = gtk.HBox()<br>
-        self.bin.show()<br>
+        # README: I changed this because I was getting an error when I<br>
+        # tried to modify self.bin with something different than<br>
+        # Gtk.Bin<br>
+<br>
+        # self.bin = Gtk.HBox()<br>
+        # self.bin.show()<br>
+<br>
+        self.canvas = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)<br>
+<br>
         self.playlist_widget = PlayListWidget(self.play)<br>
         self.playlist_widget.update(self.playlist)<br>
         self.playlist_widget.show()<br>
-        self.bin.pack_start(self.playlist_widget, expand=False)<br>
-        self._empty_widget = gtk.Label("")<br>
+        self.canvas.pack_start(self.playlist_widget, False, True, 0)<br>
+        self._empty_widget = Gtk.Label(label="")<br>
         self._empty_widget.show()<br>
         self.videowidget = VideoWidget()<br>
         self._switch_canvas(show_video=False)<br>
-        self.set_canvas(self.bin)<br>
+        self.set_canvas(self.canvas)<br>
         self.show_all()<br>
-        self.bin.connect('size-allocate', self.__size_allocate_cb)<br>
+        self.canvas.connect('size-allocate', self.__size_allocate_cb)<br>
<br>
         #From ImageViewer Activity<br>
         self._want_document = True<br>
         if self._object_id is None:<br>
-            self._show_object_picker = gobject.timeout_add(1000, \<br>
+            self._show_object_picker = GObject.timeout_add(1000, \<br>
             self._show_picker_cb)<br>
<br>
         if handle.uri:<br>
             self.uri = handle.uri<br>
-            gobject.idle_add(self._start, self.uri, handle.title)<br>
+            GObject.idle_add(self._start, self.uri, handle.title)<br>
<br>
     def _switch_canvas(self, show_video):<br>
         """Show or hide the video visualization in the canvas.<br>
@@ -194,19 +172,19 @@ class JukeboxActivity(activity.Activity):<br>
<br>
         """<br>
         if show_video:<br>
-            self.bin.remove(self._empty_widget)<br>
-            self.bin.pack_end(self.videowidget)<br>
+            self.canvas.remove(self._empty_widget)<br>
+            self.canvas.pack_end(self.videowidget, True, True, 0)<br>
         else:<br>
-            self.bin.pack_end(self._empty_widget)<br>
-            self.bin.remove(self.videowidget)<br>
-        self.bin.queue_draw()<br>
+            self.canvas.pack_end(self._empty_widget, True, True, 0)<br>
+            self.canvas.remove(self.videowidget)<br>
+        self.canvas.queue_draw()<br>
<br>
     def __get_tags_cb(self, tags_reader, order, tags):<br>
         self.playlist[order]['title'] = tags['title']<br>
         self.playlist_widget.update(self.playlist)<br>
<br>
     def __size_allocate_cb(self, widget, allocation):<br>
-        canvas_size = self.bin.get_allocation()<br>
+        canvas_size = self.canvas.get_allocation()<br>
         playlist_width = int(canvas_size.width * PLAYLIST_WIDTH_PROP)<br>
         self.playlist_widget.set_size_request(playlist_width, 0)<br>
<br>
@@ -219,10 +197,10 @@ class JukeboxActivity(activity.Activity):<br>
         #self.currentplaying = None<br>
         #self.playflag = False<br>
         self._want_document = True<br>
-        self._show_object_picker = gobject.timeout_add(1, self._show_picker_cb)<br>
+        self._show_object_picker = GObject.timeout_add(1, self._show_picker_cb)<br>
<br>
     def _key_press_event_cb(self, widget, event):<br>
-        keyname = gtk.gdk.keyval_name(event.keyval)<br>
+        keyname = Gdk.keyval_name(event.keyval)<br>
         <a href="http://logging.info" target="_blank">logging.info</a>("Keyname Press: %s, time: %s", keyname, event.time)<br>
         if self.title_entry.has_focus():<br>
             return False<br>
@@ -289,10 +267,10 @@ class JukeboxActivity(activity.Activity):<br>
         self.player.stop()<br>
         self.player.set_uri(None)<br>
         self.control.set_disabled()<br>
-        self.bin.remove(self.videowidget)<br>
-        text = gtk.Label("Error: %s - %s" % (message, detail))<br>
+        self.canvas.remove(self.videowidget)<br>
+        text = Gtk.Label("Error: %s - %s" % (message, detail))<br>
         text.show_all()<br>
-        self.bin.add(text)<br>
+        self.canvas.add(text)<br>
<br>
     def _player_new_tag_cb(self, widget, tag, value):<br>
         if not tag in [gst.TAG_TITLE, gst.TAG_ARTIST, gst.TAG_ALBUM]:<br>
@@ -342,14 +320,18 @@ class JukeboxActivity(activity.Activity):<br>
         if not self._want_document:<br>
             return<br>
<br>
-        chooser = ObjectChooser(_('Choose document'), self,<br>
-            gtk.DIALOG_MODAL |<br>
-            gtk.DIALOG_DESTROY_WITH_PARENT,<br>
-            what_filter=mime.GENERIC_TYPE_AUDIO)<br>
+        # README: some arguments are deprecated so I avoid them<br>
+<br>
+        # chooser = ObjectChooser(_('Choose document'), self,<br>
+        #     Gtk.DialogFlags.MODAL |<br>
+        #     Gtk.DialogFlags.DESTROY_WITH_PARENT,<br>
+        #     what_filter=mime.GENERIC_TYPE_AUDIO)<br>
+<br>
+        chooser = ObjectChooser(self, what_filter=mime.GENERIC_TYPE_AUDIO)<br>
<br>
         try:<br>
             result = chooser.run()<br>
-            if result == gtk.RESPONSE_ACCEPT:<br>
+            if result == Gtk.ResponseType.ACCEPT:<br>
                 jobject = chooser.get_selected_object()<br>
                 if jobject and jobject.file_path:<br>
                     logging.error('Adding %s', jobject.file_path)<br>
@@ -376,11 +358,11 @@ class JukeboxActivity(activity.Activity):<br>
         if mimetype == 'audio/x-mpegurl':<br>
             # is a M3U playlist:<br>
             for uri in self._read_m3u_playlist(file_path):<br>
-                gobject.idle_add(self._start, uri['url'], uri['title'],<br>
+                GObject.idle_add(self._start, uri['url'], uri['title'],<br>
                         uri['object_id'])<br>
         else:<br>
             # is another media file:<br>
-            gobject.idle_add(self._start, self.uri, title, object_id)<br>
+            GObject.idle_add(self._start, self.uri, title, object_id)<br>
<br>
     def _create_playlist_jobject(self):<br>
         """Create an object in the Journal to store the playlist.<br>
@@ -536,7 +518,7 @@ class JukeboxActivity(activity.Activity):<br>
             else:<br>
                 self.player.play()<br>
                 if self.update_id == -1:<br>
-                    self.update_id = gobject.timeout_add(self.UPDATE_INTERVAL,<br>
+                    self.update_id = GObject.timeout_add(self.UPDATE_INTERVAL,<br>
                                                          self.update_scale_cb)<br>
                 self.control.set_button_pause()<br>
<br>
@@ -552,7 +534,7 @@ class JukeboxActivity(activity.Activity):<br>
<br>
         # don't timeout-update position during seek<br>
         if self.update_id != -1:<br>
-            gobject.source_remove(self.update_id)<br>
+            GObject.source_remove(self.update_id)<br>
             self.update_id = -1<br>
<br>
         # make sure we get changed notifies<br>
@@ -574,7 +556,7 @@ class JukeboxActivity(activity.Activity):<br>
<br>
         self.control.button.set_sensitive(True)<br>
         if self.seek_timeout_id != -1:<br>
-            gobject.source_remove(self.seek_timeout_id)<br>
+            GObject.source_remove(self.seek_timeout_id)<br>
             self.seek_timeout_id = -1<br>
         else:<br>
             if self.was_playing:<br>
@@ -583,7 +565,7 @@ class JukeboxActivity(activity.Activity):<br>
         if self.update_id != -1:<br>
             self.error('Had a previous update timeout id')<br>
         else:<br>
-            self.update_id = gobject.timeout_add(self.UPDATE_INTERVAL,<br>
+            self.update_id = GObject.timeout_add(self.UPDATE_INTERVAL,<br>
                 self.update_scale_cb)<br>
<br>
     def update_scale_cb(self):<br>
@@ -617,17 +599,17 @@ class JukeboxActivity(activity.Activity):<br>
             self.playlist_widget.hide()<br>
         else:<br>
             self.playlist_widget.show_all()<br>
-        self.bin.queue_draw()<br>
+        self.canvas.queue_draw()<br>
<br>
<br>
-class TagReader(gobject.GObject):<br>
+class TagReader(GObject.GObject):<br>
<br>
     __gsignals__ = {<br>
-        'get-tags': (gobject.SIGNAL_RUN_FIRST, None, [int, object]),<br>
+        'get-tags': (GObject.SignalFlags.RUN_FIRST, None, [int, object]),<br>
     }<br>
<br>
     def __init__(self):<br>
-        gobject.GObject.__init__(self)<br>
+        GObject.GObject.__init__(self)<br>
         #make a playbin to parse the audio file<br>
         self.pbin = gst.element_factory_make('playbin', 'player')<br>
         fakesink = gst.element_factory_make('fakesink', 'fakesink')<br>
@@ -661,17 +643,17 @@ class TagReader(gobject.GObject):<br>
         self.pbin.set_state(gst.STATE_PAUSED)<br>
<br>
<br>
-class GstPlayer(gobject.GObject):<br>
+class GstPlayer(GObject.GObject):<br>
<br>
     __gsignals__ = {<br>
-        'error': (gobject.SIGNAL_RUN_FIRST, None, [str, str]),<br>
-        'eos': (gobject.SIGNAL_RUN_FIRST, None, []),<br>
-        'tag': (gobject.SIGNAL_RUN_FIRST, None, [str, str]),<br>
-        'stream-info': (gobject.SIGNAL_RUN_FIRST, None, [object])<br>
+        'error': (GObject.SignalFlags.RUN_FIRST, None, [str, str]),<br>
+        'eos': (GObject.SignalFlags.RUN_FIRST, None, []),<br>
+        'tag': (GObject.SignalFlags.RUN_FIRST, None, [str, str]),<br>
+        'stream-info': (GObject.SignalFlags.RUN_FIRST, None, [object])<br>
     }<br>
<br>
     def __init__(self, videowidget):<br>
-        gobject.GObject.__init__(self)<br>
+        GObject.GObject.__init__(self)<br>
<br>
         self.playing = False<br>
         self.error = False<br>
@@ -689,7 +671,7 @@ class GstPlayer(gobject.GObject):<br>
         self.overlay = None<br>
         videowidget.realize()<br>
         self.videowidget = videowidget<br>
-        self.videowidget_xid = videowidget.window.xid<br>
+        self.videowidget_xid = videowidget.get_window().get_xid()<br>
         self._init_video_sink()<br>
<br>
         bus = self.player.get_bus()<br>
@@ -831,17 +813,18 @@ class GstPlayer(gobject.GObject):<br>
         return self.playing<br>
<br>
<br>
-class VideoWidget(gtk.DrawingArea):<br>
+class VideoWidget(Gtk.DrawingArea):<br>
     def __init__(self):<br>
-        gtk.DrawingArea.__init__(self)<br>
-        self.set_events(gtk.gdk.POINTER_MOTION_MASK |<br>
-        gtk.gdk.POINTER_MOTION_HINT_MASK |<br>
-        gtk.gdk.EXPOSURE_MASK |<br>
-        gtk.gdk.KEY_PRESS_MASK |<br>
-        gtk.gdk.KEY_RELEASE_MASK)<br>
+        GObject.GObject.__init__(self)<br>
+        self.set_events(Gdk.EventMask.POINTER_MOTION_MASK |<br>
+        Gdk.EventMask.POINTER_MOTION_HINT_MASK |<br>
+        Gdk.EventMask.EXPOSURE_MASK |<br>
+        Gdk.EventMask.KEY_PRESS_MASK |<br>
+        Gdk.EventMask.KEY_RELEASE_MASK)<br>
         self.imagesink = None<br>
-        self.unset_flags(gtk.DOUBLE_BUFFERED)<br>
-        self.set_flags(gtk.APP_PAINTABLE)<br>
+<br>
+        self.set_app_paintable(True)<br>
+        self.set_double_buffered(False)<br>
<br>
     def do_expose_event(self, event):<br>
         if self.imagesink:<br>
@@ -856,7 +839,7 @@ class VideoWidget(gtk.DrawingArea):<br>
<br>
<br>
 if __name__ == '__main__':<br>
-    window = gtk.Window()<br>
+    window = Gtk.Window()<br>
<br>
     view = VideoWidget()<br>
<br>
@@ -873,4 +856,4 @@ if __name__ == '__main__':<br>
     player.set_uri('<a href="http://78.46.73.237:8000/prog" target="_blank">http://78.46.73.237:8000/prog</a>')<br>
     player.play()<br>
     window.show_all()<br>
-    gtk.main()<br>
+    Gtk.main()<br>
diff --git a/setup.py b/setup.py<br>
index d3ab3a3..2f2c143 100755<br>
--- a/setup.py<br>
+++ b/setup.py<br>
@@ -16,6 +16,6 @@<br>
 # along with this program; if not, write to the Free Software<br>
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA<br>
<br>
-from sugar.activity import bundlebuilder<br>
+from sugar3.activity import bundlebuilder<br>
<br>
 bundlebuilder.start()<br>
diff --git a/widgets.py b/widgets.py<br>
index bd09a73..2dd5742 100644<br>
--- a/widgets.py<br>
+++ b/widgets.py<br>
@@ -16,41 +16,41 @@<br>
 import logging<br>
 from gettext import gettext as _<br>
<br>
-import pygtk<br>
-pygtk.require('2.0')<br>
+import gi<br>
+gi.require_version('Gtk', '3.0')<br>
<br>
-import gobject<br>
-import gtk<br>
-import pango<br>
+from gi.repository import GObject<br>
+from gi.repository import Gtk<br>
+from gi.repository import Pango<br>
<br>
<br>
 COLUMNS_NAME = ('index', 'media')<br>
 COLUMNS = dict((name, i) for i, name in enumerate(COLUMNS_NAME))<br>
<br>
<br>
-class PlayListWidget(gtk.ScrolledWindow):<br>
+class PlayListWidget(Gtk.ScrolledWindow):<br>
     def __init__(self, play_callback):<br>
         self._playlist = None<br>
         self._play_callback = play_callback<br>
<br>
-        gtk.ScrolledWindow.__init__(self, hadjustment=None,<br>
+        GObject.GObject.__init__(self, hadjustment=None,<br>
                                     vadjustment=None)<br>
-        self.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)<br>
-        self.listview = gtk.TreeView()<br>
-        self.treemodel = gtk.ListStore(int, object)<br>
+        self.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)<br>
+        self.listview = Gtk.TreeView()<br>
+        self.treemodel = Gtk.ListStore(int, object)<br>
         self.listview.set_model(self.treemodel)<br>
         selection = self.listview.get_selection()<br>
-        selection.set_mode(gtk.SELECTION_SINGLE)<br>
+        selection.set_mode(Gtk.SelectionMode.SINGLE)<br>
<br>
-        renderer_idx = gtk.CellRendererText()<br>
-        treecol_idx = gtk.TreeViewColumn(_('No.'))<br>
+        renderer_idx = Gtk.CellRendererText()<br>
+        treecol_idx = Gtk.TreeViewColumn(_('No.'))<br>
         treecol_idx.pack_start(renderer_idx, True)<br>
         treecol_idx.set_cell_data_func(renderer_idx, self._set_number)<br>
         self.listview.append_column(treecol_idx)<br>
<br>
-        renderer_title = gtk.CellRendererText()<br>
-        renderer_title.set_property('ellipsize', pango.ELLIPSIZE_END)<br>
-        treecol_title = gtk.TreeViewColumn(_('Play List'))<br>
+        renderer_title = Gtk.CellRendererText()<br>
+        renderer_title.set_property('ellipsize', Pango.EllipsizeMode.END)<br>
+        treecol_title = Gtk.TreeViewColumn(_('Play List'))<br>
         treecol_title.pack_start(renderer_title, True)<br>
         treecol_title.set_cell_data_func(renderer_title, self._set_title)<br>
         self.listview.append_column(treecol_title)<br>
@@ -64,14 +64,16 @@ class PlayListWidget(gtk.ScrolledWindow):<br>
<br>
     def __on_row_activated(self, treeview, path, col):<br>
         model = treeview.get_model()<br>
-        media_idx = path[COLUMNS['index']]<br>
+<br>
+        treeiter = model.get_iter(path)<br>
+        media_idx = model.get_value(treeiter, COLUMNS['index'])<br>
         self._play_callback(media_idx)<br>
<br>
-    def _set_number(self, column, cell, model, it):<br>
+    def _set_number(self, column, cell, model, it, data):<br>
         idx = model.get_value(it, COLUMNS['index'])<br>
         cell.set_property('text', idx + 1)<br>
<br>
-    def _set_title(self, column, cell, model, it):<br>
+    def _set_title(self, column, cell, model, it, data):<br>
         playlist_item = model.get_value(it, COLUMNS['media'])<br>
         cell.set_property('text', playlist_item['title'])<br>
<br>
@@ -90,6 +92,7 @@ class PlayListWidget(gtk.ScrolledWindow):<br>
         selection = self.listview.get_selection()<br>
         sel_model, sel_rows = self.listview.get_selection().get_selected_rows()<br>
         for row in sel_rows:<br>
-            self._playlist.pop(row[0])<br>
+            index = sel_model.get_value(sel_model.get_iter(row), 0)<br>
+            self._playlist.pop(index)<br>
             self.treemodel.remove(self.treemodel.get_iter(row))<br>
         self.update(self._playlist)<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.7.10.4<br>
<br>
</font></span></blockquote></div><br></div>