[pitivi] Port everything to PyGI and remove pygtkcompat



commit e6e84d90ef1faf319870ce1c3efe05095a6c630d
Author: Thibault Saunier <thibault saunier collabora com>
Date:   Thu Aug 30 17:19:55 2012 -0700

    Port everything to PyGI and remove pygtkcompat

 bin/pitivi.in                                      |   24 +-
 pitivi/application.py                              |   21 +-
 pitivi/autoaligner.py                              |   26 +-
 pitivi/check.py                                    |   78 ++-
 pitivi/clipproperties.py                           |  118 ++--
 pitivi/dialogs/clipmediaprops.py                   |   14 +-
 pitivi/dialogs/depsmanager.py                      |    6 +-
 pitivi/dialogs/filelisterrordialog.py              |   22 +-
 pitivi/dialogs/prefs.py                            |   32 +-
 pitivi/dialogs/startupwizard.py                    |   18 +-
 pitivi/effects.py                                  |  113 ++--
 pitivi/mainwindow.py                               |  277 ++++----
 pitivi/mediafilespreviewer.py                      |  172 +++---
 pitivi/medialibrary.py                             |  230 +++---
 pitivi/preset.py                                   |   14 +-
 pitivi/project.py                                  |   76 +-
 pitivi/render.py                                   |  104 ++--
 pitivi/settings.py                                 |   16 +-
 pitivi/tabsmanager.py                              |   16 +-
 pitivi/timeline/curve.py                           |   23 +-
 pitivi/timeline/layer.py                           |   32 +-
 pitivi/timeline/ruler.py                           |   69 +-
 pitivi/timeline/thumbnailer.py                     |  123 ++--
 pitivi/timeline/timeline.py                        |  310 ++++----
 pitivi/timeline/track.py                           |  156 +++--
 pitivi/titleeditor.py                              |  268 +++++--
 pitivi/transitions.py                              |   82 ++-
 pitivi/undo/effect.py                              |   22 +-
 pitivi/utils/extract.py                            |   26 +-
 pitivi/utils/misc.py                               |   52 +-
 pitivi/utils/pipeline.py                           |  133 ++--
 pitivi/utils/pygtkcompat.py                        |  752 --------------------
 pitivi/utils/ripple_update_group.py                |    6 +-
 pitivi/utils/system.py                             |   12 +-
 pitivi/utils/timeline.py                           |   69 +-
 pitivi/utils/ui.py                                 |   96 ++--
 pitivi/utils/widgets.py                            |  255 ++++----
 pitivi/viewer.py                                   |  142 ++--
 tests/__init__.py                                  |    6 +-
 tests/common.py                                    |    4 +-
 tests/dogtail_scripts/helper_functions.py          |   34 +-
 tests/dogtail_scripts/test_base.py                 |    4 +-
 tests/dogtail_scripts/test_clipproperties.py       |   50 +-
 .../dogtail_scripts/test_dialogs_clipmediaprops.py |   14 +-
 tests/dogtail_scripts/test_dialogs_prefs.py        |   32 +-
 .../dogtail_scripts/test_dialogs_startupwizard.py  |    8 +-
 tests/dogtail_scripts/test_effects.py              |   20 +-
 tests/dogtail_scripts/test_medialibrary.py         |    2 +-
 tests/dogtail_scripts/test_project.py              |   54 +-
 tests/dogtail_scripts/test_timeline.py             |   20 +-
 tests/runtests.py                                  |    6 +-
 tests/test_cache.py                                |    4 +-
 tests/test_integration.py                          |  186 +++---
 tests/test_projectmanager.py                       |    6 +-
 tests/test_still_image.py                          |   16 +-
 tests/test_timeline_undo.py                        |   36 +-
 tests/test_utils.py                                |    4 +-
 57 files changed, 1967 insertions(+), 2544 deletions(-)
---
diff --git a/bin/pitivi.in b/bin/pitivi.in
index 0322b5f..c5b530e 100644
--- a/bin/pitivi.in
+++ b/bin/pitivi.in
@@ -21,6 +21,7 @@
 # Boston, MA 02110-1301, USA.
 
 import os
+import gi
 import sys
 import string
 import locale
@@ -93,24 +94,27 @@ def _add_pitivi_path():
             # ld caches LD_LIBRARY_PATH at startup so we need to execv() here. LALA.
             jump_through_hoops()
 
+
 def _init_gobject_gtk_gst_ges():
     global localedir
     try:
-        import pitivi.utils.pygtkcompat
-        pitivi.utils.pygtkcompat.enable()
-        pitivi.utils.pygtkcompat.enable_gtk(version='3.0')
-        from gi.repository import GdkX11
-        GdkX11 #pyflakes
+        gi.require_version('Gtk', '3.0')
+        from gi.repository import Gtk
+        Gtk #pyflakes
     except ImportError, e:
         raise SystemExit("PyGTK couldn't be found !", str(e))
 
     try:
-        pitivi.utils.pygtkcompat.enable_gst()
+        gi.require_version('Gst', '1.0')
+        from gi.repository import Gst
+        Gst #pyflakes
     except ImportError:
-        raise SystemExit("Gst-Python couldn't be found!")
+        raise SystemExit("Gst 1.0 couldn't be found!")
 
     try:
-        pitivi.utils.pygtkcompat.enable_ges()
+        gi.require_version('GES', '1.0')
+        from gi.repository import GES
+        GES #pyflakes
     except ImportError:
         raise SystemExit("GStreamer Editing Services couldn't be found!")
 
@@ -119,7 +123,9 @@ def _init_gobject_gtk_gst_ges():
     GObject.threads_init()
 
     try:
-        pitivi.utils.pygtkcompat.enable_goocanvas()
+        gi.require_version('GooCanvas', '2.0')
+        from gi.repository import GooCanvas
+        GooCanvas # pyflakes
     except ImportError:
         raise SystemExit("GooCanvas couldn't be found!")
 
diff --git a/pitivi/application.py b/pitivi/application.py
index 42aa8e2..45a44dc 100644
--- a/pitivi/application.py
+++ b/pitivi/application.py
@@ -24,13 +24,13 @@
 """
 Main application
 """
-import gobject
-import gtk
 import os
 import sys
 import urllib
-import ges
-import gio
+from gi.repository import GES
+from gi.repository import Gio
+from gi.repository import GObject
+from gi.repository import Gtk
 
 from gettext import gettext as _
 from optparse import OptionParser
@@ -214,7 +214,7 @@ class Pitivi(Loggable, Signallable):
 
     # check if for version information online
     def _checkVersion(self):
-        giofile = gio.File.new_for_uri(RELEASES_URL)
+        giofile = Gio.File.new_for_uri(RELEASES_URL)
         self.info("Requesting version information")
         giofile.load_contents_async(None, self._versionInfoReceivedCb, None)
 
@@ -249,7 +249,7 @@ class InteractivePitivi(Pitivi):
 
     def __init__(self, debug=False):
         Pitivi.__init__(self)
-        self.mainloop = gobject.MainLoop()
+        self.mainloop = GObject.MainLoop()
         self.actioner = None
         self.gui = None
 
@@ -291,6 +291,7 @@ class InteractivePitivi(Pitivi):
 
     def run(self):
         """Runs the main loop."""
+        print "SELF,", self
         self.mainloop.run()
 
 
@@ -304,8 +305,8 @@ class GuiPitivi(InteractivePitivi):
         self._showGui()
 
     def _showStartupError(self, message, detail):
-        dialog = gtk.MessageDialog(type=gtk.MESSAGE_ERROR,
-                                   buttons=gtk.BUTTONS_OK)
+        dialog = Gtk.MessageDialog(type=Gtk.MessageType.ERROR,
+                                   buttons=Gtk.ButtonsType.OK)
         dialog.set_icon_name("pitivi")
         dialog.set_markup("<b>" + message + "</b>")
         dialog.format_secondary_text(detail)
@@ -315,7 +316,7 @@ class GuiPitivi(InteractivePitivi):
         self.shutdown()
 
     def _createGui(self):
-        """Returns a gtk.Widget which represents the UI."""
+        """Returns a Gtk.Widget which represents the UI."""
         raise NotImplementedError()
 
     def _showGui(self):
@@ -368,7 +369,7 @@ class ProjectCreatorGuiPitivi(FullGuiPitivi):
         if self._maybePopStartupUri(startup_uris, info.get_uri()) \
                 and add_to_timeline:
             self.action_log.begin("add clip")
-            src = ges.TimelineFileSource(uri=info.get_uri())
+            src = GES.TimelineFileSource(uri=info.get_uri())
             src.set_property("priority", 1)
             self.current.timeline.get_layers()[0].add_object(src)
             self.action_log.commit()
diff --git a/pitivi/autoaligner.py b/pitivi/autoaligner.py
index 5ef1af9..cfc9109 100644
--- a/pitivi/autoaligner.py
+++ b/pitivi/autoaligner.py
@@ -24,11 +24,11 @@
 Classes for automatic alignment of L{TimelineObject}s
 """
 
-import gobject
-import gst
+from gi.repository import GObject
+from gi.repository import Gst
 import array
 import time
-import gtk
+from gi.repository import Gtk
 import os
 
 
@@ -374,7 +374,7 @@ class ProgressAggregator(ProgressMeter):
 
         def cb(thusfar):
             self._portions[i] = thusfar
-            gobject.idle_add(self._callForward)
+            GObject.idle_add(self._callForward)
         return cb
 
     def addWatcher(self, function):
@@ -382,7 +382,7 @@ class ProgressAggregator(ProgressMeter):
 
     def _callForward(self):
         # This function always returns False so that it may be safely
-        # invoked via gobject.idle_add(). Use of idle_add() is necessary
+        # invoked via GObject.idle_add(). Use of idle_add() is necessary
         # to ensure that watchers are always called from the main thread,
         # even if progress updates are received from other threads.
         total_target = sum(self._targets)
@@ -393,7 +393,7 @@ class ProgressAggregator(ProgressMeter):
         now = time.time()
         remaining = (now - self._start) * (1 - frac) / frac
         for function in self._watchers:
-            function(frac, beautify_ETA(int(remaining * gst.SECOND)))
+            function(frac, beautify_ETA(int(remaining * Gst.SECOND)))
         return False
 
 
@@ -585,13 +585,13 @@ class AutoAligner(Loggable):
                 # numsamples is the total number of samples in the track,
                 # which is used by progress_aggregator to determine
                 # the percent completion.
-                numsamples = ((audiotrack.duration / gst.SECOND) *
+                numsamples = ((audiotrack.duration / Gst.SECOND) *
                               audiotrack.stream.rate)
                 extractee.addWatcher(
                         progress_aggregator.getPortionCB(numsamples))
                 self._extraction_stack.append((audiotrack, extractee))
             # After we return, start the extraction cycle.
-            # This gobject.idle_add call should not be necessary;
+            # This GObject.idle_add call should not be necessary;
             # we should be able to invoke _extractNextEnvelope directly
             # here.  However, there is some as-yet-unexplained
             # race condition between the Python GIL, GTK UI updates,
@@ -599,10 +599,10 @@ class AutoAligner(Loggable):
             # occasional deadlocks during autoalignment.
             # This call to idle_add() reportedly eliminates the deadlock.
             # No one knows why.
-            gobject.idle_add(self._extractNextEnvelope)
+            GObject.idle_add(self._extractNextEnvelope)
         else:  # We can't do anything without at least two audio tracks
             # After we return, call the callback function (once)
-            gobject.idle_add(call_false, self._callback)
+            GObject.idle_add(call_false, self._callback)
         return progress_aggregator
 
     def _chooseReference(self):
@@ -636,7 +636,7 @@ class AutoAligner(Loggable):
         offsets = rigidalign(reference_envelope, envelopes)
         for (movable, envelope), offset in zip(pairs, offsets):
             # tshift is the offset rescaled to units of nanoseconds
-            tshift = int((offset * gst.SECOND) / self.BLOCKRATE)
+            tshift = int((offset * Gst.SECOND) / self.BLOCKRATE)
             self.debug("Shifting %s to %i ns from %i",
                        movable, tshift, reference.start)
             newstart = reference.start + tshift
@@ -658,7 +658,7 @@ class AlignmentProgressDialog:
         (read-only, no buttons)."""
 
     def __init__(self, app):
-        self.builder = gtk.Builder()
+        self.builder = Gtk.Builder()
         self.builder.add_from_file(os.path.join(configure.get_ui_dir(),
                                    "alignmentprogress.ui"))
         self.builder.connect_signals(self)
@@ -671,7 +671,7 @@ class AlignmentProgressDialog:
         # taken from RenderingProgressDialog.  In both cases, it appears
         # to work correctly, although there is a known bug for Gnome 3 in
         # RenderingProgressDialog (bug #652917)
-        self.window.set_transient_for(app.gui)
+        self.set_transient_for(app.gui)
 
         # UI widgets
         # We currently reuse the render icon for this dialog.
diff --git a/pitivi/check.py b/pitivi/check.py
index 305d336..ad8dec1 100644
--- a/pitivi/check.py
+++ b/pitivi/check.py
@@ -23,8 +23,9 @@
 Runtime checks.
 """
 
-import gtk
-import gst
+from gi.repository import Gdk
+from gi.repository import Gtk
+from gi.repository import Gst
 
 from gettext import gettext as _
 
@@ -40,10 +41,10 @@ def initiate_videosinks():
     Test if the autovideosink element can initiate, return TRUE if it is the
     case.
     """
-    sink = gst.element_factory_make("autovideosink")
-    if not sink.set_state(gst.STATE_READY):
+    sink = Gst.ElementFactory.make("autovideosink", None)
+    if not sink.set_state(Gst.State.READY):
         return False
-    sink.set_state(gst.STATE_NULL)
+    sink.set_state(Gst.State.NULL)
     return True
 
 
@@ -52,13 +53,25 @@ def initiate_audiosinks():
     Test if the autoaudiosink element can initiate, return TRUE if it is the
     case.
     """
-    sink = gst.element_factory_make("autoaudiosink")
-    if not sink.set_state(gst.STATE_READY):
+    sink = Gst.ElementFactory.make("autoaudiosink", None)
+    if not sink.set_state(Gst.State.READY):
         return False
-    sink.set_state(gst.STATE_NULL)
+    sink.set_state(Gst.State.NULL)
     return True
 
 
+def __try_import_from_gi__(modulename):
+    """
+    Attempt to load given module.
+    Returns True on success, else False.
+    """
+    try:
+        __import__("gi.repository." + modulename)
+        return True
+    except:
+        return False
+
+
 def __try_import__(modulename):
     """
     Attempt to load given module.
@@ -86,31 +99,29 @@ def check_required_version(modulename):
     containing the strings of the required version and the installed version.
     This function does not check for the existence of the given module !
     """
-    if modulename == "pygtk":
-        if list(gtk.pygtk_version) < _string_to_list(PYGTK_REQ):
-            return [PYGTK_REQ, _version_to_string(gtk.pygtk_version)]
     if modulename == "gtk":
-        if list(gtk.gtk_version) < _string_to_list(GTK_REQ):
-            return [GTK_REQ, _version_to_string(gtk.gtk_version)]
-    if modulename == "pygst":
-        if list(gst.get_pygst_version()) < _string_to_list(PYGST_REQ):
-            return [PYGST_REQ, _version_to_string(gst.get_pygst_version())]
+        if list((Gtk.MAJOR_VERSION, Gtk.MINOR_VERSION, Gtk.MICRO_VERSION)) < \
+                _string_to_list(GTK_REQ):
+            return [GTK_REQ, _version_to_string((Gtk.MAJOR_VERSION,
+                       Gtk.MINOR_VERSION, Gtk.MICRO_VERSION))]
     if modulename == "cairo":
         import cairo
         if _string_to_list(cairo.cairo_version_string()) < _string_to_list(PYCAIRO_REQ):
             return [PYCAIRO_REQ, cairo.cairo_version_string()]
     if modulename == "gst":
-        if list(gst.get_gst_version()) < _string_to_list(GST_REQ):
-            return [GST_REQ, _version_to_string(gst.get_gst_version())]
+        if list(Gst.version()) < _string_to_list(GST_REQ):
+            return [GST_REQ, _version_to_string(Gst.version())]
     if modulename == "gnonlin":
-        gnlver = gst.registry_get_default().find_plugin("gnonlin").get_version()
+        gnlver = Gst.Registry.get().find_plugin("gnonlin").get_version()
         if _string_to_list(gnlver) < _string_to_list(GNONLIN_REQ):
             return [GNONLIN_REQ, gnlver]
     return [None, None]
 
 
 def initial_checks():
-    reg = gst.registry_get_default()
+    Gst.init(None)
+    reg = Gst.Registry.get()
+
     if PiTiVi:
         return (_("%s is already running") % APPNAME,
                 _("An instance of %s is already running in this script.") % APPNAME)
@@ -120,7 +131,7 @@ def initial_checks():
     if not reg.find_plugin("autodetect"):
         return (_("Could not find the autodetect plugins"),
                 _("Make sure you have installed gst-plugins-good and that it's available in the GStreamer plugin path."))
-    if not hasattr(gtk.gdk.Window, 'cairo_create'):
+    if not hasattr(Gdk.Window, 'cairo_create'):
         return (_("PyGTK doesn't have cairo support"),
                 _("Please use a version of the GTK+ Python bindings built with cairo support."))
     if not initiate_videosinks():
@@ -129,19 +140,15 @@ def initial_checks():
     if not initiate_audiosinks():
         return (_("Could not initiate the audio output plugins"),
                 _("Make sure you have at least one valid audio output sink available (alsasink or osssink)."))
-    if not __try_import__("cairo"):
+    if not __try_import_from_gi__("cairo"):
         return (_("Could not import the cairo Python bindings"),
                 _("Make sure you have the cairo Python bindings installed."))
-    if not __try_import__("goocanvas"):
+    if not __try_import_from_gi__("GooCanvas"):
         return (_("Could not import the goocanvas Python bindings"),
                 _("Make sure you have the goocanvas Python bindings installed."))
     if not __try_import__("xdg"):
         return (_("Could not import the xdg Python library"),
                 _("Make sure you have the xdg Python library installed."))
-    req, inst = check_required_version("pygtk")
-    if req:
-        return (_("You do not have a recent enough version of the GTK+ Python bindings (your version %s)") % inst,
-                _("Install a version of the GTK+ Python bindings greater than or equal to %s.") % req)
     req, inst = check_required_version("gtk")
     if req:
         return (_("You do not have a recent enough version of GTK+ (your version %s)") % inst,
@@ -162,7 +169,7 @@ def initial_checks():
     if req:
         return (_("You do not have a recent enough version of the GNonLin GStreamer plugin (your version %s)") % inst,
                 _("Install a version of the GNonLin GStreamer plugin greater than or equal to %s.") % req)
-    if not __try_import__("ges"):
+    if not __try_import_from_gi__("GES"):
         #FIXME enable version checking in GES
         return (_("Could not import GStreamer Editing Services "),
                 _("Make sure you have GStreamer Editing Services installed."))
@@ -171,23 +178,20 @@ def initial_checks():
                 _("Make sure you have the distutils Python module installed."))
 
     # The following are soft dependencies
-    # Note that instead of checking for plugins using gst.registry_get_default().find_plugin("foo"),
-    # we could check for elements using gst.element_factory_make("foo")
+    # Note that instead of checking for plugins using Gst.Registry.get().find_plugin("foo"),
+    # we could check for elements using Gst.ElementFactory.make("foo")
     if not __try_import__("numpy"):
         soft_deps["NumPy"] = _("Enables the autoalign feature")
-    try:
-        #if not gst.registry_get_default().find_plugin("frei0r"):
-        gst.element_factory_make("frei0r-filter-scale0tilt")
-    except gst.ElementNotFoundError:
+    if Gst.ElementFactory.make("frei0r-filter-scale0tilt", None) is None:
         soft_deps["Frei0r"] = _("Additional video effects")
-    if not gst.registry_get_default().find_plugin("libav"):
+    if not Gst.Registry.get().find_plugin("libav"):
         soft_deps["GStreamer Libav plugin"] = _('Additional multimedia codecs through the Libav library')
     # Test for gst bad
     # This is disabled because, by definition, gst bad is a set of plugins that can
     # move to gst good or ugly, and we don't really have something to rely upon.
-    #if not gst.registry_get_default().find_plugin("swfdec"): # FIXME: find a more representative plugin
+    #if not Gst.Registry.get().find_plugin("swfdec"): # FIXME: find a more representative plugin
     #    soft_deps["GStreamer bad plugins"] = _('Additional GStreamer plugins whose code is not of good enough quality, or are not considered tested well enough. The licensing may or may not be LGPL')
     # Test for gst ugly
-    #if not gst.registry_get_default().find_plugin("x264"):
+    #if not Gst.Registry.get().find_plugin("x264"):
     #    soft_deps["GStreamer ugly plugins"] = _('Additional good quality GStreamer plugins whose license is not LGPL or with licensing issues')
     return None
diff --git a/pitivi/clipproperties.py b/pitivi/clipproperties.py
index 4a93fad..9d164c4 100644
--- a/pitivi/clipproperties.py
+++ b/pitivi/clipproperties.py
@@ -22,10 +22,12 @@
 """
 Class handling the midle pane
 """
-import gtk
-import pango
 import os
-import ges
+
+from gi.repository import Gtk
+from gi.repository import Gdk
+from gi.repository import Pango
+from gi.repository import GES
 
 from gettext import gettext as _
 
@@ -56,43 +58,43 @@ class ClipPropertiesError(Exception):
 
 def compare_type(track, effect_type):
 
-    if track.get_property("track_type") == ges.TRACK_TYPE_AUDIO and \
+    if track.get_property("track_type") == GES.TrackType.AUDIO and \
             effect_type == AUDIO_EFFECT:
         return True
-    elif track.get_property("track_type") == ges.TRACK_TYPE_VIDEO and \
+    elif track.get_property("track_type") == GES.TrackType.VIDEO and \
              effect_type == VIDEO_EFFECT:
         return True
     return False
 
 
-class ClipProperties(gtk.ScrolledWindow, Loggable):
+class ClipProperties(Gtk.ScrolledWindow, Loggable):
     """
     Widget for configuring clips properties
     """
 
     def __init__(self, instance, uiman):
-        gtk.ScrolledWindow.__init__(self)
+        Gtk.ScrolledWindow.__init__(self)
         Loggable.__init__(self)
         self.app = instance
         self.settings = instance.settings
         self._project = None
 
-        self.infobar_box = gtk.VBox()
+        self.infobar_box = Gtk.VBox()
         effect_properties_handling = EffectsPropertiesManager(instance)
         self.effect_expander = EffectProperties(instance, effect_properties_handling, self)
         self.transformation_expander = TransformationProperties(instance, instance.action_log)
         self.effect_expander.set_vexpand(False)
         self.transformation_expander.set_vexpand(False)
 
-        vbox = gtk.VBox()
+        vbox = Gtk.VBox()
         vbox.set_spacing(SPACING)
-        vbox.pack_start(self.infobar_box, expand=False, fill=True)
-        vbox.pack_start(self.transformation_expander, expand=False, fill=True)
-        vbox.pack_start(self.effect_expander, expand=True, fill=True)
+        vbox.pack_start(self.infobar_box, False, True, 0)
+        vbox.pack_start(self.transformation_expander, False, True, 0)
+        vbox.pack_start(self.effect_expander, True, True, 0)
 
-        viewport = gtk.Viewport()
+        viewport = Gtk.Viewport()
         viewport.add(vbox)
-        self.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+        self.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
         self.add(viewport)
         viewport.show()
         vbox.show()
@@ -111,11 +113,11 @@ class ClipProperties(gtk.ScrolledWindow, Loggable):
     project = property(_getProject, _setProject)
 
     def addInfoBar(self, text):
-        label = gtk.Label(label=text)
+        label = Gtk.Label(label=text)
         label.set_line_wrap(True)
-        info_bar = gtk.InfoBar()
+        info_bar = Gtk.InfoBar()
         info_bar.get_content_area().add(label)
-        self.infobar_box.pack_start(info_bar, expand=False, fill=False)
+        self.infobar_box.pack_start(info_bar, False, False, 0)
         return info_bar
 
     def _getTimeline(self):
@@ -129,15 +131,15 @@ class ClipProperties(gtk.ScrolledWindow, Loggable):
     timeline = property(_getTimeline, _setTimeline)
 
 
-class EffectProperties(gtk.Expander):
+class EffectProperties(Gtk.Expander):
     """
     Widget for viewing and configuring effects
     """
-    # Note: This should be inherited from gtk.Expander when we get other things
+    # Note: This should be inherited from Gtk.Expander when we get other things
     # to put in ClipProperties, that is why this is done this way
 
     def __init__(self, instance, effect_properties_handling, clip_properties):
-        gtk.Expander.__init__(self)
+        Gtk.Expander.__init__(self)
 
         self.selected_effects = []
         self.timeline_objects = []
@@ -153,66 +155,66 @@ class EffectProperties(gtk.Expander):
         self._config_ui_h_pos = None
         self._timeline = None
 
-        self._vcontent = gtk.VPaned()
+        self._vcontent = Gtk.VPaned()
         self.add(self._vcontent)
 
-        self._table = gtk.Table(3, 1, False)
+        self._table = Gtk.Table(3, 1, False)
 
-        self._toolbar = gtk.Toolbar()
-        self._removeEffectBt = gtk.ToolButton("gtk-delete")
+        self._toolbar = Gtk.Toolbar()
+        self._removeEffectBt = Gtk.ToolButton("gtk-delete")
         self._removeEffectBt.set_label(_("Remove effect"))
         self._removeEffectBt.set_use_underline(True)
         self._removeEffectBt.set_is_important(True)
         self._removeEffectBt.set_sensitive(False)
         self._toolbar.insert(self._removeEffectBt, 0)
-        self._table.attach(self._toolbar, 0, 1, 0, 1, yoptions=gtk.FILL)
+        self._table.attach(self._toolbar, 0, 1, 0, 1, yoptions=Gtk.AttachOptions.FILL)
 
-        self.storemodel = gtk.ListStore(bool, str, str, str, object)
+        self.storemodel = Gtk.ListStore(bool, str, str, str, object)
 
         #Treeview
-        self.treeview_scrollwin = gtk.ScrolledWindow()
-        self.treeview_scrollwin.set_policy(gtk.POLICY_NEVER,
-                                           gtk.POLICY_AUTOMATIC)
-        self.treeview_scrollwin.set_shadow_type(gtk.SHADOW_ETCHED_IN)
+        self.treeview_scrollwin = Gtk.ScrolledWindow()
+        self.treeview_scrollwin.set_policy(Gtk.PolicyType.NEVER,
+                                           Gtk.PolicyType.AUTOMATIC)
+        self.treeview_scrollwin.set_shadow_type(Gtk.ShadowType.ETCHED_IN)
 
         # TreeView
         # Displays name, description
-        self.treeview = gtk.TreeView(self.storemodel)
+        self.treeview = Gtk.TreeView(self.storemodel)
         self.treeview_scrollwin.add(self.treeview)
         self.treeview.set_property("rules_hint", True)
         self.treeview.set_property("has_tooltip", True)
         tsel = self.treeview.get_selection()
-        tsel.set_mode(gtk.SELECTION_SINGLE)
+        tsel.set_mode(Gtk.SelectionMode.SINGLE)
 
-        activatedcell = gtk.CellRendererToggle()
+        activatedcell = Gtk.CellRendererToggle()
         activatedcell.props.xpad = PADDING
         activatedcell.connect("toggled", self._effectActiveToggleCb)
 
-        typecol = gtk.TreeViewColumn(_("Type"))
+        typecol = Gtk.TreeViewColumn(_("Type"))
         typecol.set_sort_column_id(COL_TYPE)
         self.treeview.append_column(typecol)
         typecol.set_spacing(SPACING)
-        typecol.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+        typecol.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
         typecol.set_min_width(50)
-        typecell = gtk.CellRendererText()
+        typecell = Gtk.CellRendererText()
         typecell.props.xpad = PADDING
-        typecell.set_property("ellipsize", pango.ELLIPSIZE_END)
-        typecol.pack_start(typecell)
+        typecell.set_property("ellipsize", Pango.EllipsizeMode.END)
+        typecol.pack_start(typecell, True)
         typecol.add_attribute(typecell, "text", COL_TYPE)
 
-        namecol = gtk.TreeViewColumn(_("Effect name"))
+        namecol = Gtk.TreeViewColumn(_("Effect name"))
         namecol.set_sort_column_id(COL_NAME_TEXT)
         self.treeview.append_column(namecol)
         namecol.set_spacing(SPACING)
-        namecell = gtk.CellRendererText()
+        namecell = Gtk.CellRendererText()
         namecell.props.xpad = PADDING
-        namecell.set_property("ellipsize", pango.ELLIPSIZE_END)
-        namecol.pack_start(namecell)
+        namecell.set_property("ellipsize", Pango.EllipsizeMode.END)
+        namecol.pack_start(namecell, True)
         namecol.add_attribute(namecell, "text", COL_NAME_TEXT)
 
-        self.treeview.drag_dest_set(gtk.DEST_DEFAULT_MOTION,
+        self.treeview.drag_dest_set(Gtk.DestDefaults.MOTION,
             [EFFECT_TARGET_ENTRY],
-            gtk.gdk.ACTION_COPY)
+            Gdk.DragAction.COPY)
 
         self.treeview.drag_dest_add_text_targets()
 
@@ -287,13 +289,13 @@ class EffectProperties(gtk.Expander):
         self.updateAll()
 
     def  _trackObjectAddedCb(self, unused_timeline_object, track_object):
-        if isinstance(track_object, ges.TrackEffect):
+        if isinstance(track_object, GES.TrackEffect):
             selec = self.timeline.selection.getSelectedTrackEffects()
             self.selected_effects = selec
             self.updateAll()
 
     def  _trackRemovedRemovedCb(self, unused_timeline_object, track_object):
-        if isinstance(track_object, ges.TrackEffect):
+        if isinstance(track_object, GES.TrackEffect):
             selec = self.timeline.selection.getSelectedTrackEffects()
             self.selected_effects = selec
             self.updateAll()
@@ -331,13 +333,13 @@ class EffectProperties(gtk.Expander):
             # Which means, it has the corresponding media_type
             for tckobj in tlobj.get_track_objects():
                 track = tckobj.get_track()
-                if track.get_property("track_type") == ges.TRACK_TYPE_AUDIO and \
+                if track.get_property("track_type") == GES.TrackType.AUDIO and \
                         media_type == AUDIO_EFFECT or \
-                        track.get_property("track_type") == ges.TRACK_TYPE_VIDEO and \
+                        track.get_property("track_type") == GES.TrackType.VIDEO and \
                         media_type == VIDEO_EFFECT:
                     #Actually add the effect
                     self.app.action_log.begin("add effect")
-                    effect = ges.TrackParseLaunchEffect(bin_description=bin_desc)
+                    effect = GES.TrackParseLaunchEffect(bin_description=bin_desc)
                     tlobj.add_track_object(effect)
                     track.add_object(effect)
                     self.updateAll()
@@ -404,9 +406,9 @@ class EffectProperties(gtk.Expander):
                         track_effect.props.bin_description)
                 to_append = [track_effect.props.active]
                 track = track_effect.get_track()
-                if track.get_property("track_type") == ges.TRACK_TYPE_AUDIO:
+                if track.get_property("track_type") == GES.TrackType.AUDIO:
                     to_append.append("Audio")
-                elif track.get_property("track_type") == ges.TRACK_TYPE_VIDEO:
+                elif track.get_property("track_type") == GES.TrackType.VIDEO:
                     to_append.append("Video")
 
                 to_append.append(track_effect.props.bin_description)
@@ -424,7 +426,7 @@ class EffectProperties(gtk.Expander):
 
     def _setEffectDragable(self):
         self.show()
-        self._info_bar.hide_all()
+        self._info_bar.hide()
 
     def _treeviewSelectionChangedCb(self, treeview):
         if self.selection.count_selected_rows() == 0 and self.timeline_objects:
@@ -447,7 +449,7 @@ class EffectProperties(gtk.Expander):
                                                COL_TRACK_EFFECT)
 
             for widget in self._vcontent.get_children():
-                if type(widget) in [gtk.ScrolledWindow, GstElementSettingsWidget]:
+                if type(widget) in [Gtk.ScrolledWindow, GstElementSettingsWidget]:
                     self._vcontent.remove(widget)
 
             element = track_effect
@@ -470,7 +472,7 @@ class EffectProperties(gtk.Expander):
             self._effect_config_ui = None
 
 
-class TransformationProperties(gtk.Expander):
+class TransformationProperties(Gtk.Expander):
     """
     Widget for viewing and configuring speed
     """
@@ -478,7 +480,7 @@ class TransformationProperties(gtk.Expander):
         'selection-changed': []}
 
     def __init__(self, app, action_log):
-        gtk.Expander.__init__(self)
+        Gtk.Expander.__init__(self)
         self.action_log = action_log
         self.app = app
         self._timeline = None
@@ -488,7 +490,7 @@ class TransformationProperties(gtk.Expander):
         self.set_label(_("Transformation"))
 
         if not "Frei0r" in soft_deps:
-            self.builder = gtk.Builder()
+            self.builder = Gtk.Builder()
             self.builder.add_from_file(os.path.join(get_ui_dir(),
                         "cliptransformation.ui"))
 
@@ -591,7 +593,7 @@ class TransformationProperties(gtk.Expander):
 
     def _findEffect(self, name):
         for track_effect in self._current_tl_obj.get_track_objects():
-            if isinstance(track_effect, ges.TrackParseLaunchEffect):
+            if isinstance(track_effect, GES.TrackParseLaunchEffect):
                 if name in track_effect.get_property("bin-description"):
                         self.track_effect = track_effect
                         return track_effect.get_element()
@@ -599,7 +601,7 @@ class TransformationProperties(gtk.Expander):
     def _findOrCreateEffect(self, name):
         effect = self._findEffect(name)
         if not effect:
-            effect = ges.TrackParseLaunchEffect(bin_description=name)
+            effect = GES.TrackParseLaunchEffect(bin_description=name)
             self._current_tl_obj.add_track_object(effect)
             tracks = self.app.projectManager.current.timeline.get_tracks()
             for track in tracks:
diff --git a/pitivi/dialogs/clipmediaprops.py b/pitivi/dialogs/clipmediaprops.py
index b86878a..77fd690 100644
--- a/pitivi/dialogs/clipmediaprops.py
+++ b/pitivi/dialogs/clipmediaprops.py
@@ -24,8 +24,8 @@ Dialog box displaying the properties of a clip from media library, allowing
 to set those properties as the project settings.
 """
 
-import gtk
-import gst
+from gi.repository import Gtk
+from gi.repository import Gst
 import os
 
 from gettext import gettext as _
@@ -65,11 +65,11 @@ class clipmediapropsDialog():
             self.is_image = stream.is_image()
             if not self.is_image:
                 self.frame_rate.set_text(
-                    get_value_from_model(frame_rates, gst.Fraction(
+                    get_value_from_model(frame_rates, Gst.Fraction(
                                                 stream.get_framerate_num(),
                                                 stream.get_framerate_denom())))
                 self.aspect_ratio.set_text(
-                    get_value_from_model(pixel_aspect_ratios, gst.Fraction(
+                    get_value_from_model(pixel_aspect_ratios, Gst.Fraction(
                                                     stream.get_par_num(),
                                                     stream.get_par_denom())))
             self.has_video = True
@@ -86,7 +86,7 @@ class clipmediapropsDialog():
         self.dialog.run()
 
     def _createUi(self):
-        builder = gtk.Builder()
+        builder = Gtk.Builder()
         builder.add_from_file(os.path.join(get_ui_dir(), "clipmediaprops.ui"))
         builder.connect_signals(self)
         self.dialog = builder.get_object("Import Settings")
@@ -120,10 +120,10 @@ class clipmediapropsDialog():
                 _width = video.get_width()
                 _height = video.get_height()
             if (self.checkbutton2.get_active() and not self.is_image):
-                _framerate = gst.Fraction(video.get_framerate_num(),
+                _framerate = Gst.Fraction(video.get_framerate_num(),
                                           video.get_framerate_denom())
             if (self.checkbutton3.get_active() and not self.is_image):
-                _par = gst.Fraction(video.get_par_num(),
+                _par = Gst.Fraction(video.get_par_num(),
                                     video.get_par_denom())
             self.settings.setVideoProperties(_width, _height, _framerate, _par)
 
diff --git a/pitivi/dialogs/depsmanager.py b/pitivi/dialogs/depsmanager.py
index 0c39c7a..808e89e 100644
--- a/pitivi/dialogs/depsmanager.py
+++ b/pitivi/dialogs/depsmanager.py
@@ -20,7 +20,7 @@
 # Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 # Boston, MA 02110-1301, USA.
 
-import gtk
+from gi.repository import Gtk
 import os
 
 from pitivi.configure import get_ui_dir
@@ -34,7 +34,7 @@ class DepsManager(object):
 
     def __init__(self, app):
         self.app = app
-        self.builder = gtk.Builder()
+        self.builder = Gtk.Builder()
         self.builder.add_from_file(os.path.join(get_ui_dir(), "depsmanager.ui"))
         self.builder.connect_signals(self)
         self.window = self.builder.get_object("window1")
@@ -79,7 +79,7 @@ class DepsManager(object):
         self.builder.get_object("pkg_list").set_text(label_contents)
 
     def show(self):
-        self.window.set_transient_for(self.app.gui)
+        self.set_transient_for(self.app.gui)
         self.window.set_modal(True)
         self._setDepsLabel()
         self.window.show()
diff --git a/pitivi/dialogs/filelisterrordialog.py b/pitivi/dialogs/filelisterrordialog.py
index 6410f0f..1ca0e6c 100644
--- a/pitivi/dialogs/filelisterrordialog.py
+++ b/pitivi/dialogs/filelisterrordialog.py
@@ -23,9 +23,9 @@
 Dialog box listing files which had errors, and the reasons.
 """
 
-import gtk
+from gi.repository import Gtk
 import os
-import pango
+from gi.repository import Pango
 
 from gettext import gettext as _
 
@@ -43,7 +43,7 @@ class FileListErrorDialog(Signallable, Loggable):
 
     def __init__(self, title, headline):
         Loggable.__init__(self)
-        self.builder = gtk.Builder()
+        self.builder = Gtk.Builder()
         self.builder.add_from_file(os.path.join(get_ui_dir(),
             "filelisterrordialog.ui"))
         self.builder.connect_signals(self)
@@ -62,7 +62,7 @@ class FileListErrorDialog(Signallable, Loggable):
         """
         self.debug("Uri:%s, reason:%s, extra:%s", uri, reason, extra)
         exp = self._createFileExpander(uri, reason, extra)
-        self.errorvbox.pack_start(exp, expand=False, fill=False)
+        self.errorvbox.pack_start(exp, False, False, 0)
         if len(self.errorvbox.get_children()) < 3:
             exp.set_expanded(True)  # Let's save the user some clicks
         exp.show_all()
@@ -73,14 +73,14 @@ class FileListErrorDialog(Signallable, Loggable):
                 uri = uri[7:]
             uri = uri.split('/')[-1]
             uri = unquote(uri)
-            exp = gtk.Expander(label=uri)
+            exp = Gtk.Expander(label=uri)
         else:
-            exp = gtk.Expander(label=reason)
+            exp = Gtk.Expander(label=reason)
 
-        textbuffer = gtk.TextBuffer()
+        textbuffer = Gtk.TextBuffer()
         table = textbuffer.get_tag_table()
-        boldtag = gtk.TextTag()
-        boldtag.props.weight = pango.WEIGHT_BOLD
+        boldtag = Gtk.TextTag()
+        boldtag.props.weight = Pango.Weight.BOLD
         table.add(boldtag)
 
         end = textbuffer.get_end_iter()
@@ -96,8 +96,8 @@ class FileListErrorDialog(Signallable, Loggable):
             end = textbuffer.get_end_iter()
             textbuffer.insert(end, "%s\n" % extra)
 
-        textview = gtk.TextView(buffer=textbuffer)
-        textview.set_wrap_mode(gtk.WRAP_WORD)
+        textview = Gtk.TextView(buffer=textbuffer)
+        textview.set_wrap_mode(Gtk.WrapMode.WORD)
 
         exp.add(textview)
 
diff --git a/pitivi/dialogs/prefs.py b/pitivi/dialogs/prefs.py
index 5da0fcc..15c9778 100644
--- a/pitivi/dialogs/prefs.py
+++ b/pitivi/dialogs/prefs.py
@@ -23,7 +23,7 @@
 Dialog box for user preferences.
 """
 
-import gtk
+from gi.repository import Gtk
 import os
 
 import pitivi.utils.widgets as ptvWidgets
@@ -67,7 +67,7 @@ class PreferencesDialog():
         self.dialog.run()
 
     def _createUi(self):
-        builder = gtk.Builder()
+        builder = Gtk.Builder()
         builder.add_from_file(os.path.join(get_ui_dir(), "preferences.ui"))
         builder.connect_signals(self)
 
@@ -111,7 +111,7 @@ class PreferencesDialog():
     def addPathPreference(cls, attrname, label, description, section=None):
         """
         Add an auto-generated user preference that will show up as a
-        gtk.FileChooserButton.
+        Gtk.FileChooserButton.
 
         @param label: user-visible name for this option
         @type label: C{str}
@@ -130,7 +130,7 @@ class PreferencesDialog():
         upper=None, lower=None):
         """
         Add an auto-generated user preference that will show up as either a
-        gtk.SpinButton or a gtk.HScale, depending whether both the upper and lower
+        Gtk.SpinButton or a Gtk.HScale, depending whether both the upper and lower
         limits are set.
 
         @param label: user-visible name for this option
@@ -154,7 +154,7 @@ class PreferencesDialog():
         matches=None):
         """
         Add an auto-generated user preference that will show up as either a
-        gtk.SpinButton or a gtk.HScale, depending on the upper and lower
+        Gtk.SpinButton or a Gtk.HScale, depending on the upper and lower
         limits
 
         @param label: user-visible name for this option
@@ -174,7 +174,7 @@ class PreferencesDialog():
         section=None):
         """
         Add an auto-generated user preference that will show up as either a
-        gtk.ComboBox or a group of radio buttons, depending on the number of
+        Gtk.ComboBox or a group of radio buttons, depending on the number of
         choices.
 
         @param label: user-visible name for this option
@@ -195,7 +195,7 @@ class PreferencesDialog():
     def addTogglePreference(cls, attrname, label, description, section=None):
         """
         Add an auto-generated user preference that will show up as a
-        gtk.CheckButton.
+        Gtk.CheckButton.
 
         @param label: user-visible name for this option
         @type label: C{str}
@@ -215,7 +215,7 @@ class PreferencesDialog():
         """
         Add an auto-generated user preference for specifying colors. The
         colors can be returned as either int, a string colorspec, or a
-        gtk.gdk.Color object. See the gtk.gdk.color_parse() function for info
+        Gdk.Color object. See the Gdk.color_parse() function for info
         on colorspecs.
 
         @param label: user-visible name for this option
@@ -254,7 +254,7 @@ class PreferencesDialog():
         for section in sorted(self.prefs):
             options = self.prefs[section]
             self.model.append((_(section), section))
-            widgets = gtk.Table()
+            widgets = Gtk.Table()
             widgets.set_border_width(SPACING)
             widgets.props.column_spacing = SPACING
             widgets.props.row_spacing = SPACING / 2
@@ -269,12 +269,12 @@ class PreferencesDialog():
                 self.widgets[attrname] = widget
                 if isinstance(widget, ptvWidgets.ToggleWidget):
                     # Don't add a semicolon for checkbuttons
-                    label_widget = gtk.Label(_(label))
+                    label_widget = Gtk.Label(label=_(label))
                 else:
-                    label_widget = gtk.Label(_(label) + ":")
-                icon = gtk.Image()
-                icon.set_from_stock('gtk-clear', gtk.ICON_SIZE_MENU)
-                revert = gtk.Button()
+                    label_widget = Gtk.Label(label=_(label) + ":")
+                icon = Gtk.Image()
+                icon.set_from_stock('gtk-clear', Gtk.IconSize.MENU)
+                revert = Gtk.Button()
                 revert.add(icon)
                 revert.set_tooltip_text(_("Reset to default value"))
                 revert.set_sensitive(not self.settings.isDefault(attrname))
@@ -297,7 +297,7 @@ class PreferencesDialog():
                 else:
                     label.set_alignment(1.0, 0.5)
                     label.set_tooltip_text(description)
-                    widgets.attach(label, 0, 1, y, y + 1, xoptions=gtk.FILL, yoptions=0)
+                    widgets.attach(label, 0, 1, y, y + 1, xoptions=Gtk.AttachOptions.FILL, yoptions=0)
                     widgets.attach(widget, 1, 2, y, y + 1, yoptions=0)
                     widgets.attach(revert, 2, 3, y, y + 1, xoptions=0, yoptions=0)
                     label.show()
@@ -305,7 +305,7 @@ class PreferencesDialog():
                 widget.show()
                 revert.show()
 
-            self.contents.pack_start(widgets, True, True)
+            self.contents.pack_start(widgets, True, True, 0)
 
         self.treeview.get_selection().select_path((0,))
         self.factory_settings.set_sensitive(self._canReset())
diff --git a/pitivi/dialogs/startupwizard.py b/pitivi/dialogs/startupwizard.py
index 127d2a7..55c8590 100644
--- a/pitivi/dialogs/startupwizard.py
+++ b/pitivi/dialogs/startupwizard.py
@@ -20,7 +20,9 @@
 # Boston, MA 02110-1301, USA.
 
 import os
-import gtk
+
+from gi.repository import Gtk
+from gi.repository import Gdk
 
 from gettext import gettext as _
 
@@ -43,7 +45,7 @@ class StartUpWizard(object):
 
     def __init__(self, app):
         self.app = app
-        self.builder = gtk.Builder()
+        self.builder = Gtk.Builder()
         self.builder.add_from_file(os.path.join(get_ui_dir(), "startupwizard.ui"))
         self.builder.connect_signals(self)
 
@@ -52,7 +54,7 @@ class StartUpWizard(object):
         self.recent_chooser = self.builder.get_object("recentchooser2")
         # FIXME: gtk creates a combo box with only one item, but there is no
         # simple way to hide it.
-        filter = gtk.RecentFilter()
+        filter = Gtk.RecentFilter()
         filter.set_name(_("Projects"))
         filter.add_pattern("*.xptv")
         self.recent_chooser.add_filter(filter)
@@ -65,8 +67,8 @@ class StartUpWizard(object):
         self.app.projectManager.connect("new-project-loading", self._projectLoadingCb)
 
         vbox = self.builder.get_object("topvbox")
-        self.infobar = gtk.InfoBar()
-        vbox.pack_start(self.infobar)
+        self.infobar = Gtk.InfoBar()
+        vbox.pack_start(self.infobar, True, True, 0)
         if self.app.version_information:
             self._appVersionInfoReceivedCb(None, self.app.version_information)
         else:
@@ -87,7 +89,7 @@ class StartUpWizard(object):
 
     def _keyPressCb(self, widget, event):
         """Handle a key press event on the dialog."""
-        if event.keyval == gtk.keysyms.Escape:
+        if event.keyval == Gdk.KEY_Escape:
             # The user pressed "Esc".
             self.app.projectManager.newBlankProject()
 
@@ -152,7 +154,7 @@ class StartUpWizard(object):
         # increment counter, create infobar and show info
         self.app.settings.displayCounter = self.app.settings.displayCounter + 1
         text = _("PiTiVi %s is available." % version["current"])
-        label = gtk.Label(text)
+        label = Gtk.Label(label=text)
         self.infobar.get_content_area().add(label)
-        self.infobar.set_message_type(gtk.MESSAGE_INFO)
+        self.infobar.set_message_type(Gtk.MessageType.INFO)
         self.infobar.show_all()
diff --git a/pitivi/effects.py b/pitivi/effects.py
index 00f8cd7..2f892ae 100644
--- a/pitivi/effects.py
+++ b/pitivi/effects.py
@@ -35,15 +35,16 @@ Effects global handling
   _ Complex Audio/Video Effects
 """
 import glib
-import gst
-import gtk
 import re
 import os
-import gobject
 import time
-import pango
 
+from gi.repository import Gst
+from gi.repository import Gtk
 from gi.repository import Gdk
+from gi.repository import Pango
+from gi.repository import GObject
+from gi.repository import GdkPixbuf
 
 from gettext import gettext as _
 
@@ -161,8 +162,8 @@ class EffectsHandler(object):
         go trough the list of element factories and
         add them to the correct list filtering if necessary
         """
-        factlist = gst.registry_get_default().get_feature_list(
-            gst.ElementFactory)
+        factlist = Gst.Registry.get().get_feature_list(
+            Gst.ElementFactory)
         for element_factory in factlist:
             klass = element_factory.get_klass()
             name = element_factory.get_name()
@@ -207,7 +208,7 @@ class EffectsHandler(object):
     def _getEffectDescripton(self, element_factory):
         """
         @ivar element_factory: The element factory
-        @type element_factory: L{gst.ElementFactory}
+        @type element_factory: L{Gst.ElementFactory}
         @returns: A human description C{str} for the effect
         """
         return element_factory.get_description()
@@ -247,7 +248,7 @@ class EffectsHandler(object):
     def _getEffectName(self, element_factory):
         """
         @ivar element_factory: The element factory
-        @type element_factory: L{gst.ElementFactory}
+        @type element_factory: L{Gst.ElementFactory}
         @returns: A human readable name C{str} for the effect
         """
         #TODO check if it is the good way to make it translatable
@@ -312,13 +313,13 @@ class EffectsHandler(object):
         effect_name = effect_name + ".png"
         icon = None
         try:
-            icon = gtk.gdk.pixbuf_new_from_file(os.path.join(self._pixdir,
+            icon = GdkPixbuf.Pixbuf.new_from_file(os.path.join(self._pixdir,
                 effect_name))
-        # empty except clause is bad but load_icon raises gio.Error.
+        # empty except clause is bad but load_icon raises Gio.Error.
         ## Right, *gio*.
         except:
             try:
-                icon = gtk.gdk.pixbuf_new_from_file(os.path.join(self._pixdir,
+                icon = GdkPixbuf.Pixbuf.new_from_file(os.path.join(self._pixdir,
                     "defaultthumbnail.svg"))
             except:
                 return None
@@ -339,15 +340,15 @@ GlobalSettings.addConfigSection('effect-library')
  COL_ELEMENT_NAME,
  COL_ICON) = range(7)
 
-INVISIBLE = gtk.gdk.pixbuf_new_from_file(os.path.join(get_pixmap_dir(),
+INVISIBLE = GdkPixbuf.Pixbuf.new_from_file(os.path.join(get_pixmap_dir(),
     "invisible.png"))
 
 
-class EffectListWidget(gtk.VBox, Loggable):
+class EffectListWidget(Gtk.VBox, Loggable):
     """ Widget for listing effects """
 
     def __init__(self, instance, uiman):
-        gtk.VBox.__init__(self)
+        GObject.GObject.__init__(self)
         Loggable.__init__(self)
 
         self.app = instance
@@ -356,62 +357,62 @@ class EffectListWidget(gtk.VBox, Loggable):
         self._draggedItems = None
 
         #Searchbox and combobox
-        hfilters = gtk.HBox()
+        hfilters = Gtk.HBox()
         hfilters.set_spacing(SPACING)
         hfilters.set_border_width(3)  # Prevents being flush against the notebook
-        self.effectType = gtk.ComboBoxText()
+        self.effectType = Gtk.ComboBoxText()
         self.effectType.append_text(_("Video effects"))
         self.effectType.append_text(_("Audio effects"))
-        self.effectCategory = gtk.ComboBoxText()
+        self.effectCategory = Gtk.ComboBoxText()
         self.effectType.set_active(VIDEO_EFFECT)
 
-        hfilters.pack_start(self.effectType, expand=True)
-        hfilters.pack_end(self.effectCategory, expand=True)
+        hfilters.pack_start(self.effectType, True, True, 0)
+        hfilters.pack_end(self.effectCategory, True, True, 0)
 
-        hsearch = gtk.HBox()
+        hsearch = Gtk.HBox()
         hsearch.set_spacing(SPACING)
         hsearch.set_border_width(3)  # Prevents being flush against the notebook
-        searchStr = gtk.Label(_("Search:"))
-        self.searchEntry = gtk.Entry()
-        self.searchEntry.set_icon_from_stock(gtk.ENTRY_ICON_SECONDARY, "gtk-clear")
-        hsearch.pack_start(searchStr, expand=False)
-        hsearch.pack_end(self.searchEntry, expand=True)
+        searchStr = Gtk.Label(label=_("Search:"))
+        self.searchEntry = Gtk.Entry()
+        self.searchEntry.set_icon_from_stock(Gtk.EntryIconPosition.SECONDARY, "gtk-clear")
+        hsearch.pack_start(searchStr, False, True, 0)
+        hsearch.pack_end(self.searchEntry, True, True, 0)
 
         # Store
-        self.storemodel = gtk.ListStore(str, str, int, object, object, str, gtk.gdk.Pixbuf)
+        self.storemodel = Gtk.ListStore(str, str, int, object, object, str, GdkPixbuf.Pixbuf)
 
-        scrollwin = gtk.ScrolledWindow()
-        scrollwin.props.hscrollbar_policy = gtk.POLICY_NEVER
-        scrollwin.props.vscrollbar_policy = gtk.POLICY_AUTOMATIC
-        scrollwin.props.shadow_type = gtk.SHADOW_ETCHED_IN
+        scrollwin = Gtk.ScrolledWindow()
+        scrollwin.props.hscrollbar_policy = Gtk.PolicyType.NEVER
+        scrollwin.props.vscrollbar_policy = Gtk.PolicyType.AUTOMATIC
+        scrollwin.props.shadow_type = Gtk.ShadowType.ETCHED_IN
 
-        self.view = gtk.TreeView(self.storemodel)
+        self.view = Gtk.TreeView(self.storemodel)
         scrollwin.add(self.view)
         self.view.props.headers_visible = False
         tsel = self.view.get_selection()
-        tsel.set_mode(gtk.SELECTION_SINGLE)
+        tsel.set_mode(Gtk.SelectionMode.SINGLE)
 
-        icon_col = gtk.TreeViewColumn()
+        icon_col = Gtk.TreeViewColumn()
         self.view.append_column(icon_col)
         icon_col.props.spacing = SPACING
-        icon_col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
+        icon_col.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
         icon_col.props.fixed_width = 96
-        icon_cell = gtk.CellRendererPixbuf()
+        icon_cell = Gtk.CellRendererPixbuf()
         icon_cell.props.xpad = 6
-        icon_col.pack_start(icon_cell)
+        icon_col.pack_start(icon_cell, True)
         icon_col.add_attribute(icon_cell, "pixbuf", COL_ICON)
 
-        text_col = gtk.TreeViewColumn()
+        text_col = Gtk.TreeViewColumn()
         self.view.append_column(text_col)
         text_col.set_expand(True)
         text_col.set_spacing(SPACING)
-        text_col.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+        text_col.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
         text_col.set_min_width(150)
-        text_cell = gtk.CellRendererText()
+        text_cell = Gtk.CellRendererText()
         text_cell.props.yalign = 0.0
         text_cell.props.xpad = 6
-        text_cell.set_property("ellipsize", pango.ELLIPSIZE_END)
-        text_col.pack_start(text_cell)
+        text_cell.set_property("ellipsize", Pango.EllipsizeMode.END)
+        text_col.pack_start(text_cell, True)
         text_col.set_cell_data_func(text_cell,
                                     self.view_description_cell_data_func,
                                     None)
@@ -428,7 +429,7 @@ class EffectListWidget(gtk.VBox, Loggable):
         self.view.connect("button-press-event", self._buttonPressEventCb)
         self.view.connect("select-cursor-row", self._enterPressEventCb)
 
-        self.view.drag_source_set(0, [], gtk.gdk.ACTION_COPY)
+        self.view.drag_source_set(0, [], Gdk.DragAction.COPY)
         self.view.enable_model_drag_source(Gdk.ModifierType.BUTTON1_MASK, [("pitivi/effect", 0, TYPE_PITIVI_EFFECT)], Gdk.DragAction.COPY)
         self.view.drag_source_set_target_list(None)
         self.view.drag_source_add_text_targets()
@@ -437,11 +438,11 @@ class EffectListWidget(gtk.VBox, Loggable):
 
         # Delay the loading of the available effects so the application
         # starts faster.
-        gobject.idle_add(self._loadAvailableEffectsCb)
+        GObject.idle_add(self._loadAvailableEffectsCb)
 
-        self.pack_start(hfilters, expand=False)
-        self.pack_start(hsearch, expand=False)
-        self.pack_end(scrollwin, expand=True)
+        self.pack_start(hfilters, False, True, 0)
+        self.pack_start(hsearch, False, True, 0)
+        self.pack_end(scrollwin, True, True, 0)
 
         #create the filterModel
         self.modelFilter = self.storemodel.filter_new()
@@ -479,7 +480,7 @@ class EffectListWidget(gtk.VBox, Loggable):
                                          effect.getCategories(),
                                          effect, name,
                                          self.app.effects.getEffectIcon(name)])
-                self.storemodel.set_sort_column_id(COL_NAME_TEXT, gtk.SORT_ASCENDING)
+                self.storemodel.set_sort_column_id(COL_NAME_TEXT, Gtk.SortType.ASCENDING)
 
     def show_categories(self, effectType):
         self.effectCategory.get_model().clear()
@@ -508,7 +509,7 @@ class EffectListWidget(gtk.VBox, Loggable):
         path = paths[0]
         pixbuf = model.get_value(model.get_iter(path), COL_ICON)
         if pixbuf:
-            gtk.drag_set_icon_pixbuf(context, pixbuf, 0, 0)
+            Gtk.drag_set_icon_pixbuf(context, pixbuf, 0, 0)
 
     def _rowUnderMouseSelected(self, view, event):
         result = view.get_path_at_pos(int(event.x), int(event.y))
@@ -541,7 +542,7 @@ class EffectListWidget(gtk.VBox, Loggable):
         else:
             self._draggedItems = self.getSelectedItems()
 
-        gtk.TreeView.do_button_press_event(view, event)
+        Gtk.TreeView.do_button_press_event(view, event)
         return True
 
     def getSelectedItems(self):
@@ -608,7 +609,7 @@ class EffectsPropertiesManager:
         """
             Permit to get a configuration GUI for the effect
             @param effect: The effect for which we want the configuration UI
-            @type effect: C{gst.Element}
+            @type effect: C{Gst.Element}
         """
 
         if effect not in self.cache_dict:
@@ -617,10 +618,10 @@ class EffectsPropertiesManager:
             effect_set_ui.setElement(effect, ignore=PROPS_TO_IGNORE,
                                      default_btn=True, use_element_props=True)
             nb_rows = effect_set_ui.get_children()[0].get_property('n-rows')
-            effect_configuration_ui = gtk.ScrolledWindow()
+            effect_configuration_ui = Gtk.ScrolledWindow()
             effect_configuration_ui.add_with_viewport(effect_set_ui)
-            effect_configuration_ui.set_policy(gtk.POLICY_AUTOMATIC,
-                                               gtk.POLICY_AUTOMATIC)
+            effect_configuration_ui.set_policy(Gtk.PolicyType.AUTOMATIC,
+                                               Gtk.PolicyType.AUTOMATIC)
             self.cache_dict[effect] = effect_configuration_ui
             self._connectAllWidgetCbs(effect_set_ui, effect)
             self._postConfiguration(effect, effect_set_ui)
@@ -648,7 +649,7 @@ class EffectsPropertiesManager:
 
     def _getUiToSetEffect(self, effect):
         """ Permit to get the widget to set the effect and not its container """
-        if type(self.cache_dict[effect]) is gtk.ScrolledWindow:
+        if type(self.cache_dict[effect]) is Gtk.ScrolledWindow:
             effect_set_ui = self.cache_dict[effect].get_children()[0].get_children()[0]
         else:
             effect_set_ui = self.cache_dict[effect]
@@ -666,8 +667,8 @@ class EffectsPropertiesManager:
         value = dynamic.getWidgetValue()
 
         #FIXME Workaround in order to make aspectratiocrop working
-        if isinstance(value, gst.Fraction):
-            value = gst.Fraction(int(value.num), int(value.denom))
+        if isinstance(value, Gst.Fraction):
+            value = Gst.Fraction(int(value.num), int(value.denom))
 
         if value != self._current_element_values.get(prop.name):
             self.action_log.begin("Effect property change")
diff --git a/pitivi/mainwindow.py b/pitivi/mainwindow.py
index c058995..42ffc1a 100644
--- a/pitivi/mainwindow.py
+++ b/pitivi/mainwindow.py
@@ -25,16 +25,19 @@ Main GTK+ window
 """
 
 import os
-import gtk
-import gst
-import ges
 
 from time import time
 from urllib import unquote
 from gettext import gettext as _
-from gtk import RecentManager
 from hashlib import md5
-from gst.pbutils import InstallPluginsContext, install_plugins_async
+
+from gi.repository import Gtk
+from gi.repository import Gdk
+from gi.repository import Gst
+from gi.repository import GES
+from gi.repository import GObject
+from gi.repository import GdkPixbuf
+from gi.repository.GstPbutils import InstallPluginsContext, install_plugins_async
 
 from pitivi.utils.loggable import Loggable
 from pitivi.utils.misc import in_devel
@@ -47,11 +50,8 @@ from pitivi.utils.misc import show_user_manual
 from pitivi.utils.ui import info_name, beautify_time_delta, SPACING,\
         FILESOURCE_TARGET_ENTRY, URI_TARGET_ENTRY, TYPE_URI_LIST, \
         TYPE_PITIVI_FILESOURCE
-
 from pitivi.timeline.timeline import Timeline
-
 from pitivi.viewer import PitiviViewer
-
 from pitivi.tabsmanager import BaseTabs
 from pitivi.mediafilespreviewer import PreviewWidget
 from pitivi.clipproperties import ClipProperties
@@ -134,10 +134,13 @@ GlobalSettings.addConfigOption('lastCurrentVersion',
 #FIXME Hacky, reimplement when avalaible in GES
 formats = [(None, _("PiTiVi Native (XML)"), ('xptv',))]
 
+# FIXME PyGi to get stock_add working
+Gtk.stock_add = lambda items: None
+
 
 def create_stock_icons():
     """ Creates the pitivi-only stock icons """
-    gtk.stock_add([
+    Gtk.stock_add([
             ('pitivi-render', _('Render'), 0, 0, 'pitivi'),
             ('pitivi-split', _('Split'), 0, 0, 'pitivi'),
             ('pitivi-keyframe', _('Keyframe'), 0, 0, 'pitivi'),
@@ -159,16 +162,16 @@ def create_stock_icons():
         "pitivi-group": "pitivi-group-24.svg",
         "pitivi-align": "pitivi-align-24.svg",
     }
-    factory = gtk.IconFactory()
+    factory = Gtk.IconFactory()
     pmdir = get_pixmap_dir()
     for stockid, path in pixmaps.iteritems():
-        pixbuf = gtk.gdk.pixbuf_new_from_file(os.path.join(pmdir, path))
-        iconset = gtk.IconSet(pixbuf)
+        pixbuf = GdkPixbuf.Pixbuf.new_from_file(os.path.join(pmdir, path))
+        iconset = Gtk.IconSet(pixbuf)
         factory.add(stockid, iconset)
         factory.add_default()
 
 
-class PitiviMainWindow(gtk.Window, Loggable):
+class PitiviMainWindow(Gtk.Window, Loggable):
     """
     Pitivi's main window.
 
@@ -179,9 +182,9 @@ class PitiviMainWindow(gtk.Window, Loggable):
     """
     def __init__(self, instance, allow_full_screen=True):
         """ initialize with the Pitivi object """
-        gtksettings = gtk.Settings.get_default()
+        gtksettings = Gtk.Settings.get_default()
         gtksettings.set_property("gtk-application-prefer-dark-theme", True)
-        gtk.Window.__init__(self)
+        GObject.GObject.__init__(self)
         Loggable.__init__(self, "mainwindow")
         self.app = instance
         self.log("Creating MainWindow")
@@ -191,7 +194,7 @@ class PitiviMainWindow(gtk.Window, Loggable):
         create_stock_icons()
         self._setActions(instance)
         self._createUi(instance, allow_full_screen)
-        self.recent_manager = RecentManager()
+        self.recent_manager = Gtk.RecentManager()
         self._zoom_duration_changed = False
         self._missingUriOnLoading = False
 
@@ -254,48 +257,48 @@ class PitiviMainWindow(gtk.Window, Loggable):
             # In some cases we manually specify the translatable label,
             # because we want to have the "..." at the end, indicating
             # an action that requires "further interaction" from the user.
-            ("NewProject", gtk.STOCK_NEW, None,
+            ("NewProject", Gtk.STOCK_NEW, None,
             None, _("Create a new project"), self._newProjectMenuCb),
 
-            ("OpenProject", gtk.STOCK_OPEN, _("_Open..."),
+            ("OpenProject", Gtk.STOCK_OPEN, _("_Open..."),
             None, _("Open an existing project"), self._openProjectCb),
 
-            ("SaveProject", gtk.STOCK_SAVE, None,
+            ("SaveProject", Gtk.STOCK_SAVE, None,
             None, _("Save the current project"), self._saveProjectCb),
 
-            ("SaveProjectAs", gtk.STOCK_SAVE_AS, _("Save _As..."),
+            ("SaveProjectAs", Gtk.STOCK_SAVE_AS, _("Save _As..."),
             None, _("Save the current project"), self._saveProjectAsCb),
 
-            ("RevertToSavedProject", gtk.STOCK_REVERT_TO_SAVED, None,
+            ("RevertToSavedProject", Gtk.STOCK_REVERT_TO_SAVED, None,
             None, _("Reload the current project"), self._revertToSavedProjectCb),
 
-            ("ExportProject", gtk.STOCK_HARDDISK, _("Export as Archive..."),
+            ("ExportProject", Gtk.STOCK_HARDDISK, _("Export as Archive..."),
             None, _("Export the current project"), self._exportProjectAsTarCb),
 
-            ("ProjectSettings", gtk.STOCK_PROPERTIES, _("Project Settings"),
+            ("ProjectSettings", Gtk.STOCK_PROPERTIES, _("Project Settings"),
             None, _("Edit the project settings"), self._projectSettingsCb),
 
             ("RenderProject", 'pitivi-render', _("_Render..."),
             None, _("Export your project as a finished movie"), self._renderCb),
 
-            ("Undo", gtk.STOCK_UNDO, None,
+            ("Undo", Gtk.STOCK_UNDO, None,
             "<Ctrl>Z", _("Undo the last operation"), self._undoCb),
 
-            ("Redo", gtk.STOCK_REDO, None,
+            ("Redo", Gtk.STOCK_REDO, None,
             "<Ctrl>Y", _("Redo the last operation that was undone"), self._redoCb),
 
-            ("Preferences", gtk.STOCK_PREFERENCES, None,
+            ("Preferences", Gtk.STOCK_PREFERENCES, None,
             None, None, self._prefsCb),
 
-            ("RemoveLayer", gtk.STOCK_REMOVE, _("Remove layer"),
+            ("RemoveLayer", Gtk.STOCK_REMOVE, _("Remove layer"),
              None, _("Remove the selected layer from the project"), self._removeLayerCb),
 
-            ("Quit", gtk.STOCK_QUIT, None, None, None, self._quitCb),
+            ("Quit", Gtk.STOCK_QUIT, None, None, None, self._quitCb),
 
-            ("About", gtk.STOCK_ABOUT, None,
+            ("About", Gtk.STOCK_ABOUT, None,
             None, _("Information about %s") % APPNAME, self._aboutCb),
 
-            ("UserManual", gtk.STOCK_HELP, _("User Manual"),
+            ("UserManual", Gtk.STOCK_HELP, _("User Manual"),
              "F1", None, self._userManualCb),
 
             # Set up the toplevel menu items for translation
@@ -309,7 +312,7 @@ class PitiviMainWindow(gtk.Window, Loggable):
         ]
 
         toggleactions = [
-            ("FullScreen", gtk.STOCK_FULLSCREEN, None,
+            ("FullScreen", Gtk.STOCK_FULLSCREEN, None,
             "F11", _("View the main window on the whole screen"), self._fullScreenCb),
 
             ("ShowHideMainToolbar", None, _("Main Toolbar"),
@@ -320,12 +323,12 @@ class PitiviMainWindow(gtk.Window, Loggable):
                 self.settings.mainWindowShowTimelineToolbar),
         ]
 
-        self.main_actions = gtk.ActionGroup("mainwindow")
+        self.main_actions = Gtk.ActionGroup("mainwindow")
         self.main_actions.add_actions(actions)
-        self.undock_action = gtk.Action("WindowizeViewer", _("Undock Viewer"),
+        self.undock_action = Gtk.Action("WindowizeViewer", _("Undock Viewer"),
             _("Put the viewer in a separate window"), None)
         self.main_actions.add_action(self.undock_action)
-        self.toggle_actions = gtk.ActionGroup("mainwindowtoggles")
+        self.toggle_actions = Gtk.ActionGroup("mainwindowtoggles")
         self.toggle_actions.add_toggle_actions(toggleactions)
 
         important_actions = ("Undo", "SaveProject", "RenderProject")
@@ -351,7 +354,7 @@ class PitiviMainWindow(gtk.Window, Loggable):
                 action.set_sensitive(False)
                 self.log("%s has been made insensitive" % action_name)
 
-        self.uimanager = gtk.UIManager()
+        self.uimanager = Gtk.UIManager()
         self.add_accel_group(self.uimanager.get_accel_group())
         self.uimanager.insert_action_group(self.main_actions, 0)
         self.uimanager.insert_action_group(self.toggle_actions, -1)
@@ -364,19 +367,19 @@ class PitiviMainWindow(gtk.Window, Loggable):
         self.connect("configure-event", self._configureCb)
 
         # main menu & toolbar
-        vbox = gtk.VBox(False)
+        vbox = Gtk.VBox(False)
         self.add(vbox)
         vbox.show()
         self.menu = self.uimanager.get_widget("/MainMenuBar")
         self.toolbar = self.uimanager.get_widget("/MainToolBar")
         self.toolbar.get_style_context().add_class("primary-toolbar")
-        vbox.pack_start(self.menu, expand=False)
-        vbox.pack_start(self.toolbar, expand=False)
+        vbox.pack_start(self.menu, False, True, 0)
+        vbox.pack_start(self.toolbar, False, True, 0)
         self.menu.show()
         self.toolbar.show()
         # timeline and project tabs
-        vpaned = gtk.VPaned()
-        vbox.pack_start(vpaned)
+        vpaned = Gtk.VPaned()
+        vbox.pack_start(vpaned, True, True, 0)
         vpaned.show()
 
         self.timeline_ui = Timeline(instance, self.uimanager)
@@ -385,10 +388,10 @@ class PitiviMainWindow(gtk.Window, Loggable):
         self.app.current = None
         vpaned.pack2(self.timeline_ui, resize=True, shrink=False)
         self.timeline_ui.show()
-        self.mainhpaned = gtk.HPaned()
+        self.mainhpaned = Gtk.HPaned()
         vpaned.pack1(self.mainhpaned, resize=True, shrink=False)
 
-        self.secondhpaned = gtk.HPaned()
+        self.secondhpaned = Gtk.HPaned()
         self.mainhpaned.pack1(self.secondhpaned, resize=True, shrink=False)
         self.secondhpaned.show()
         self.mainhpaned.show()
@@ -397,8 +400,8 @@ class PitiviMainWindow(gtk.Window, Loggable):
         self.main_tabs = BaseTabs(instance)
         self.medialibrary = MediaLibraryWidget(instance, self.uimanager)
         self.effectlist = EffectListWidget(instance, self.uimanager)
-        self.main_tabs.append_page(self.medialibrary, gtk.Label(_("Media Library")))
-        self.main_tabs.append_page(self.effectlist, gtk.Label(_("Effect Library")))
+        self.main_tabs.append_page(self.medialibrary, Gtk.Label(label=_("Media Library")))
+        self.main_tabs.append_page(self.effectlist, Gtk.Label(label=_("Effect Library")))
         self.medialibrary.connect('play', self._mediaLibraryPlayCb)
         self.medialibrary.show()
         self.effectlist.show()
@@ -411,9 +414,9 @@ class PitiviMainWindow(gtk.Window, Loggable):
         self.clipconfig = ClipProperties(instance, self.uimanager)
         self.trans_list = TransitionsListWidget(instance, self.uimanager)
         self.title_editor = TitleEditor(instance, self.uimanager)
-        self.context_tabs.append_page(self.clipconfig, gtk.Label(_("Clip configuration")))
-        self.context_tabs.append_page(self.trans_list, gtk.Label(_("Transitions")))
-        self.context_tabs.append_page(self.title_editor.widget, gtk.Label(_("Title editor")))
+        self.context_tabs.append_page(self.clipconfig, Gtk.Label(label=_("Clip configuration")))
+        self.context_tabs.append_page(self.trans_list, Gtk.Label(label=_("Transitions")))
+        self.context_tabs.append_page(self.title_editor.widget, Gtk.Label(_("Title editor")))
         self.context_tabs.connect("switch-page", self.title_editor.tab_switched)
         self.clipconfig.show()
         self.trans_list.show()
@@ -423,9 +426,9 @@ class PitiviMainWindow(gtk.Window, Loggable):
 
         # Viewer
         self.viewer = PitiviViewer(instance, undock_action=self.undock_action)
-        self.viewer.drag_dest_set(gtk.DEST_DEFAULT_DROP | gtk.DEST_DEFAULT_MOTION,
+        self.viewer.drag_dest_set(Gtk.DestDefaults.DROP | Gtk.DestDefaults.MOTION,
                            [FILESOURCE_TARGET_ENTRY, URI_TARGET_ENTRY],
-                           gtk.gdk.ACTION_COPY)
+                           Gdk.DragAction.COPY)
         self.viewer.connect("drag_data_received", self._viewerDndDataReceivedCb)
         self.mainhpaned.pack2(self.viewer, resize=False, shrink=False)
 
@@ -454,7 +457,7 @@ class PitiviMainWindow(gtk.Window, Loggable):
         # toolbar buttons should be clickable with the mouse cursor at the
         # very bottom of the screen.
         ttb = self.uimanager.get_widget("/TimelineToolBar")
-        vbox.pack_start(ttb, expand=False)
+        vbox.pack_start(ttb, False, True, 0)
         ttb.show()
 
         if not self.settings.mainWindowShowMainToolbar:
@@ -485,8 +488,6 @@ class PitiviMainWindow(gtk.Window, Loggable):
                 page = 0
             elif tab == "transitions":
                 page = 1
-            elif tab == "title editor":
-                page = 2
             else:
                 self.debug("Invalid context tab switch requested")
                 return False
@@ -637,25 +638,24 @@ class PitiviMainWindow(gtk.Window, Loggable):
         dialog.destroy()
 
     def _aboutCb(self, unused_action):
-        abt = gtk.AboutDialog()
+        abt = Gtk.AboutDialog()
         abt.set_name(APPNAME)
         if in_devel:
             abt.set_version(_("Development version"))
         else:
             abt.set_version(pitivi_version)
         abt.set_website(APPURL)
-        ges_version_str = "GES %i.%i.%i.%i" % (ges.version())
-        gst_version_str = "GStreamer %i.%i.%i.%i" % (gst.version())
-        pygst_version_str = "PyGST %i.%i.%i.%i" % (gst.get_pygst_version())
+        ges_version_str = "GES %i.%i.%i.%i" % (GES.version())
+        gst_version_str = "GStreamer %i.%i.%i.%i" % (Gst.version())
         if self.app.version_information and \
            self.app.version_information["status"] != "CURRENT":
             version_str = _("PiTiVi %s is available." %
                 (self.app.version_information["current"]))
 
-            abt.set_comments("%s\n%s\n%s\n\n%s" %
-                (ges_version_str, pygst_version_str, gst_version_str, version_str))
+            abt.set_comments("%s\n\n%s\n\n%s" %
+                (ges_version_str, gst_version_str, version_str))
         else:
-            abt.set_comments("%s\n%s\n%s" % (ges_version_str, pygst_version_str, gst_version_str))
+            abt.set_comments("%s\n%s" % (ges_version_str, gst_version_str))
         authors = [_("Current maintainers:"),
                    "Jean-FranÃois Fortin Tam <nekohayo gmail com>",
                    "Thibault Saunier <thibault saunier collabora com>",
@@ -682,35 +682,35 @@ class PitiviMainWindow(gtk.Window, Loggable):
         documenters = ["Jean-FranÃois Fortin Tam <nekohayo gmail com>", ]
         abt.set_documenters(documenters)
         # TODO GTK3: use set_license_type instead
-        abt.set_license_type(gtk.License.LGPL_2_1)
+        abt.set_license_type(Gtk.License.LGPL_2_1)
         abt.set_icon_name("pitivi")
         abt.set_logo_icon_name("pitivi")
         abt.connect("response", self._aboutResponseCb)
         abt.show()
 
     def openProject(self):
-        chooser = gtk.FileChooserDialog(_("Open File..."),
+        chooser = Gtk.FileChooserDialog(_("Open File..."),
             self,
-            action=gtk.FILE_CHOOSER_ACTION_OPEN,
-            buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
-                gtk.STOCK_OPEN, gtk.RESPONSE_OK))
+            action=Gtk.FileChooserAction.OPEN,
+            buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
+                Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
         chooser.set_icon_name("pitivi")
         chooser.set_select_multiple(False)
         chooser.set_current_folder(self.settings.lastProjectFolder)
         for format in formats:
-            filt = gtk.FileFilter()
+            filt = Gtk.FileFilter()
             filt.set_name(format[1])
             for ext in format[2]:
                 filt.add_pattern("*%s" % ext)
             chooser.add_filter(filt)
-        default = gtk.FileFilter()
+        default = Gtk.FileFilter()
         default.set_name(_("All Supported Formats"))
-        default.add_custom(gtk.FILE_FILTER_URI, ges.formatter_can_load_uri, None)
+        default.add_custom(Gtk.FILE_FILTER_URI, GES.formatter_can_load_uri, None)
         chooser.add_filter(default)
 
         response = chooser.run()
         self.settings.lastProjectFolder = chooser.get_current_folder()
-        if response == gtk.RESPONSE_OK:
+        if response == Gtk.ResponseType.OK:
             self.app.projectManager.loadProject(chooser.get_uri())
 
         chooser.destroy()
@@ -773,10 +773,10 @@ class PitiviMainWindow(gtk.Window, Loggable):
 
     def _projectManagerSaveProjectFailedCb(self, projectManager, uri, exception=None):
         project_filename = unquote(uri.split("/")[-1])
-        dialog = gtk.MessageDialog(self,
-            gtk.DIALOG_MODAL,
-            gtk.MESSAGE_ERROR,
-            gtk.BUTTONS_OK,
+        dialog = Gtk.MessageDialog(self,
+            Gtk.DialogFlags.MODAL,
+            Gtk.MessageType.ERROR,
+            Gtk.ButtonsType.OK,
             _('Unable to save project "%s"') % project_filename)
         dialog.set_title(_("Error Saving Project"))
         if exception:
@@ -800,21 +800,21 @@ class PitiviMainWindow(gtk.Window, Loggable):
             return True
 
         if project.uri:
-            save = gtk.STOCK_SAVE
+            save = Gtk.STOCK_SAVE
         else:
-            save = gtk.STOCK_SAVE_AS
+            save = Gtk.STOCK_SAVE_AS
 
-        dialog = gtk.Dialog("",
-            self, gtk.DIALOG_MODAL,
-            (_("Close without saving"), gtk.RESPONSE_REJECT,
-                    gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
-                    save, gtk.RESPONSE_YES))
+        dialog = Gtk.Dialog("",
+            self, Gtk.DialogFlags.MODAL,
+            (_("Close without saving"), Gtk.ResponseType.REJECT,
+                    Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
+                    save, Gtk.ResponseType.YES))
         dialog.set_icon_name("pitivi")
         dialog.set_resizable(False)
-        dialog.set_default_response(gtk.RESPONSE_YES)
+        dialog.set_default_response(Gtk.ResponseType.YES)
         dialog.set_transient_for(self)
 
-        primary = gtk.Label()
+        primary = Gtk.Label()
         primary.set_line_wrap(True)
         primary.set_use_markup(True)
         primary.set_alignment(0, 0.5)
@@ -822,7 +822,7 @@ class PitiviMainWindow(gtk.Window, Loggable):
         message = _("Save changes to the current project before closing?")
         primary.set_markup("<span weight=\"bold\">" + message + "</span>")
 
-        secondary = gtk.Label()
+        secondary = Gtk.Label()
         secondary.set_line_wrap(True)
         secondary.set_use_markup(True)
         secondary.set_alignment(0, 0.5)
@@ -839,32 +839,32 @@ class PitiviMainWindow(gtk.Window, Loggable):
                                     "your changes will be lost.")
 
         # put the text in a vbox
-        vbox = gtk.VBox(False, SPACING * 2)
-        vbox.pack_start(primary, expand=True, fill=True)
-        vbox.pack_start(secondary, expand=True, fill=True)
+        vbox = Gtk.VBox(False, SPACING * 2)
+        vbox.pack_start(primary, True, True, 0)
+        vbox.pack_start(secondary, True, True, 0)
 
         # make the [[image] text] hbox
-        image = gtk.image_new_from_stock(gtk.STOCK_DIALOG_WARNING,
-               gtk.ICON_SIZE_DIALOG)
-        hbox = gtk.HBox(False, SPACING * 2)
-        hbox.pack_start(image, expand=False)
-        hbox.pack_start(vbox, expand=True, fill=True)
+        image = Gtk.Image.new_from_stock(Gtk.STOCK_DIALOG_WARNING,
+               Gtk.IconSize.DIALOG)
+        hbox = Gtk.HBox(False, SPACING * 2)
+        hbox.pack_start(image, False, True, 0)
+        hbox.pack_start(vbox, True, True, 0)
         hbox.set_border_width(SPACING)
 
         # stuff the hbox in the dialog
         content_area = dialog.get_content_area()
-        content_area.pack_start(hbox, expand=True, fill=True)
+        content_area.pack_start(hbox, True, True, 0)
         content_area.set_spacing(SPACING * 2)
         hbox.show_all()
 
         response = dialog.run()
         dialog.destroy()
-        if response == gtk.RESPONSE_YES:
+        if response == Gtk.ResponseType.YES:
             if project.uri is not None:
                 res = self.app.projectManager.saveProject(project, overwrite=True)
             else:
                 res = self._saveProjectAsCb(None)
-        elif response == gtk.RESPONSE_REJECT:
+        elif response == Gtk.ResponseType.REJECT:
             res = True
         else:
             res = False
@@ -882,32 +882,32 @@ class PitiviMainWindow(gtk.Window, Loggable):
 
     def _projectManagerRevertingToSavedCb(self, projectManager, unused_project):
         if self.app.current.hasUnsavedModifications():
-            dialog = gtk.MessageDialog(self,
-                    gtk.DIALOG_MODAL,
-                    gtk.MESSAGE_WARNING,
-                    gtk.BUTTONS_NONE,
+            dialog = Gtk.MessageDialog(self,
+                    Gtk.DialogFlags.MODAL,
+                    Gtk.MessageType.WARNING,
+                    Gtk.ButtonsType.NONE,
                     _("Do you want to reload current project?"))
             dialog.set_icon_name("pitivi")
-            dialog.add_buttons(gtk.STOCK_CANCEL, gtk.RESPONSE_NO,
-                    gtk.STOCK_REVERT_TO_SAVED, gtk.RESPONSE_YES)
+            dialog.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.NO,
+                    Gtk.STOCK_REVERT_TO_SAVED, Gtk.ResponseType.YES)
             dialog.set_title(_("Revert to saved project"))
             dialog.set_resizable(False)
             dialog.set_property("secondary-text",
                     _("All unsaved changes will be lost."))
-            dialog.set_default_response(gtk.RESPONSE_NO)
+            dialog.set_default_response(Gtk.ResponseType.NO)
             dialog.set_transient_for(self)
             response = dialog.run()
             dialog.destroy()
-            if response != gtk.RESPONSE_YES:
+            if response != Gtk.ResponseType.YES:
                 return False
         return True
 
     def _projectManagerNewProjectFailedCb(self, projectManager, uri, exception):
         project_filename = unquote(uri.split("/")[-1])
-        dialog = gtk.MessageDialog(self,
-            gtk.DIALOG_MODAL,
-            gtk.MESSAGE_ERROR,
-            gtk.BUTTONS_OK,
+        dialog = Gtk.MessageDialog(self,
+            Gtk.DialogFlags.MODAL,
+            Gtk.MessageType.ERROR,
+            Gtk.ButtonsType.OK,
             _('Unable to load project "%s"') % project_filename)
         dialog.set_title(_("Error Loading Project"))
         dialog.set_property("secondary-use-markup", True)
@@ -917,18 +917,18 @@ class PitiviMainWindow(gtk.Window, Loggable):
         dialog.destroy()
 
     def _projectManagerMissingUriCb(self, instance, formatter, tfs):
-        dialog = gtk.Dialog(_("Locate missing file..."),
+        dialog = Gtk.Dialog(_("Locate missing file..."),
             self,
-            gtk.DIALOG_MODAL,
-            buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
-            gtk.STOCK_OPEN, gtk.RESPONSE_OK))
+            Gtk.DialogFlags.MODAL,
+            buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
+            Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
         dialog.set_icon_name("pitivi")
         dialog.set_border_width(SPACING * 2)
         dialog.get_content_area().set_spacing(SPACING)
         dialog.set_transient_for(self)
 
         # This box will contain the label and optionally a thumbnail
-        hbox = gtk.HBox()
+        hbox = Gtk.HBox()
         hbox.set_spacing(SPACING)
 
         # Check if we have a thumbnail available.
@@ -940,14 +940,14 @@ class PitiviMainWindow(gtk.Window, Loggable):
         thumb_path_normal = thumb_dir + thumbnail_hash + ".png"
         if os.path.exists(thumb_path_normal):
             self.debug("A thumbnail file was found for %s" % tfs.get_uri())
-            thumbnail = gtk.image_new_from_file(thumb_path_normal)
+            thumbnail = Gtk.image_new_from_file(thumb_path_normal)
             thumbnail.set_padding(0, SPACING)
-            hbox.pack_start(thumbnail, False, False)
+            hbox.pack_start(thumbnail, False, False, 0)
 
         # FIXME GES port, help user identify files with more information
         # need work to be done in GES directly
         # TODO: display the filesize to help the user identify the file
-        #if info.get_duration() == gst.CLOCK_TIME_NONE:
+        #if info.get_duration() == Gst.CLOCK_TIME_NONE:
             ## The file is probably an image, not video or audio.
             #text = _('The following file has moved: "<b>%s</b>"'
                      #'\nPlease specify its new location:'
@@ -962,20 +962,20 @@ class PitiviMainWindow(gtk.Window, Loggable):
                  '\nPlease specify its new location:'
                  % info_name(tfs))
 
-        label = gtk.Label()
+        label = Gtk.Label()
         label.set_markup(text)
-        hbox.pack_start(label, False, False)
-        dialog.get_content_area().pack_start(hbox, False, False)
+        hbox.pack_start(label, False, False, 0)
+        dialog.get_content_area().pack_start(hbox, False, False, 0)
         hbox.show_all()
 
-        chooser = gtk.FileChooserWidget(action=gtk.FILE_CHOOSER_ACTION_OPEN)
+        chooser = Gtk.FileChooserWidget(action=Gtk.FileChooserAction.OPEN)
         chooser.set_select_multiple(False)
         pw = PreviewWidget(self.app)
         chooser.set_preview_widget(pw)
         chooser.set_use_preview_label(False)
         chooser.connect('update-preview', pw.add_preview_request)
         chooser.set_current_folder(self.settings.lastProjectFolder)
-        dialog.get_content_area().pack_start(chooser, True, True)
+        dialog.get_content_area().pack_start(chooser, True, True, 0)
         chooser.show()
 
         # If the window is too big, the window manager will resize it so that
@@ -983,7 +983,7 @@ class PitiviMainWindow(gtk.Window, Loggable):
         dialog.set_default_size(1024, 1000)
         response = dialog.run()
 
-        if response == gtk.RESPONSE_OK:
+        if response == Gtk.ResponseType.OK:
             self.log("User chose a new URI for the missing file")
             new_uri = chooser.get_uri()
             if new_uri:
@@ -1093,18 +1093,17 @@ class PitiviMainWindow(gtk.Window, Loggable):
 
     def _timelineDurationChangedCb(self, timeline, unused_duration):
         duration = timeline.get_duration()
-        self.debug("Timeline duration changed to %s",
-            gst.TIME_ARGS(duration))
+        self.debug("Timeline duration changed to %s", duration)
         self.render_button.set_sensitive(duration > 0)
 
 ## other
     def _showExportDialog(self, project):
         self.log("Export requested")
-        chooser = gtk.FileChooserDialog(_("Export To..."),
+        chooser = Gtk.FileChooserDialog(_("Export To..."),
             self,
-            action=gtk.FILE_CHOOSER_ACTION_SAVE,
-            buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
-            gtk.STOCK_SAVE, gtk.RESPONSE_OK))
+            action=Gtk.FileChooserAction.SAVE,
+            buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
+            Gtk.STOCK_SAVE, Gtk.ResponseType.OK))
 
         chooser.set_icon_name("pitivi")
         chooser.set_select_multiple(False)
@@ -1116,11 +1115,11 @@ class PitiviMainWindow(gtk.Window, Loggable):
         chooser.set_current_folder(self.settings.lastProjectFolder)
         chooser.props.do_overwrite_confirmation = True
 
-        filt = gtk.FileFilter()
+        filt = Gtk.FileFilter()
         filt.set_name("Tar Archive")
         filt.add_pattern("*.tar")
         chooser.add_filter(filt)
-        default = gtk.FileFilter()
+        default = Gtk.FileFilter()
         default.set_name(_("Detect Automatically"))
         default.add_pattern("*")
         chooser.add_filter(default)
@@ -1130,9 +1129,9 @@ class PitiviMainWindow(gtk.Window, Loggable):
         if current_folder:
             self.settings.lastProjectFolder = current_folder
 
-        if response == gtk.RESPONSE_OK:
+        if response == Gtk.ResponseType.OK:
             self.log("User chose a URI to export project to")
-            # need to do this to work around bug in gst.uri_construct
+            # need to do this to work around bug in Gst.uri_construct
             # which escapes all /'s in path!
             uri = "file://" + chooser.get_filename()
             format = chooser.get_filter().get_name()
@@ -1149,11 +1148,11 @@ class PitiviMainWindow(gtk.Window, Loggable):
 
     def _showSaveAsDialog(self, project):
         self.log("Save URI requested")
-        chooser = gtk.FileChooserDialog(_("Save As..."),
+        chooser = Gtk.FileChooserDialog(_("Save As..."),
             self,
-            action=gtk.FILE_CHOOSER_ACTION_SAVE,
-            buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
-            gtk.STOCK_SAVE, gtk.RESPONSE_OK))
+            action=Gtk.FileChooserAction.SAVE,
+            buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
+            Gtk.STOCK_SAVE, Gtk.ResponseType.OK))
 
         chooser.set_icon_name("pitivi")
         chooser.set_select_multiple(False)
@@ -1161,12 +1160,12 @@ class PitiviMainWindow(gtk.Window, Loggable):
         chooser.set_current_folder(self.settings.lastProjectFolder)
         chooser.props.do_overwrite_confirmation = True
         for format in formats:
-            filt = gtk.FileFilter()
+            filt = Gtk.FileFilter()
             filt.set_name(format[1])
             for ext in format[2]:
                 filt.add_pattern("*.%s" % ext)
             chooser.add_filter(filt)
-        default = gtk.FileFilter()
+        default = Gtk.FileFilter()
         default.set_name(_("Detect Automatically"))
         default.add_pattern("*")
         chooser.add_filter(default)
@@ -1176,9 +1175,9 @@ class PitiviMainWindow(gtk.Window, Loggable):
         if current_folder:
             self.settings.lastProjectFolder = current_folder
 
-        if response == gtk.RESPONSE_OK:
+        if response == Gtk.ResponseType.OK:
             self.log("User chose a URI to save project to")
-            # need to do this to work around bug in gst.uri_construct
+            # need to do this to work around bug in Gst.uri_construct
             # which escapes all /'s in path!
             uri = "file://" + chooser.get_filename()
             format = chooser.get_filter().get_name()
@@ -1221,7 +1220,7 @@ class PitiviMainWindow(gtk.Window, Loggable):
 
     def _viewUri(self, path):
         """ Preview a media file from the media library """
-        preview_window = gtk.Window()
+        preview_window = Gtk.Window()
         preview_window.set_title(_("Preview - click outside to close"))
         preview_window.set_transient_for(self)
         preview_window.connect("focus-out-event", self._leavePreviewCb)
@@ -1258,7 +1257,7 @@ class PitiviMainWindow(gtk.Window, Loggable):
             preview_window.resize(1, 1)
         # Setting the position of the window only works if it's currently hidden
         # otherwise, after the resize the position will not be readjusted
-        preview_window.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+        preview_window.set_position(Gtk.WindowPosition.CENTER_ON_PARENT)
         preview_window.show()
 
         previewer.play()
diff --git a/pitivi/mediafilespreviewer.py b/pitivi/mediafilespreviewer.py
index a2146c7..489be44 100644
--- a/pitivi/mediafilespreviewer.py
+++ b/pitivi/mediafilespreviewer.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
-import gobject
-import gst
-import gtk
-import pango
+from gi.repository import GObject
+from gi.repository import Gst
+from gi.repository import Gtk
+from gi.repository import Pango
 import os
 
 from gettext import gettext as _
-from gst.pbutils import Discoverer
+from gi.repository.GstPbutils import Discoverer
 
 from pitivi.configure import get_pixmap_dir
 from pitivi.settings import GlobalSettings
@@ -37,21 +37,21 @@ GlobalSettings.addConfigOption('FCpreviewHeight',
     key='video-preview-height',
     default=PREVIEW_HEIGHT)
 
-acceptable_tags = [gst.TAG_ALBUM_ARTIST,
-                    gst.TAG_ARTIST,
-                    gst.TAG_TITLE,
-                    gst.TAG_ALBUM,
-                    gst.TAG_BITRATE,
-                    gst.TAG_COMPOSER,
-                    gst.TAG_GENRE,
-                    gst.TAG_PERFORMER,
-                    gst.TAG_DATE]
+acceptable_tags = [Gst.TAG_ALBUM_ARTIST,
+                    Gst.TAG_ARTIST,
+                    Gst.TAG_TITLE,
+                    Gst.TAG_ALBUM,
+                    Gst.TAG_BITRATE,
+                    Gst.TAG_COMPOSER,
+                    Gst.TAG_GENRE,
+                    Gst.TAG_PERFORMER,
+                    Gst.TAG_DATE]
 
 
-class PreviewWidget(gtk.VBox, Loggable):
+class PreviewWidget(Gtk.VBox, Loggable):
 
     def __init__(self, instance):
-        gtk.VBox.__init__(self)
+        GObject.GObject.__init__(self)
         Loggable.__init__(self)
 
         self.log("Init PreviewWidget")
@@ -61,10 +61,10 @@ class PreviewWidget(gtk.VBox, Loggable):
         self.preview_cache = {}
         self.preview_cache_errors = {}
 
-        self.discoverer = Discoverer.new(gst.SECOND)
+        self.discoverer = Discoverer.new(Gst.SECOND)
 
         #playbin for play pics
-        self.player = gst.element_factory_make("playbin", "preview-player")
+        self.player = Gst.ElementFactory.make("playbin", "preview-player")
         bus = self.player.get_bus()
         bus.add_signal_watch()
         bus.connect('message', self._bus_message_cb)
@@ -72,11 +72,11 @@ class PreviewWidget(gtk.VBox, Loggable):
         bus.connect('sync-message::element', self._sync_message_cb)
         bus.connect('message::tag', self._tag_found_cb)
         self.__videosink = self.player.get_property("video-sink")
-        self.__fakesink = gst.element_factory_make("fakesink", "fakesink")
+        self.__fakesink = Gst.ElementFactory.make("fakesink", "fakesink")
 
         #some global variables for preview handling
         self.is_playing = False
-        self.time_format = gst.Format(gst.FORMAT_TIME)
+        self.time_format = Gst.Format(Gst.FORMAT_TIME)
         self.original_dims = (PREVIEW_WIDTH, PREVIEW_HEIGHT)
         self.countinuous_seek = False
         self.current_selected_uri = ""
@@ -87,65 +87,65 @@ class PreviewWidget(gtk.VBox, Loggable):
         # Gui elements:
         # Drawing area for video output
         self.preview_video = ViewerWidget()
-        self.preview_video.modify_bg(gtk.STATE_NORMAL, self.preview_video.style.black)
-        self.pack_start(self.preview_video, expand=False)
+        self.preview_video.modify_bg(Gtk.StateType.NORMAL, self.preview_video.style.black)
+        self.pack_start(self.preview_video, False, True, 0)
 
         # An image for images and audio
-        self.preview_image = gtk.Image()
+        self.preview_image = Gtk.Image()
         self.preview_image.set_size_request(self.settings.FCpreviewWidth, self.settings.FCpreviewHeight)
         self.preview_image.show()
-        self.pack_start(self.preview_image, expand=False)
+        self.pack_start(self.preview_image, False, True, 0)
 
         # Play button
-        self.bbox = gtk.HBox()
-        self.play_button = gtk.ToolButton(gtk.STOCK_MEDIA_PLAY)
+        self.bbox = Gtk.HBox()
+        self.play_button = Gtk.ToolButton(Gtk.STOCK_MEDIA_PLAY)
         self.play_button.connect("clicked", self._on_start_stop_clicked_cb)
-        self.bbox.pack_start(self.play_button, expand=False)
+        self.bbox.pack_start(self.play_button, False, True, 0)
 
         #Scale for position handling
-        self.pos_adj = gtk.Adjustment()
-        self.seeker = gtk.HScale(self.pos_adj)
+        self.pos_adj = Gtk.Adjustment()
+        self.seeker = Gtk.HScale(self.pos_adj)
         self.seeker.connect('button-press-event', self._on_seeker_press_cb)
         self.seeker.connect('button-release-event', self._on_seeker_press_cb)
         self.seeker.connect('motion-notify-event', self._on_motion_notify_cb)
         self.seeker.set_draw_value(False)
         self.seeker.show()
-        self.bbox.pack_start(self.seeker)
+        self.bbox.pack_start(self.seeker, True, True, 0)
 
         # Zoom buttons
-        self.b_zoom_in = gtk.ToolButton(gtk.STOCK_ZOOM_IN)
+        self.b_zoom_in = Gtk.ToolButton(Gtk.STOCK_ZOOM_IN)
         self.b_zoom_in.connect("clicked", self._on_zoom_clicked_cb, 1)
-        self.b_zoom_out = gtk.ToolButton(gtk.STOCK_ZOOM_OUT)
+        self.b_zoom_out = Gtk.ToolButton(Gtk.STOCK_ZOOM_OUT)
         self.b_zoom_out.connect("clicked", self._on_zoom_clicked_cb, -1)
-        self.bbox.pack_start(self.b_zoom_in, expand=False)
-        self.bbox.pack_start(self.b_zoom_out, expand=False)
+        self.bbox.pack_start(self.b_zoom_in, False, True, 0)
+        self.bbox.pack_start(self.b_zoom_out, False, True, 0)
         self.bbox.show_all()
-        self.pack_start(self.bbox, expand=False, fill=False)
+        self.pack_start(self.bbox, False, False, 0)
 
         # Label for metadata tags
-        self.l_tags = gtk.Label()
-        self.l_tags.set_justify(gtk.JUSTIFY_LEFT)
-        self.l_tags.set_ellipsize(pango.ELLIPSIZE_END)
+        self.l_tags = Gtk.Label()
+        self.l_tags.set_justify(Gtk.Justification.LEFT)
+        self.l_tags.set_ellipsize(Pango.EllipsizeMode.END)
         self.l_tags.show()
-        self.pack_start(self.l_tags, expand=False, fill=False)
+        self.pack_start(self.l_tags, False, False, 0)
 
         # Error handling
-        vbox = gtk.VBox()
+        vbox = Gtk.VBox()
         vbox.set_spacing(SPACING)
-        self.l_error = gtk.Label(_("PiTiVi can not preview this file."))
-        self.b_details = gtk.Button(_("More info"))
+        self.l_error = Gtk.Label(label=_("PiTiVi can not preview this file."))
+        self.b_details = Gtk.Button(_("More info"))
         self.b_details.connect('clicked', self._on_b_details_clicked_cb)
-        vbox.pack_start(self.l_error)
-        vbox.pack_start(self.b_details, expand=False, fill=False)
+        vbox.pack_start(self.l_error, True, True, 0)
+        vbox.pack_start(self.b_details, False, False, 0)
         vbox.show()
-        self.pack_start(vbox, expand=False, fill=False)
+        self.pack_start(vbox, False, False, 0)
 
     def setMinimal(self):
         self.remove(self.l_tags)
         self.b_zoom_in.hide()
         self.b_zoom_out.hide()
         # Allow expanding/filling and pack the video preview below the controls
-        self.set_child_packing(self.preview_video, True, True, 0, gtk.PACK_END)
+        self.set_child_packing(self.preview_video, True, True, 0, Gtk.PACK_END)
 
     def add_preview_request(self, dialogbox):
         """add a preview request """
@@ -199,11 +199,11 @@ class PreviewWidget(gtk.VBox, Loggable):
             if video.is_image():
                 self.current_preview_type = 'image'
                 self.preview_video.hide()
-                pixbuf = gtk.gdk.pixbuf_new_from_file(gst.uri_get_location(uri))
+                pixbuf = GdkPixbuf.Pixbuf.new_from_file(Gst.uri_get_location(uri))
                 pixbuf_w = pixbuf.get_width()
                 pixbuf_h = pixbuf.get_height()
                 w, h = self.__get_best_size(pixbuf_w, pixbuf_h)
-                pixbuf = pixbuf.scale_simple(w, h, gtk.gdk.INTERP_NEAREST)
+                pixbuf = pixbuf.scale_simple(w, h, GdkPixbuf.InterpType.NEAREST)
                 self.preview_image.set_from_pixbuf(pixbuf)
                 self.preview_image.set_size_request(self.settings.FCpreviewWidth, self.settings.FCpreviewHeight)
                 self.preview_image.show()
@@ -217,7 +217,7 @@ class PreviewWidget(gtk.VBox, Loggable):
                 self.preview_image.hide()
                 self.player.set_property("video-sink", self.__videosink)
                 self.player.set_property("uri", self.current_selected_uri)
-                self.player.set_state(gst.STATE_PAUSED)
+                self.player.set_state(Gst.State.PAUSED)
                 self.pos_adj.props.upper = duration
                 w, h = self.__get_best_size((video.get_par_num() / video.get_par_denom()) * video.get_width(),
                     video.get_height())
@@ -246,10 +246,10 @@ class PreviewWidget(gtk.VBox, Loggable):
             self.preview_image.set_size_request(PREVIEW_WIDTH, PREVIEW_HEIGHT)
             self.description = beautify_stream(audio) + "\n" + \
                 _("<b>Duration</b>: %s") % pretty_duration + "\n"
-            self.player.set_state(gst.STATE_NULL)
+            self.player.set_state(Gst.State.NULL)
             self.player.set_property("uri", self.current_selected_uri)
             self.player.set_property("video-sink", self.__fakesink)
-            self.player.set_state(gst.STATE_PAUSED)
+            self.player.set_state(Gst.State.PAUSED)
             self.play_button.show()
             self.seeker.show()
             self.b_zoom_in.hide()
@@ -261,17 +261,17 @@ class PreviewWidget(gtk.VBox, Loggable):
         self.b_details.show()
 
     def play(self):
-        self.player.set_state(gst.STATE_PLAYING)
+        self.player.set_state(Gst.State.PLAYING)
         self.is_playing = True
-        self.play_button.set_stock_id(gtk.STOCK_MEDIA_PAUSE)
+        self.play_button.set_stock_id(Gtk.STOCK_MEDIA_PAUSE)
         #Make sure position is updated regularly
-        gobject.timeout_add(500, self._update_position)
+        GObject.timeout_add(500, self._update_position)
         self.debug("Preview started")
 
     def pause(self):
-        self.player.set_state(gst.STATE_PAUSED)
+        self.player.set_state(Gst.State.PAUSED)
         self.is_playing = False
-        self.play_button.set_stock_id(gtk.STOCK_MEDIA_PLAY)
+        self.play_button.set_stock_id(Gtk.STOCK_MEDIA_PLAY)
         self.log("Preview paused")
 
     def clear_preview(self):
@@ -282,8 +282,8 @@ class PreviewWidget(gtk.VBox, Loggable):
         self.b_details.hide()
         self.description = ""
         self.l_tags.set_markup("")
-        self.play_button.set_stock_id(gtk.STOCK_MEDIA_PLAY)
-        self.player.set_state(gst.STATE_NULL)
+        self.play_button.set_stock_id(Gtk.STOCK_MEDIA_PLAY)
+        self.player.set_state(Gst.State.NULL)
         self.is_playing = False
         self.tags = {}
         self.current_selected_uri = ""
@@ -293,30 +293,30 @@ class PreviewWidget(gtk.VBox, Loggable):
 
     def _on_seeker_press_cb(self, widget, event):
         event.button = 2
-        if event.type == gtk.gdk.BUTTON_PRESS:
+        if event.type == Gdk.EventType.BUTTON_PRESS:
             self.countinuous_seek = True
             if self.is_playing:
-                self.player.set_state(gst.STATE_PAUSED)
-        elif event.type == gtk.gdk.BUTTON_RELEASE:
+                self.player.set_state(Gst.State.PAUSED)
+        elif event.type == Gdk.BUTTON_RELEASE:
             self.countinuous_seek = False
             value = long(widget.get_value())
-            self.player.seek_simple(self.time_format, gst.SEEK_FLAG_FLUSH, value)
+            self.player.seek_simple(self.time_format, Gst.SeekFlags.FLUSH, value)
             if self.is_playing:
-                self.player.set_state(gst.STATE_PLAYING)
+                self.player.set_state(Gst.State.PLAYING)
 
     def _on_motion_notify_cb(self, widget, event):
         if self.countinuous_seek:
             value = widget.get_value()
-            self.player.seek_simple(self.time_format, gst.SEEK_FLAG_FLUSH, value)
+            self.player.seek_simple(self.time_format, Gst.SeekFlags.FLUSH, value)
 
     def _bus_message_cb(self, bus, message):
-        if message.type == gst.MESSAGE_EOS:
-            self.player.set_state(gst.STATE_NULL)
+        if message.type == Gst.MESSAGE_EOS:
+            self.player.set_state(Gst.State.NULL)
             self.is_playing = False
-            self.play_button.set_stock_id(gtk.STOCK_MEDIA_PLAY)
+            self.play_button.set_stock_id(Gtk.STOCK_MEDIA_PLAY)
             self.pos_adj.set_value(0)
-        elif message.type == gst.MESSAGE_ERROR:
-            self.player.set_state(gst.STATE_NULL)
+        elif message.type == Gst.MESSAGE_ERROR:
+            self.player.set_state(Gst.State.NULL)
             self.is_playing = False
             err, dbg = message.parse_error()
             self.error("Error: %s " % err, dbg)
@@ -359,8 +359,8 @@ class PreviewWidget(gtk.VBox, Loggable):
                 h *= 0.8
                 if (w, h) < self.original_dims:
                     (w, h) = self.original_dims
-            pixbuf = gtk.gdk.pixbuf_new_from_file(gst.uri_get_location(self.current_selected_uri))
-            pixbuf = pixbuf.scale_simple(int(w), int(h), gtk.gdk.INTERP_BILINEAR)
+            pixbuf = GdkPixbuf.Pixbuf.new_from_file(Gst.uri_get_location(self.current_selected_uri))
+            pixbuf = pixbuf.scale_simple(int(w), int(h), GdkPixbuf.InterpType.BILINEAR)
 
             w = max(w, self.settings.FCpreviewWidth)
             h = max(h, self.settings.FCpreviewHeight)
@@ -371,7 +371,7 @@ class PreviewWidget(gtk.VBox, Loggable):
             self.settings.FCpreviewHeight = int(h)
 
     def _sync_message_cb(self, bus, mess):
-        if mess.type == gst.MESSAGE_ELEMENT:
+        if mess.type == Gst.MESSAGE_ELEMENT:
             if mess.has_name('prepare-window-handle'):
                 sink = mess.src
 
@@ -393,19 +393,19 @@ class PreviewWidget(gtk.VBox, Loggable):
                     realsink.set_property('force-aspect-ratio', True)
                     realsink.set_property("handle-expose", True)
                 finally:
-                    gtk.gdk.threads_enter()
+                    Gdk.threads_enter()
                     sink.set_window_handle(self.preview_video.window_xid)
                     sink.expose()
-                    gtk.gdk.threads_leave()
-        return gst.BUS_PASS
+                    Gdk.threads_leave()
+        return Gst.BUS_PASS
 
     def _appendTag(self, taglist, tag, unused_udata):
-            if tag in acceptable_tags and gst.tag_get_type(tag) in (gobject.TYPE_STRING,
-                                   gobject.TYPE_DOUBLE,
-                                   gobject.TYPE_FLOAT,
-                                   gobject.TYPE_INT,
-                                   gobject.TYPE_UINT):
-                name = gst.tag_get_nick(tag)
+            if tag in acceptable_tags and Gst.tag_get_type(tag) in (GObject.TYPE_STRING,
+                                   GObject.TYPE_DOUBLE,
+                                   GObject.TYPE_FLOAT,
+                                   GObject.TYPE_INT,
+                                   GObject.TYPE_UINT):
+                name = Gst.tag_get_nick(tag)
                 value = unicode(taglist.get_string(tag)[1]).replace('<', ' ').replace('>', ' ')
                 self.tags[name] = value
 
@@ -422,10 +422,10 @@ class PreviewWidget(gtk.VBox, Loggable):
     def _on_b_details_clicked_cb(self, unused_button):
         mess = self.preview_cache_errors.get(self.current_selected_uri, None)
         if mess is not None:
-            dialog = gtk.MessageDialog(None,
-                gtk.DIALOG_MODAL,
-                gtk.MESSAGE_WARNING,
-                gtk.BUTTONS_OK,
+            dialog = Gtk.MessageDialog(None,
+                Gtk.DialogFlags.MODAL,
+                Gtk.MessageType.WARNING,
+                Gtk.ButtonsType.OK,
                 str(mess))
             dialog.set_icon_name("pitivi")
             dialog.set_title(_("Error while analyzing a file"))
@@ -433,7 +433,7 @@ class PreviewWidget(gtk.VBox, Loggable):
             dialog.destroy()
 
     def _destroy_cb(self, widget):
-        self.player.set_state(gst.STATE_NULL)
+        self.player.set_state(Gst.State.NULL)
         self.is_playing = False
         #FIXME: are the following lines really needed?
         del self.player
diff --git a/pitivi/medialibrary.py b/pitivi/medialibrary.py
index 54c55d5..e41513e 100644
--- a/pitivi/medialibrary.py
+++ b/pitivi/medialibrary.py
@@ -24,11 +24,13 @@
 Handles the list of source for a project
 """
 
-import gst
-import ges
-import gobject
-import gtk
-import pango
+from gi.repository import Gst
+from gi.repository import GES
+from gi.repository import GObject
+from gi.repository import Gtk
+from gi.repository import Pango
+from gi.repository import GdkPixbuf
+
 import os
 import time
 
@@ -37,7 +39,7 @@ from gi.repository import Gdk
 from urllib import unquote
 from gettext import gettext as _
 from hashlib import md5
-from gst.pbutils import Discoverer, DiscovererVideoInfo
+from gi.repository.GstPbutils import Discoverer, DiscovererVideoInfo
 
 from pitivi.configure import get_pixmap_dir
 from pitivi.settings import GlobalSettings
@@ -110,7 +112,7 @@ ui = '''
 </ui>
 '''
 
-INVISIBLE = gtk.gdk.pixbuf_new_from_file(os.path.join(get_pixmap_dir(),
+INVISIBLE = GdkPixbuf.Pixbuf.new_from_file(os.path.join(get_pixmap_dir(),
     "invisible.png"))
 
 
@@ -159,7 +161,7 @@ class MediaLibrary(Signallable, Loggable):
         self._ordered_sources = []
         self._resetImportCounters()
 
-        self.discoverer = self.discovererClass.new(gst.SECOND)
+        self.discoverer = self.discovererClass.new(Gst.SECOND)
         self.discoverer.connect("discovered", self.addDiscovererInfo)
         self.discoverer.connect("finished", self.finishDiscovererCb)
         self.discoverer.start()
@@ -259,15 +261,15 @@ class MediaLibrary(Signallable, Loggable):
         return self._ordered_sources
 
 
-class MediaLibraryWidget(gtk.VBox, Loggable):
+class MediaLibraryWidget(Gtk.VBox, Loggable):
     """ Widget for listing sources """
 
     __gsignals__ = {
-        'play': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
-                (gobject.TYPE_PYOBJECT,))}
+        'play': (GObject.SignalFlags.RUN_LAST, None,
+                (GObject.TYPE_PYOBJECT,))}
 
     def __init__(self, instance, uiman):
-        gtk.VBox.__init__(self)
+        GObject.GObject.__init__(self)
         Loggable.__init__(self)
 
         self.pending_rows = []
@@ -282,24 +284,24 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
 
         # Store
         # icon, infotext, objectfactory, uri, length
-        self.storemodel = gtk.ListStore(gtk.gdk.Pixbuf, gtk.gdk.Pixbuf,
+        self.storemodel = Gtk.ListStore(GdkPixbuf.Pixbuf, GdkPixbuf.Pixbuf,
             str, object, str, str, str, str)
 
         # Scrolled Windows
-        self.treeview_scrollwin = gtk.ScrolledWindow()
-        self.treeview_scrollwin.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
-        self.treeview_scrollwin.set_shadow_type(gtk.SHADOW_ETCHED_IN)
+        self.treeview_scrollwin = Gtk.ScrolledWindow()
+        self.treeview_scrollwin.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
+        self.treeview_scrollwin.set_shadow_type(Gtk.ShadowType.ETCHED_IN)
 
-        self.iconview_scrollwin = gtk.ScrolledWindow()
-        self.iconview_scrollwin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
-        self.iconview_scrollwin.set_shadow_type(gtk.SHADOW_ETCHED_IN)
+        self.iconview_scrollwin = Gtk.ScrolledWindow()
+        self.iconview_scrollwin.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
+        self.iconview_scrollwin.set_shadow_type(Gtk.ShadowType.ETCHED_IN)
 
         # Popup Menu
-        self.popup = gtk.Menu()
-        self.popup_remitem = gtk.ImageMenuItem(_("_Remove from Project"))
-        self.popup_playmenuitem = gtk.MenuItem(_("_Preview Clip"))
-        self.popup_clipprop = gtk.MenuItem(_("_Clip Properties..."))
-        self.popup_insertEnd = gtk.MenuItem(_("Insert at _End of Timeline"))
+        self.popup = Gtk.Menu()
+        self.popup_remitem = Gtk.ImageMenuItem(_("_Remove from Project"))
+        self.popup_playmenuitem = Gtk.MenuItem(_("_Preview Clip"))
+        self.popup_clipprop = Gtk.MenuItem(_("_Clip Properties..."))
+        self.popup_insertEnd = Gtk.MenuItem(_("Insert at _End of Timeline"))
         self.popup_remitem.connect("activate", self._removeClickedCb)
         self.popup_playmenuitem.connect("activate", self._previewClickedCb)
         self.popup_clipprop.connect("activate", self._clipPropertiesCb)
@@ -316,18 +318,18 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
         self._importDialog = None
 
         # Search/filter box
-        self.search_hbox = gtk.HBox()
+        self.search_hbox = Gtk.HBox()
         self.search_hbox.set_spacing(SPACING)
         self.search_hbox.set_border_width(3)  # Prevents being flush against the notebook
-        searchLabel = gtk.Label(_("Search:"))
-        searchEntry = gtk.Entry()
-        searchEntry.set_icon_from_stock(gtk.ENTRY_ICON_SECONDARY, "gtk-clear")
+        searchLabel = Gtk.Label(label=_("Search:"))
+        searchEntry = Gtk.Entry()
+        searchEntry.set_icon_from_stock(Gtk.EntryIconPosition.SECONDARY, "gtk-clear")
         searchEntry.connect("changed", self._searchEntryChangedCb)
         searchEntry.connect("focus-in-event", self._disableKeyboardShortcutsCb)
         searchEntry.connect("focus-out-event", self._enableKeyboardShortcutsCb)
         searchEntry.connect("icon-press", self._searchEntryIconClickedCb)
-        self.search_hbox.pack_start(searchLabel, expand=False)
-        self.search_hbox.pack_end(searchEntry, expand=True)
+        self.search_hbox.pack_start(searchLabel, False, True, 0)
+        self.search_hbox.pack_end(searchEntry, True, True, 0)
         # Filtering model for the search box.
         # Use this instead of using self.storemodel directly
         self.modelFilter = self.storemodel.filter_new()
@@ -335,7 +337,7 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
 
         # TreeView
         # Displays icon, name, type, length
-        self.treeview = gtk.TreeView(self.modelFilter)
+        self.treeview = Gtk.TreeView(self.modelFilter)
         self.treeview_scrollwin.add(self.treeview)
         self.treeview.connect("button-press-event", self._treeViewButtonPressEventCb)
         self.treeview.connect("button-release-event", self._treeViewButtonReleaseEventCb)
@@ -346,39 +348,39 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
         self.treeview.set_headers_visible(False)
         self.treeview.set_property("search_column", COL_SEARCH_TEXT)
         tsel = self.treeview.get_selection()
-        tsel.set_mode(gtk.SELECTION_MULTIPLE)
+        tsel.set_mode(Gtk.SelectionMode.MULTIPLE)
         tsel.connect("changed", self._viewSelectionChangedCb)
 
-        pixbufcol = gtk.TreeViewColumn(_("Icon"))
+        pixbufcol = Gtk.TreeViewColumn(_("Icon"))
         pixbufcol.set_expand(False)
         pixbufcol.set_spacing(SPACING)
         self.treeview.append_column(pixbufcol)
-        pixcell = gtk.CellRendererPixbuf()
+        pixcell = Gtk.CellRendererPixbuf()
         pixcell.props.xpad = 6
-        pixbufcol.pack_start(pixcell)
+        pixbufcol.pack_start(pixcell, True)
         pixbufcol.add_attribute(pixcell, 'pixbuf', COL_ICON)
 
-        namecol = gtk.TreeViewColumn(_("Information"))
+        namecol = Gtk.TreeViewColumn(_("Information"))
         self.treeview.append_column(namecol)
         namecol.set_expand(True)
         namecol.set_spacing(SPACING)
-        namecol.set_sizing(gtk.TREE_VIEW_COLUMN_GROW_ONLY)
+        namecol.set_sizing(Gtk.TreeViewColumnSizing.GROW_ONLY)
         namecol.set_min_width(150)
-        txtcell = gtk.CellRendererText()
-        txtcell.set_property("ellipsize", pango.ELLIPSIZE_END)
-        namecol.pack_start(txtcell)
+        txtcell = Gtk.CellRendererText()
+        txtcell.set_property("ellipsize", Pango.EllipsizeMode.END)
+        namecol.pack_start(txtcell, True)
         namecol.add_attribute(txtcell, "markup", COL_INFOTEXT)
 
-        namecol = gtk.TreeViewColumn(_("Duration"))
+        namecol = Gtk.TreeViewColumn(_("Duration"))
         namecol.set_expand(False)
         self.treeview.append_column(namecol)
-        txtcell = gtk.CellRendererText()
+        txtcell = Gtk.CellRendererText()
         txtcell.set_property("yalign", 0.0)
-        namecol.pack_start(txtcell)
+        namecol.pack_start(txtcell, True)
         namecol.add_attribute(txtcell, "markup", COL_LENGTH)
 
         # IconView
-        self.iconview = gtk.IconView(self.modelFilter)
+        self.iconview = Gtk.IconView(self.modelFilter)
         self.iconview_scrollwin.add(self.iconview)
         self.iconview.connect("button-press-event", self._iconViewButtonPressEventCb)
         self.iconview.connect("button-release-event", self._iconViewButtonReleaseEventCb)
@@ -386,18 +388,18 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
         self.iconview.connect("focus-out-event", self._enableKeyboardShortcutsCb)
         self.iconview.connect("item-activated", self._itemOrRowActivatedCb)
         self.iconview.connect("selection-changed", self._viewSelectionChangedCb)
-        self.iconview.set_orientation(gtk.ORIENTATION_VERTICAL)
+        self.iconview.set_item_orientation(Gtk.Orientation.VERTICAL)
         self.iconview.set_property("has_tooltip", True)
         self.iconview.set_tooltip_column(COL_INFOTEXT)
         self.iconview.props.item_padding = 3
         self.iconview.props.margin = 3
 
-        cell = gtk.CellRendererPixbuf()
+        cell = Gtk.CellRendererPixbuf()
         self.iconview.pack_start(cell, False)
         self.iconview.add_attribute(cell, "pixbuf", COL_ICON_LARGE)
 
-        cell = gtk.CellRendererText()
-        cell.props.alignment = pango.ALIGN_CENTER
+        cell = Gtk.CellRendererText()
+        cell.props.alignment = Pango.Alignment.CENTER
         cell.props.xalign = 0.5
         cell.props.yalign = 0.0
         cell.props.xpad = 0
@@ -407,16 +409,16 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
         self.iconview.pack_start(cell, False)
         self.iconview.add_attribute(cell, "text", COL_SHORT_TEXT)
 
-        self.iconview.set_selection_mode(gtk.SELECTION_MULTIPLE)
+        self.iconview.set_selection_mode(Gtk.SelectionMode.MULTIPLE)
 
         # Explanatory message InfoBar
-        self.infobar = gtk.InfoBar()
+        self.infobar = Gtk.InfoBar()
 
-        txtlabel = gtk.Label()
+        txtlabel = Gtk.Label()
         txtlabel.set_padding(PADDING, PADDING)
         txtlabel.set_line_wrap(True)
-        txtlabel.set_line_wrap_mode(pango.WRAP_WORD)
-        txtlabel.set_justify(gtk.JUSTIFY_CENTER)
+        txtlabel.set_line_wrap_mode(Pango.WrapMode.WORD)
+        txtlabel.set_justify(Gtk.Justification.CENTER)
         txtlabel.set_text(
             _('Add media to your project by dragging files and folders here or '
               'by using the "Import Files..." button.'))
@@ -424,16 +426,16 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
         self.txtlabel = txtlabel
 
         # The infobar that shows up if there are _errors when importing clips
-        self._import_warning_infobar = gtk.InfoBar()
-        self._import_warning_infobar.set_message_type(gtk.MESSAGE_WARNING)
+        self._import_warning_infobar = Gtk.InfoBar()
+        self._import_warning_infobar.set_message_type(Gtk.MessageType.WARNING)
         content_area = self._import_warning_infobar.get_content_area()
         actions_area = self._import_warning_infobar.get_action_area()
-        self._warning_label = gtk.Label()
+        self._warning_label = Gtk.Label()
         self._warning_label.set_line_wrap(True)
-        self._warning_label.set_line_wrap_mode(pango.WRAP_WORD)
-        self._warning_label.set_justify(gtk.JUSTIFY_CENTER)
-        self._view_error_btn = gtk.Button()
-        self._hide_infobar_btn = gtk.Button()
+        self._warning_label.set_line_wrap_mode(Pango.WrapMode.WORD)
+        self._warning_label.set_justify(Gtk.Justification.CENTER)
+        self._view_error_btn = Gtk.Button()
+        self._hide_infobar_btn = Gtk.Button()
         self._hide_infobar_btn.set_label(_("Hide"))
         self._view_error_btn.connect("clicked", self._viewErrorsButtonClickedCb)
         self._hide_infobar_btn.connect("clicked", self._hideInfoBarClickedCb)
@@ -442,7 +444,7 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
         actions_area.add(self._hide_infobar_btn)
 
         # The _progressbar that shows up when importing clips
-        self._progressbar = gtk.ProgressBar()
+        self._progressbar = Gtk.ProgressBar()
         self._progressbar.set_show_text(True)
 
         # Connect to project.  We must remove and reset the callbacks when
@@ -457,13 +459,13 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
         self.videofilepixbuf = self._getIcon("video-x-generic")
 
         # Drag and Drop
-        self.drag_dest_set(gtk.DEST_DEFAULT_DROP | gtk.DEST_DEFAULT_MOTION,
+        self.drag_dest_set(Gtk.DestDefaults.DROP | Gtk.DestDefaults.MOTION,
                            [dnd.URI_TARGET_ENTRY, dnd.FILE_TARGET_ENTRY],
-                           gtk.gdk.ACTION_COPY)
+                           Gdk.DragAction.COPY)
         self.drag_dest_add_uri_targets()
         self.connect("drag_data_received", self._dndDataReceivedCb)
 
-        self.treeview.drag_source_set(0, [], gtk.gdk.ACTION_COPY)
+        self.treeview.drag_source_set(0, [], Gdk.DragAction.COPY)
         self.treeview.enable_model_drag_source(Gdk.ModifierType.BUTTON1_MASK, [("pitivi/file-source", 0, TYPE_PITIVI_FILESOURCE)], Gdk.DragAction.COPY)
         self.treeview.drag_source_set_target_list(None)
         self.treeview.drag_source_add_uri_targets()
@@ -472,8 +474,8 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
         self.treeview.connect("drag_begin", self._dndDragBeginCb)
         self.treeview.connect("drag-end", self._dndDragEndCb)
 
-        self.iconview.drag_source_set(0, [], gtk.gdk.ACTION_COPY)
-        self.iconview.enable_model_drag_source(Gdk.ModifierType.BUTTON1_MASK, [gtk.TargetEntry.new("pitivi/file-source", 0, TYPE_PITIVI_FILESOURCE)], Gdk.DragAction.COPY)
+        self.iconview.drag_source_set(0, [], Gdk.DragAction.COPY)
+        self.iconview.enable_model_drag_source(Gdk.ModifierType.BUTTON1_MASK, [Gtk.TargetEntry.new("pitivi/file-source", 0, TYPE_PITIVI_FILESOURCE)], Gdk.DragAction.COPY)
         self.iconview.drag_source_set_target_list(None)
         self.iconview.drag_source_add_uri_targets()
         self.iconview.drag_source_add_text_targets()
@@ -486,11 +488,11 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
 
         # always available
         actions = (
-            ("ImportSources", gtk.STOCK_ADD, _("_Import Files..."),
+            ("ImportSources", Gtk.STOCK_ADD, _("_Import Files..."),
             None, _("Add media files to your project"),
             self._importSourcesCb),
 
-            ("ImportSourcesFolder", gtk.STOCK_ADD, _("Import _Folders..."),
+            ("ImportSourcesFolder", Gtk.STOCK_ADD, _("Import _Folders..."),
             None, _("Add the contents of a folder as clips in your project"),
             self._importSourcesFolderCb),
 
@@ -502,25 +504,25 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
 
         # only available when selection is non-empty
         selection_actions = (
-            ("RemoveSources", gtk.STOCK_DELETE, _("_Remove from Project"),
+            ("RemoveSources", Gtk.STOCK_DELETE, _("_Remove from Project"),
             "<Control>Delete", None, self._removeSourcesCb),
 
-            ("InsertEnd", gtk.STOCK_COPY, _("Insert at _End of Timeline"),
+            ("InsertEnd", Gtk.STOCK_COPY, _("Insert at _End of Timeline"),
             "Insert", None, self._insertEndCb),
 
-            ("PreviewClip", gtk.STOCK_MEDIA_PLAY, _("_Preview Clip"),
+            ("PreviewClip", Gtk.STOCK_MEDIA_PLAY, _("_Preview Clip"),
             None, None, self._previewClickedCb),
 
             ("ClipProps", None, _("_Clip Properties..."),
             None, None, self._clipPropertiesCb),
         )
 
-        actiongroup = gtk.ActionGroup("medialibrarypermanent")
+        actiongroup = Gtk.ActionGroup("medialibrarypermanent")
         actiongroup.add_actions(actions)
         actiongroup.get_action("ImportSources").props.is_important = True
         uiman.insert_action_group(actiongroup, 0)
 
-        self.selection_actions = gtk.ActionGroup("medialibraryselection")
+        self.selection_actions = Gtk.ActionGroup("medialibraryselection")
         self.selection_actions.add_actions(selection_actions)
         self.selection_actions.set_sensitive(False)
         uiman.insert_action_group(self.selection_actions, 0)
@@ -529,9 +531,9 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
         # clip view menu items
         view_menu_item = uiman.get_widget('/MainMenuBar/View')
         view_menu = view_menu_item.get_submenu()
-        seperator = gtk.SeparatorMenuItem()
-        self.treeview_menuitem = gtk.RadioMenuItem(label=_("Show Clips as a List"))
-        self.iconview_menuitem = gtk.RadioMenuItem.new_with_label(group=[self.treeview_menuitem],
+        seperator = Gtk.SeparatorMenuItem()
+        self.treeview_menuitem = Gtk.RadioMenuItem(label=_("Show Clips as a List"))
+        self.iconview_menuitem = Gtk.RadioMenuItem.new_with_label(group=[self.treeview_menuitem],
                 label=_("Show Clips as Icons"))
 
         # update menu items with current clip view before we connect to item
@@ -555,12 +557,12 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
         seperator.show()
 
         # add all child widgets
-        self.pack_start(self.infobar, expand=False, fill=False)
-        self.pack_start(self._import_warning_infobar, expand=False, fill=False)
-        self.pack_start(self.search_hbox, expand=False)
-        self.pack_start(self.iconview_scrollwin)
-        self.pack_start(self.treeview_scrollwin)
-        self.pack_start(self._progressbar, expand=False)
+        self.pack_start(self.infobar, False, False, 0)
+        self.pack_start(self._import_warning_infobar, False, False, 0)
+        self.pack_start(self.search_hbox, False, True, 0)
+        self.pack_start(self.iconview_scrollwin, True, True, 0)
+        self.pack_start(self.treeview_scrollwin, True, True, 0)
+        self.pack_start(self._progressbar, False, True, 0)
 
         # display the help text
         self.clip_view = self.settings.lastClipView
@@ -581,7 +583,7 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
     def _insertEndCb(self, unused_action):
         sources = []
         for uri in self.getSelectedItems():
-            sources.append(ges.TimelineFileSource(uri=uri))
+            sources.append(GES.TimelineFileSource(uri=uri))
 
         self.app.gui.timeline_ui.insertEnd(sources)
 
@@ -638,16 +640,16 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
             return text in model.get_value(iter, COL_INFOTEXT).lower()
 
     def _getIcon(self, iconname, alternate=None):
-        icontheme = gtk.icon_theme_get_default()
+        icontheme = Gtk.IconTheme.get_default()
         pixdir = get_pixmap_dir()
         icon = None
         try:
             icon = icontheme.load_icon(iconname, 48, 0)
         except:
-            # empty except clause is bad but load_icon raises gio.Error.
+            # empty except clause is bad but load_icon raises Gio.Error.
             # Right, *gio*.
             if alternate:
-                icon = gtk.gdk.pixbuf_new_from_file(os.path.join(pixdir, alternate))
+                icon = GdkPixbuf.Pixbuf.new_from_file(os.path.join(pixdir, alternate))
             else:
                 icon = icontheme.load_icon("dialog-question", 48, 0)
         return icon
@@ -712,7 +714,7 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
 
     def _displayHelpText(self):
         """Display the InfoBar help message"""
-        self.infobar.hide_all()
+        self.infobar.hide()
         self.txtlabel.show()
         self.infobar.show()
 
@@ -722,22 +724,22 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
             return
 
         if select_folders:
-            chooser_action = gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER
+            chooser_action = Gtk.FileChooserAction.SELECT_FOLDER
             dialogtitle = _("Select One or More Folders")
         else:
-            chooser_action = gtk.FILE_CHOOSER_ACTION_OPEN
+            chooser_action = Gtk.FileChooserAction.OPEN
             dialogtitle = _("Select One or More Files")
 
-        close_after = gtk.CheckButton(_("Close after importing files"))
+        close_after = Gtk.CheckButton(_("Close after importing files"))
         close_after.set_active(self.app.settings.closeImportDialog)
 
-        self._importDialog = gtk.FileChooserDialog(dialogtitle, None,
+        self._importDialog = Gtk.FileChooserDialog(dialogtitle, None,
                                            chooser_action,
-                                           (gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE,
-                                            gtk.STOCK_ADD, gtk.RESPONSE_OK))
+                                           (Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE,
+                                            Gtk.STOCK_ADD, Gtk.ResponseType.OK))
         self._importDialog.set_icon_name("pitivi")
         self._importDialog.props.extra_widget = close_after
-        self._importDialog.set_default_response(gtk.RESPONSE_OK)
+        self._importDialog.set_default_response(Gtk.ResponseType.OK)
         self._importDialog.set_select_multiple(True)
         self._importDialog.set_modal(False)
         self._importDialog.set_current_folder(self.app.settings.lastImportFolder)
@@ -783,11 +785,11 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
             # However, the fdo spec specifies 128 as normal and 256 as large.
             # We will thus simply use the "normal" size and scale it down.
             try:
-                thumbnail = gtk.gdk.pixbuf_new_from_file(thumb_path_normal)
+                thumbnail = GdkPixbuf.Pixbuf.new_from_file(thumb_path_normal)
                 thumbnail_large = thumbnail
                 thumbnail_height = int(thumbnail.get_height() / 2)
                 thumbnail = thumbnail.scale_simple(64, thumbnail_height, \
-                    gtk.gdk.INTERP_BILINEAR)
+                    GdkPixbuf.InterpType.BILINEAR)
             except:
                 # TODO gst discoverer should create missing thumbnails.
                 thumbnail = self.videofilepixbuf
@@ -796,7 +798,7 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
             thumbnail = self.audiofilepixbuf
             thumbnail_large = self.audiofilepixbuf
 
-        if info.get_duration() == gst.CLOCK_TIME_NONE:
+        if info.get_duration() == Gst.CLOCK_TIME_NONE:
             duration = ''
         else:
             duration = beautify_length(info.get_duration())
@@ -855,7 +857,7 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
 
     def _sourcesStartedImportingCb(self, unused_medialibrary):
         self.import_start_time = time.time()
-        self.infobar.hide_all()
+        self.infobar.hide()
         self.search_hbox.show_all()
         self._progressbar.show()
 
@@ -895,7 +897,7 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
 
     def _dialogBoxResponseCb(self, dialogbox, response, select_folders):
         self.debug("response:%r", response)
-        if response == gtk.RESPONSE_OK:
+        if response == Gtk.ResponseType.OK:
             lastfolder = dialogbox.get_current_folder()
             self.app.settings.lastImportFolder = lastfolder
             self.app.settings.closeImportDialog = \
@@ -928,7 +930,7 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
         # use row references so we don't have to care if a path has been removed
         rows = []
         for path in paths:
-            row = gtk.TreeRowReference.new(model, path)
+            row = Gtk.TreeRowReference.new(model, path)
             rows.append(row)
 
         self.app.action_log.begin("remove clip from source list")
@@ -1041,7 +1043,7 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
     _ignoreRelease = False
 
     def _rowUnderMouseSelected(self, view, event):
-        if isinstance(view, gtk.TreeView):
+        if isinstance(view, Gtk.TreeView):
             path = None
             tup = view.get_path_at_pos(int(event.x), int(event.y))
             if tup:
@@ -1049,7 +1051,7 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
             if path:
                 selection = view.get_selection()
                 return selection.path_is_selected(path) and selection.count_selected_rows() > 0
-        elif isinstance(view, gtk.IconView):
+        elif isinstance(view, Gtk.IconView):
             path = view.get_path_at_pos(int(event.x), int(event.y))
             if path:
                 selection = view.get_selected_items()
@@ -1081,13 +1083,13 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
                 self.popup_playmenuitem.set_sensitive(True)
                 self.popup_clipprop.set_sensitive(True)
         elif view != None and (not self._nothingUnderMouse(view, event)):
-            if not event.state & (gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK):
+            if not event.get_state() & (Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.SHIFT_MASK):
                 # An item was previously selected, and the user
                 # right-clicked on a different item (selecting it).
                 self._viewUnselectAll()
                 multiple_selected = False
             elif self.clip_view == SHOW_TREEVIEW and self._viewHasSelection() \
-                    and (event.state & gtk.gdk.SHIFT_MASK):
+                    and (event.get_state() & Gdk.ModifierType.SHIFT_MASK):
                 # FIXME: when does this section ever get called?
                 selection = self.treeview.get_selection()
                 start_path = self._viewGetFirstSelected()
@@ -1140,7 +1142,7 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
     def _treeViewButtonPressEventCb(self, treeview, event):
         chain_up = True
 
-        if event.type == gtk.gdk._2BUTTON_PRESS:
+        if event.type == Gdk._2BUTTON_PRESS:
             if self.getSelectedPaths() != []:
                 # It is possible to double-click outside of clips!
                 self._previewClickedCb()
@@ -1149,7 +1151,7 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
             self._viewShowPopup(treeview, event)
             chain_up = False
 
-        elif not event.state & (gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK):
+        elif not event.get_state() & (Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.SHIFT_MASK):
             chain_up = not self._rowUnderMouseSelected(treeview, event)
 
         self.clickedPath = self.getSelectedPaths()
@@ -1159,7 +1161,7 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
         else:
             self._draggedPaths = None
 
-        gtk.TreeView.do_button_press_event(treeview, event)
+        Gtk.TreeView.do_button_press_event(treeview, event)
 
         ts = self.treeview.get_selection()
 
@@ -1171,7 +1173,7 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
 
     def _treeViewButtonReleaseEventCb(self, treeview, event):
         ts = self.treeview.get_selection()
-        state = event.state & (gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK)
+        state = event.get_state() & (Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.SHIFT_MASK)
         path = self.treeview.get_path_at_pos(event.x, event.y)
 
         if not state and not self.dragged:
@@ -1196,7 +1198,7 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
     def _iconViewButtonPressEventCb(self, iconview, event):
         chain_up = True
 
-        if event.type == gtk.gdk._2BUTTON_PRESS:
+        if event.type == Gdk._2BUTTON_PRESS:
             if self.getSelectedPaths() != []:
                 # It is possible to double-click outside of clips!
                 self._previewClickedCb()
@@ -1204,7 +1206,7 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
         elif event.button == 3:
             self._viewShowPopup(iconview, event)
             chain_up = False
-        elif not event.state & (gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK):
+        elif not event.get_state() & (Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.SHIFT_MASK):
             chain_up = not self._rowUnderMouseSelected(iconview, event)
 
         if not chain_up:
@@ -1212,7 +1214,7 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
         else:
             self._draggedPaths = None
 
-        gtk.IconView.do_button_press_event(iconview, event)
+        Gtk.IconView.do_button_press_event(iconview, event)
 
         if self._draggedPaths:
             for path in self._draggedPaths:
@@ -1223,7 +1225,7 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
         return True
 
     def _iconViewButtonReleaseEventCb(self, iconview, event):
-        state = event.state & (gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK)
+        state = event.get_state() & (Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.SHIFT_MASK)
         path = self.iconview.get_path_at_pos(event.x, event.y)
 
         if not state and not self.dragged:
@@ -1290,7 +1292,7 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
             context.drag_abort(int(time.time()))
         else:
             row = self.modelFilter[paths[0]]
-            gtk.drag_set_icon_pixbuf(context, row[COL_ICON], 0, 0)
+            Gtk.drag_set_icon_pixbuf(context, row[COL_ICON], 0, 0)
 
     def _dndDragEndCb(self, view, context):
         self.dragged = False
@@ -1319,4 +1321,4 @@ class MediaLibraryWidget(gtk.VBox, Loggable):
         return [self.modelFilter[path][COL_URI]
             for path in self.getSelectedPaths()]
 
-gobject.type_register(MediaLibraryWidget)
+GObject.type_register(MediaLibraryWidget)
diff --git a/pitivi/preset.py b/pitivi/preset.py
index 0fb8673..c843fc4 100644
--- a/pitivi/preset.py
+++ b/pitivi/preset.py
@@ -21,8 +21,8 @@
 
 import os.path
 
-import gst
-import gtk
+from gi.repository import Gst
+from gi.repository import Gtk
 import json
 
 from gettext import gettext as _
@@ -52,7 +52,7 @@ class PresetManager(object):
         be selected before it can be changed.
     @type cur_preset: str
     @ivar ordered: A list holding (name -> preset_dict) tuples.
-    @type ordered: gtk.ListStore
+    @type ordered: Gtk.ListStore
     @ivar presets: A (name -> preset_dict) map.
     @type presets: dict
     @ivar widget_map: A (propname -> (setter_func, getter_func)) map.
@@ -63,7 +63,7 @@ class PresetManager(object):
     def __init__(self):
         self.presets = {}
         self.widget_map = {}
-        self.ordered = gtk.ListStore(str, object)
+        self.ordered = Gtk.ListStore(str, object)
         self.cur_preset = None
         # Whether to ignore the updateValue calls.
         self._ignore_update_requests = False
@@ -320,11 +320,11 @@ class VideoPresetManager(PresetManager):
 
         framerate_num = parser["framerate-num"]
         framerate_denom = parser["framerate-denom"]
-        framerate = gst.Fraction(framerate_num, framerate_denom)
+        framerate = Gst.Fraction(framerate_num, framerate_denom)
 
         par_num = parser["par-num"]
         par_denom = parser["par-denom"]
-        par = gst.Fraction(par_num, par_denom)
+        par = Gst.Fraction(par_num, par_denom)
 
         self.addPreset(name, {
             "width": width,
@@ -408,7 +408,7 @@ class RenderPresetManager(PresetManager):
 
         framerate_num = parser["framerate-num"]
         framerate_denom = parser["framerate-denom"]
-        framerate = gst.Fraction(framerate_num, framerate_denom)
+        framerate = Gst.Fraction(framerate_num, framerate_denom)
 
         channels = parser["channels"]
         depth = parser["depth"]
diff --git a/pitivi/project.py b/pitivi/project.py
index cfbf3c6..fe4fd0e 100644
--- a/pitivi/project.py
+++ b/pitivi/project.py
@@ -24,10 +24,10 @@ Project related classes
 """
 
 import os
-import ges
-import gst
-import gtk
-import gobject
+from gi.repository import GES
+from gi.repository import Gst
+from gi.repository import Gtk
+from gi.repository import GObject
 import tarfile
 
 from time import time
@@ -56,11 +56,11 @@ from pitivi.preset import AudioPresetManager, DuplicatePresetNameException,\
 
 
 #------------------ Backend classes ------------------------------------------#
-class Timeline(ges.Timeline):
+class Timeline(GES.Timeline):
     def __init__(self):
-        ges.Timeline.__init__(self)
-        self.add_track(ges.Track.video_raw_new())
-        self.add_track(ges.Track.audio_raw_new())
+        GES.Timeline.__init__(self)
+        self.add_track(GES.Track.video_raw_new())
+        self.add_track(GES.Track.audio_raw_new())
         self.selection = Selection()
 
 
@@ -165,7 +165,7 @@ class ProjectManager(Signallable, Loggable):
         self.emit("new-project-created", self.current)
 
         timeline = self.current.timeline
-        self.formatter = ges.PitiviFormatter()
+        self.formatter = GES.PitiviFormatter()
         self.formatter.connect("source-moved", self._formatterMissingURICb)
         self.formatter.connect("loaded", self._projectLoadedCb)
         if self.formatter.load_from_uri(timeline, uri):
@@ -180,14 +180,14 @@ class ProjectManager(Signallable, Loggable):
 
         @param time_diff: the difference, in seconds, between file mtimes
         """
-        dialog = gtk.Dialog("", None, 0,
-                    (_("Ignore backup"), gtk.RESPONSE_REJECT,
-                    _("Restore from backup"), gtk.RESPONSE_YES))
+        dialog = Gtk.Dialog("", None, 0,
+                    (_("Ignore backup"), Gtk.ResponseType.REJECT,
+                    _("Restore from backup"), Gtk.ResponseType.YES))
         dialog.set_icon_name("pitivi")
         dialog.set_resizable(False)
-        dialog.set_default_response(gtk.RESPONSE_YES)
+        dialog.set_default_response(Gtk.ResponseType.YES)
 
-        primary = gtk.Label()
+        primary = Gtk.Label()
         primary.set_line_wrap(True)
         primary.set_use_markup(True)
         primary.set_alignment(0, 0.5)
@@ -199,26 +199,26 @@ class ProjectManager(Signallable, Loggable):
         primary.props.label = message
 
         # put the text in a vbox
-        vbox = gtk.VBox(False, SPACING * 2)
-        vbox.pack_start(primary, expand=True, fill=True)
+        vbox = Gtk.VBox(False, SPACING * 2)
+        vbox.pack_start(primary, True, True, 0)
 
         # make the [[image] text] hbox
-        image = gtk.image_new_from_stock(gtk.STOCK_DIALOG_QUESTION,
-               gtk.ICON_SIZE_DIALOG)
-        hbox = gtk.HBox(False, SPACING * 2)
-        hbox.pack_start(image, expand=False)
-        hbox.pack_start(vbox, expand=True, fill=True)
+        image = Gtk.Image.new_from_stock(Gtk.STOCK_DIALOG_QUESTION,
+               Gtk.IconSize.DIALOG)
+        hbox = Gtk.HBox(False, SPACING * 2)
+        hbox.pack_start(image, False, True, 0)
+        hbox.pack_start(vbox, True, True, 0)
         hbox.set_border_width(SPACING)
 
         # stuff the hbox in the dialog
         content_area = dialog.get_content_area()
-        content_area.pack_start(hbox, expand=True, fill=True)
+        content_area.pack_start(hbox, True, True, 0)
         content_area.set_spacing(SPACING * 2)
         hbox.show_all()
 
         response = dialog.run()
         dialog.destroy()
-        if response == gtk.RESPONSE_YES:
+        if response == Gtk.ResponseType.YES:
             return True
         else:
             return False
@@ -244,7 +244,7 @@ class ProjectManager(Signallable, Loggable):
         @see: L{Formatter.saveProject}
         """
         if formatter is None:
-            formatter = ges.PitiviFormatter()
+            formatter = GES.PitiviFormatter()
         if backup:
             if project.uri and self.current.uri is not None:
                 # Ignore whatever URI that is passed on to us. It's a trap.
@@ -418,7 +418,7 @@ class ProjectManager(Signallable, Loggable):
 
         if self.backup_lock == 0:
             self.backup_lock = 10
-            gobject.timeout_add_seconds(self.backup_lock, self._saveBackupCb, project, uri)
+            GObject.timeout_add_seconds(self.backup_lock, self._saveBackupCb, project, uri)
         else:
             if self.backup_lock < 60:
                 self.backup_lock += 5
@@ -488,7 +488,7 @@ class Project(Signallable, Loggable):
     @ivar medialibrary: The sources used by this project
     @type medialibrary: L{MediaLibrary}
     @ivar timeline: The timeline
-    @type timeline: L{ges.Timeline}
+    @type timeline: L{GES.Timeline}
     @ivar pipeline: The timeline's pipeline
     @type pipeline: L{Pipeline}
     @ivar format: The format under which the project is currently stored.
@@ -537,9 +537,9 @@ class Project(Signallable, Loggable):
 
     def setUri(self, uri):
         # FIXME support not local project
-        if uri and not gst.uri_has_protocol(uri, "file"):
+        if uri and not Gst.uri_has_protocol(uri, "file"):
             # Note that this does *not* give the same result as quote_uri()
-            self._uri = gst.uri_construct("file", uri)
+            self._uri = Gst.uri_construct("file", uri)
         else:
             self._uri = uri
 
@@ -589,7 +589,7 @@ class ProjectSettingsDialog():
         self.project = project
         self.settings = project.getSettings()
 
-        self.builder = gtk.Builder()
+        self.builder = Gtk.Builder()
         self.builder.add_from_file(os.path.join(get_ui_dir(), "projectsettings.ui"))
         self._setProperties()
         self.builder.connect_signals(self)
@@ -597,19 +597,19 @@ class ProjectSettingsDialog():
         # add custom display aspect ratio widget
         self.dar_fraction_widget = FractionWidget()
         self.video_properties_table.attach(self.dar_fraction_widget,
-            0, 1, 6, 7, xoptions=gtk.EXPAND | gtk.FILL, yoptions=0)
+            0, 1, 6, 7, xoptions=Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, yoptions=0)
         self.dar_fraction_widget.show()
 
         # add custom pixel aspect ratio widget
         self.par_fraction_widget = FractionWidget()
         self.video_properties_table.attach(self.par_fraction_widget,
-            1, 2, 6, 7, xoptions=gtk.EXPAND | gtk.FILL, yoptions=0)
+            1, 2, 6, 7, xoptions=Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, yoptions=0)
         self.par_fraction_widget.show()
 
         # add custom framerate widget
         self.frame_rate_fraction_widget = FractionWidget()
         self.video_properties_table.attach(self.frame_rate_fraction_widget,
-            1, 2, 2, 3, xoptions=gtk.EXPAND | gtk.FILL, yoptions=0)
+            1, 2, 2, 3, xoptions=Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, yoptions=0)
         self.frame_rate_fraction_widget.show()
 
         # populate coboboxes with appropriate data
@@ -772,9 +772,9 @@ class ProjectSettingsDialog():
         removing and saving a preset, enabling or disabling them accordingly.
         @type update_buttons_func: function
         """
-        renderer = gtk.CellRendererText()
+        renderer = Gtk.CellRendererText()
         renderer.props.editable = True
-        column = gtk.TreeViewColumn("Preset", renderer, text=0)
+        column = Gtk.TreeViewColumn("Preset", renderer, text=0)
         treeview.append_column(column)
         treeview.props.headers_visible = False
         model = mgr.getModel()
@@ -794,9 +794,9 @@ class ProjectSettingsDialog():
 
     def createVideoNoPreset(self, mgr):
         mgr.prependPreset(_("No preset"), {
-            "par": gst.Fraction(int(get_combo_value(self.par_combo).num),
+            "par": Gst.Fraction(int(get_combo_value(self.par_combo).num),
                                     int(get_combo_value(self.par_combo).denom)),
-            "frame-rate": gst.Fraction(int(get_combo_value(self.frame_rate_combo).num),
+            "frame-rate": Gst.Fraction(int(get_combo_value(self.frame_rate_combo).num),
                             int(get_combo_value(self.frame_rate_combo).denom)),
             "height": int(self.height_spinbutton.get_value()),
             "width": int(self.width_spinbutton.get_value())})
@@ -867,7 +867,7 @@ class ProjectSettingsDialog():
     def getSAR(self):
         width = int(self.width_spinbutton.get_value())
         height = int(self.height_spinbutton.get_value())
-        return gst.Fraction(width, height)
+        return Gst.Fraction(width, height)
 
     def _setProperties(self):
         getObj = self.builder.get_object
@@ -1063,7 +1063,7 @@ class ProjectSettingsDialog():
         self.project.setSettings(self.settings)
 
     def _responseCb(self, unused_widget, response):
-        if response == gtk.RESPONSE_OK:
+        if response == Gtk.ResponseType.OK:
             self.updateSettings()
             self.updateMetadata()
         self.window.destroy()
diff --git a/pitivi/render.py b/pitivi/render.py
index ab9305e..f6b8093 100644
--- a/pitivi/render.py
+++ b/pitivi/render.py
@@ -25,15 +25,15 @@ Rendering-related utilities and classes
 """
 
 import os
-import gtk
-import gst
-import ges
+from gi.repository import Gtk
+from gi.repository import Gst
+from gi.repository import GES
 import time
 
 import pitivi.utils.loggable as log
 
 from gettext import gettext as _
-from gst.pbutils import EncodingContainerProfile, EncodingVideoProfile, \
+from gi.repository.GstPbutils import EncodingContainerProfile, EncodingVideoProfile, \
     EncodingAudioProfile
 
 from pitivi import configure
@@ -52,13 +52,13 @@ def get_compatible_sink_pad(factoryname, caps):
     Returns the pad name of a (request) pad from factoryname which is
     compatible with the given caps.
     """
-    factory = gst.registry_get_default().lookup_feature(factoryname)
+    factory = Gst.Registry.get().lookup_feature(factoryname)
     if factory == None:
         log.warning("render", "%s is not a valid factoryname", factoryname)
         return None
 
     res = []
-    sinkpads = [x for x in factory.get_static_pad_templates() if x.direction == gst.PAD_SINK]
+    sinkpads = [x for x in factory.get_static_pad_templates() if x.direction == Gst.PadDirection.SINK]
     for p in sinkpads:
         c = p.get_caps()
         log.log("render", "sinkcaps %s", c.to_string())
@@ -77,13 +77,13 @@ def get_compatible_sink_caps(factoryname, caps):
     Returns the compatible caps between 'caps' and the sink pad caps of 'factoryname'
     """
     log.log("render", "factoryname : %s , caps : %s", factoryname, caps.to_string())
-    factory = gst.registry_get_default().lookup_feature(factoryname)
+    factory = Gst.Registry.get().lookup_feature(factoryname)
     if factory == None:
         log.warning("render", "%s is not a valid factoryname", factoryname)
         return None
 
     res = []
-    sinkcaps = [x.get_caps() for x in factory.get_static_pad_templates() if x.direction == gst.PAD_SINK]
+    sinkcaps = [x.get_caps() for x in factory.get_static_pad_templates() if x.direction == Gst.PadDirection.SINK]
     for c in sinkcaps:
         log.log("render", "sinkcaps %s", c.to_string())
         inter = caps.intersect(c)
@@ -115,12 +115,12 @@ def my_can_sink_caps(muxer, ocaps, muxsinkcaps=[]):
         return False
     # slower default
     for x in muxer.get_static_pad_templates():
-        if x.direction == gst.PAD_SINK:
+        if x.direction == Gst.PadDirection.SINK:
             if not x.get_caps().intersect(ocaps).is_empty():
                 return True
     return False
 
-    # sinkcaps = (x.get_caps() for x in muxer.get_static_pad_templates() if x.direction == gst.PAD_SINK)
+    # sinkcaps = (x.get_caps() for x in muxer.get_static_pad_templates() if x.direction == Gst.PadDirection.SINK)
     # for x in sinkcaps:
     #     if not x.intersect(ocaps).is_empty():
     #         return True
@@ -130,7 +130,7 @@ def my_can_sink_caps(muxer, ocaps, muxsinkcaps=[]):
 class CachedEncoderList(object):
     def __init__(self):
         self._factories = None
-        self._registry = gst.registry_get_default()
+        self._registry = Gst.Registry.get()
         self._registry.connect("feature-added", self._registryFeatureAddedCb)
 
     def _ensure_factories(self):
@@ -138,7 +138,7 @@ class CachedEncoderList(object):
             self._buildFactories()
 
     def _buildFactories(self):
-        self._factories = self._registry.get_feature_list(gst.ElementFactory)
+        self._factories = self._registry.get_feature_list(Gst.ElementFactory)
         self._audioEncoders = []
         self._videoEncoders = []
         self._muxers = []
@@ -201,18 +201,18 @@ def encoders_muxer_compatible(encoders, muxer, muxsinkcaps=[]):
     """ returns the list of encoders compatible with the given muxer """
     res = []
     if muxsinkcaps == []:
-        muxsinkcaps = [x.get_caps() for x in muxer.get_static_pad_templates() if x.direction == gst.PAD_SINK]
+        muxsinkcaps = [x.get_caps() for x in muxer.get_static_pad_templates() if x.direction == Gst.PadDirection.SINK]
     for encoder in encoders:
         for tpl in encoder.get_static_pad_templates():
-            if tpl.direction == gst.PAD_SRC:
+            if tpl.direction == Gst.PadDirection.SRC:
                 if my_can_sink_caps(muxer, tpl.get_caps(), muxsinkcaps):
                     res.append(encoder)
                     break
     return res
 
 
-raw_audio_caps = gst.caps_from_string("audio/x-raw")
-raw_video_caps = gst.caps_from_string("video/x-raw")
+raw_audio_caps = Gst.caps_from_string("audio/x-raw")
+raw_video_caps = Gst.caps_from_string("video/x-raw")
 
 
 def muxer_can_sink_raw_audio(muxer):
@@ -255,7 +255,7 @@ def available_combinations():
 
 def beautify_factoryname(factory):
     """
-    Returns a nice name for the specified gst.ElementFactory instance.
+    Returns a nice name for the specified Gst.ElementFactory instance.
     This is intended to remove redundant words and shorten the codec names.
     """
     # only replace lowercase versions of "format", "video", "audio"
@@ -307,10 +307,10 @@ def extension_for_muxer(muxer):
 
 
 def factorylist(factories):
-    """Create a gtk.ListStore() of sorted, beautified factory names.
+    """Create a Gtk.ListStore() of sorted, beautified factory names.
 
     @param factories: The factories available for creating the list.
-    @type factories: A sequence of gst.ElementFactory instances.
+    @type factories: A sequence of Gst.ElementFactory instances.
     """
     columns = (str, object)
     data = [(beautify_factoryname(factory), factory)
@@ -329,7 +329,7 @@ class RenderingProgressDialog(Signallable):
 
     def __init__(self, app, parent):
         self.app = app
-        self.builder = gtk.Builder()
+        self.builder = Gtk.Builder()
         self.builder.add_from_file(os.path.join(configure.get_ui_dir(),
             "renderingprogress.ui"))
         self.builder.connect_signals(self)
@@ -340,7 +340,7 @@ class RenderingProgressDialog(Signallable):
         self.play_pause_button = self.builder.get_object("play_pause_button")
         # Parent the dialog with mainwindow, since renderingdialog is hidden.
         # It allows this dialog to properly minimize together with mainwindow
-        self.window.set_transient_for(self.app.gui)
+        self.set_transient_for(self.app.gui)
 
         # UI widgets
         self.window.set_icon_from_file(configure.get_pixmap_dir() + "/pitivi-render-16.png")
@@ -403,7 +403,7 @@ class RenderDialog(Loggable):
         # {object: sigId}
         self._gstSigId = {}
 
-        self.builder = gtk.Builder()
+        self.builder = Gtk.Builder()
         self.builder.add_from_file(os.path.join(configure.get_ui_dir(),
             "renderingdialog.ui"))
         self._setProperties()
@@ -491,7 +491,7 @@ class RenderDialog(Loggable):
             "acodec": get_combo_value(self.audio_encoder_combo).get_name(),
             "vcodec": get_combo_value(self.video_encoder_combo).get_name(),
             "container": get_combo_value(self.muxercombobox).get_name(),
-            "frame-rate": gst.Fraction(int(get_combo_value(self.frame_rate_combo).num),
+            "frame-rate": Gst.Fraction(int(get_combo_value(self.frame_rate_combo).num),
                                         int(get_combo_value(self.frame_rate_combo).denom)),
             "height": self.getDimension("height"),
             "width": self.getDimension("width")})
@@ -533,7 +533,7 @@ class RenderDialog(Loggable):
                 lambda: get_combo_value(widget))
 
     def muxer_setter(self, widget, value):
-        set_combo_value(widget, gst.ElementFactory.find(value))
+        set_combo_value(widget, Gst.ElementFactory.find(value))
         self.settings.setEncoders(muxer=value)
 
         # Update the extension of the filename.
@@ -548,14 +548,14 @@ class RenderDialog(Loggable):
             self.muxer_combo_changing = False
 
     def acodec_setter(self, widget, value):
-        set_combo_value(widget, gst.ElementFactory.find(value))
+        set_combo_value(widget, Gst.ElementFactory.find(value))
         self.settings.setEncoders(aencoder=value)
         if not self.muxer_combo_changing:
             # The user directly changed the audio encoder combo.
             self.preferred_aencoder = value
 
     def vcodec_setter(self, widget, value):
-        set_combo_value(widget, gst.ElementFactory.find(value))
+        set_combo_value(widget, Gst.ElementFactory.find(value))
         self.settings.setEncoders(vencoder=value)
         if not self.muxer_combo_changing:
             # The user directly changed the video encoder combo.
@@ -605,9 +605,9 @@ class RenderDialog(Loggable):
         removing and saving a preset, enabling or disabling them accordingly.
         @type update_buttons_func: function
         """
-        renderer = gtk.CellRendererText()
+        renderer = Gtk.CellRendererText()
         renderer.props.editable = True
-        column = gtk.TreeViewColumn("Preset", renderer, text=0)
+        column = Gtk.TreeViewColumn("Preset", renderer, text=0)
         treeview.append_column(column)
         treeview.props.headers_visible = False
         model = mgr.getModel()
@@ -690,7 +690,7 @@ class RenderDialog(Loggable):
             "acodec": get_combo_value(self.audio_encoder_combo).get_name(),
             "vcodec": get_combo_value(self.video_encoder_combo).get_name(),
             "container": get_combo_value(self.muxercombobox).get_name(),
-            "frame-rate": gst.Fraction(int(get_combo_value(self.frame_rate_combo).num),
+            "frame-rate": Gst.Fraction(int(get_combo_value(self.frame_rate_combo).num),
                                         int(get_combo_value(self.frame_rate_combo).denom)),
             "height": 0,
             "width": 0})
@@ -783,7 +783,7 @@ class RenderDialog(Loggable):
         # Muxer settings
         # note: this will trigger an update of the codec comboboxes
         set_combo_value(self.muxercombobox,
-            gst.ElementFactory.find(self.settings.muxer))
+            Gst.ElementFactory.find(self.settings.muxer))
 
     def _checkForExistingFile(self, *args):
         """
@@ -793,7 +793,7 @@ class RenderDialog(Loggable):
         if not path:
             # This happens when the window is initialized.
             return
-        warning_icon = gtk.STOCK_DIALOG_WARNING
+        warning_icon = Gtk.STOCK_DIALOG_WARNING
         filename = self.fileentry.get_text()
         if not filename:
             tooltip_text = _("A file name is required.")
@@ -836,7 +836,7 @@ class RenderDialog(Loggable):
         if preferred_encoder:
             # A preference exists, pick it if it can be found in
             # the current model of the combobox.
-            vencoder = gst.ElementFactory.find(preferred_encoder)
+            vencoder = Gst.ElementFactory.find(preferred_encoder)
             set_combo_value(encoder_combo, vencoder, default_index=0)
         else:
             # No preference exists, pick the first encoder from
@@ -847,24 +847,24 @@ class RenderDialog(Loggable):
         """Open a dialog to edit the properties for the specified factory.
 
         @param factory: An element factory whose properties the user will edit.
-        @type factory: gst.ElementFactory
+        @type factory: Gst.ElementFactory
         @param settings_attr: The MultimediaSettings attribute holding
         the properties.
         @type settings_attr: str
         """
         properties = getattr(self.settings, settings_attr)
         self.dialog = GstElementSettingsDialog(factory, properties=properties)
-        self.dialog.window.set_transient_for(self.window)
+        self.dialog.set_transient_for(self.window)
         self.dialog.ok_btn.connect("clicked", self._okButtonClickedCb, settings_attr)
         self.dialog.window.run()
 
     def startAction(self):
         """ Start the render process """
-        self._pipeline.set_state(gst.STATE_NULL)
-        self._pipeline.set_mode(ges.TIMELINE_MODE_SMART_RENDER)
+        self._pipeline.set_state(Gst.State.NULL)
+        self._pipeline.set_mode(GES.TimelineMode.SMART_RENDER)
         encodebin = self._pipeline.get_by_name("internal-encodebin")
         self._gstSigId[encodebin] = encodebin.connect("element-added", self._elementAddedCb)
-        self._pipeline.set_state(gst.STATE_PLAYING)
+        self._pipeline.set_state(Gst.State.PLAYING)
 
     def _cancelRender(self, progress):
         self.debug("aborting render")
@@ -874,9 +874,9 @@ class RenderDialog(Loggable):
     def _shutDown(self):
         """ The render process has been aborted, shutdown the gstreamer pipeline
         and disconnect from its signals """
-        self._pipeline.set_state(gst.STATE_NULL)
+        self._pipeline.set_state(Gst.State.NULL)
         self._disconnectFromGst()
-        self._pipeline.set_mode(ges.TIMELINE_MODE_PREVIEW)
+        self._pipeline.set_mode(GES.TimelineMode.PREVIEW)
 
     def _pauseRender(self, progress):
         self.app.current.pipeline.togglePlayback()
@@ -940,16 +940,16 @@ class RenderDialog(Loggable):
 
         # FIXME GES: Handle presets here!
         self.containerprofile = EncodingContainerProfile.new(None, None,
-                                    gst.caps_from_string(self.muxertype), None)
+                                    Gst.caps_from_string(self.muxertype), None)
 
         if self.video_output_checkbutton.get_active():
             self.videoprofile = EncodingVideoProfile.new(
-                                    gst.caps_from_string(self.videotype), None,
+                                    Gst.caps_from_string(self.videotype), None,
                                     self.settings.getVideoCaps(True), 0)
             self.containerprofile.add_profile(self.videoprofile)
         if self.audio_output_checkbutton.get_active():
             self.audioprofile = EncodingAudioProfile.new(
-                                    gst.caps_from_string(self.audiotype), None,
+                                    Gst.caps_from_string(self.audiotype), None,
                                     self.settings.getAudioCaps(), 0)
             self.containerprofile.add_profile(self.audioprofile)
 
@@ -973,16 +973,16 @@ class RenderDialog(Loggable):
 
     #-- GStreamer callbacks
     def _busMessageCb(self, unused_bus, message):
-        if message.type == gst.MESSAGE_EOS:  # Render complete
+        if message.type == Gst.MESSAGE_EOS:  # Render complete
             self.debug("got EOS message, render complete")
             self._shutDown()
             self._destroyProgressWindow()
-        elif message.type == gst.MESSAGE_STATE_CHANGED and self.progress:
+        elif message.type == Gst.MessageType.CHANGED and self.progress:
             prev, state, pending = message.parse_state_changed()
             if message.src == self._pipeline:
-                state_really_changed = pending == gst.STATE_VOID_PENDING
+                state_really_changed = pending == Gst.State.VOID_PENDING
                 if state_really_changed:
-                    if state == gst.STATE_PLAYING:
+                    if state == Gst.State.PLAYING:
                         self.debug("Rendering started/resumed, resetting ETA calculation and inhibiting sleep")
                         self.timestarted = time.time()
                         self.system.inhibitSleep(RenderDialog.INHIBIT_REASON)
@@ -999,12 +999,12 @@ class RenderDialog(Loggable):
                 # only display ETA after 5s in order to have enough averaging and
                 # if the position is non-null
                 totaltime = (timediff * float(length) / float(position)) - timediff
-                text = beautify_ETA(int(totaltime * gst.SECOND))
+                text = beautify_ETA(int(totaltime * Gst.SECOND))
             self.progress.updatePosition(fraction, text)
 
     def _elementAddedCb(self, bin, element):
-        # Setting properties on gst.Element-s has they are added to the
-        # gst.Encodebin
+        # Setting properties on Gst.Element-s has they are added to the
+        # Gst.Encodebin
         if element.get_factory() == get_combo_value(self.video_encoder_combo):
             for setting in self.settings.vcodecsettings:
                 element.set_property(setting, self.settings.vcodecsettings[setting])
@@ -1079,7 +1079,7 @@ class RenderDialog(Loggable):
 
     def _videoEncoderComboChangedCb(self, combo):
         vencoder = get_combo_value(combo).get_name()
-        for template in gst.registry_get_default().lookup_feature(vencoder).get_static_pad_templates():
+        for template in Gst.Registry.get().lookup_feature(vencoder).get_static_pad_templates():
             if template.name_template == "src":
                 self.videotype = template.get_caps().to_string()
                 for elem in self.videotype.split(","):
@@ -1107,7 +1107,7 @@ class RenderDialog(Loggable):
     def _audioEncoderChangedComboCb(self, combo):
         aencoder = get_combo_value(combo).get_name()
         self.settings.setEncoders(aencoder=aencoder)
-        for template in gst.registry_get_default().lookup_feature(aencoder).get_static_pad_templates():
+        for template in Gst.Registry.get().lookup_feature(aencoder).get_static_pad_templates():
             if template.name_template == "src":
                 self.audiotype = template.get_caps().to_string()
                 for elem in self.audiotype.split(","):
@@ -1125,7 +1125,7 @@ class RenderDialog(Loggable):
     def _muxerComboChangedCb(self, muxer_combo):
         """Handle the changing of the container format combobox."""
         muxer = get_combo_value(muxer_combo).get_name()
-        for template in gst.registry_get_default().lookup_feature(muxer).get_static_pad_templates():
+        for template in Gst.Registry.get().lookup_feature(muxer).get_static_pad_templates():
             if template.name_template == "src":
                 self.muxertype = template.get_caps().to_string()
         self.settings.setEncoders(muxer=muxer)
diff --git a/pitivi/settings.py b/pitivi/settings.py
index 81d2e55..f6196f2 100644
--- a/pitivi/settings.py
+++ b/pitivi/settings.py
@@ -20,7 +20,7 @@
 # Boston, MA 02110-1301, USA.
 
 import os
-import gst
+from gi.repository import Gst
 from ConfigParser import SafeConfigParser, ParsingError
 import xdg.BaseDirectory as xdg_dirs  # Freedesktop directories spec
 
@@ -330,8 +330,8 @@ class MultimediaSettings(Signallable, Loggable):
         self.videowidth = 720
         self.videoheight = 576
         self.render_scale = 100
-        self.videorate = gst.Fraction(25, 1)
-        self.videopar = gst.Fraction(16, 15)
+        self.videorate = Gst.Fraction(25, 1)
+        self.videopar = Gst.Fraction(16, 15)
         self.audiochannels = 2
         self.audiorate = 44100
         self.audiodepth = 16
@@ -350,8 +350,8 @@ class MultimediaSettings(Signallable, Loggable):
         ret.videowidth = self.videowidth
         ret.videoheight = self.videoheight
         ret.render_scale = self.render_scale
-        ret.videorate = gst.Fraction(self.videorate.num, self.videorate.denom)
-        ret.videopar = gst.Fraction(self.videopar.num, self.videopar.denom)
+        ret.videorate = Gst.Fraction(self.videorate.num, self.videorate.denom)
+        ret.videopar = Gst.Fraction(self.videopar.num, self.videopar.denom)
         ret.audiochannels = self.audiochannels
         ret.audiorate = self.audiorate
         ret.audiodepth = self.audiodepth
@@ -364,7 +364,7 @@ class MultimediaSettings(Signallable, Loggable):
         return ret
 
     def getDAR(self):
-        return gst.Fraction(self.videowidth, self.videoheight) * self.videopar
+        return Gst.Fraction(self.videowidth, self.videoheight) * self.videopar
 
     def __str__(self):
         """
@@ -408,7 +408,7 @@ class MultimediaSettings(Signallable, Loggable):
                 self.videopar.num, self.videopar.denom,
                 self.videorate.num, self.videorate.denom)
         caps_str = "video/x-raw,%s" % (vstr)
-        video_caps = gst.caps_from_string(caps_str)
+        video_caps = Gst.caps_from_string(caps_str)
         if self.vencoder:
             return get_compatible_sink_caps(self.vencoder, video_caps)
         return video_caps
@@ -418,7 +418,7 @@ class MultimediaSettings(Signallable, Loggable):
         # TODO: Figure out why including 'depth' causes pipeline failures:
         astr = "rate=%d,channels=%d" % (self.audiorate, self.audiochannels)
         caps_str = "audio/x-raw,%s" % (astr)
-        audio_caps = gst.caps_from_string(caps_str)
+        audio_caps = Gst.caps_from_string(caps_str)
         if self.aencoder:
             return get_compatible_sink_caps(self.aencoder, audio_caps)
         return audio_caps
diff --git a/pitivi/tabsmanager.py b/pitivi/tabsmanager.py
index 5a7d5a5..84657b8 100644
--- a/pitivi/tabsmanager.py
+++ b/pitivi/tabsmanager.py
@@ -19,13 +19,13 @@
 # Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 # Boston, MA 02110-1301, USA.
 
-import gtk
+from gi.repository import Gtk
 from pitivi.utils.ui import SPACING
 
 
-class BaseTabs(gtk.Notebook):
+class BaseTabs(Gtk.Notebook):
     def __init__(self, app):
-        gtk.Notebook.__init__(self)
+        Gtk.Notebook.__init__(self)
         self.set_border_width(SPACING)
         self.set_scrollable(True)
         self.connect("create-window", self._createWindowCb)
@@ -35,10 +35,10 @@ class BaseTabs(gtk.Notebook):
     def _createUi(self):
         settings = self.get_settings()
         settings.props.gtk_dnd_drag_threshold = 1
-        self.set_tab_pos(gtk.POS_TOP)
+        self.set_tab_pos(Gtk.PositionType.TOP)
 
     def append_page(self, child, label):
-        gtk.Notebook.append_page(self, child, label)
+        Gtk.Notebook.append_page(self, child, label)
         self._set_child_properties(child, label)
         child.show()
         label.show()
@@ -60,13 +60,13 @@ class BaseTabs(gtk.Notebook):
         # unused_notebook here is the same as "self"
         original_position = self.page_num(page)
         label = self.get_tab_label(page)
-        window = gtk.Window()
-        window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_UTILITY)
+        window = Gtk.Window()
+        window.set_type_hint(Gdk.WindowTypeHint.UTILITY)
         window.set_title(label.get_text())
         window.set_default_size(600, 400)
         window.connect("destroy", self._detachedWindowDestroyCb,
                         page, original_position, label)
-        notebook = gtk.Notebook()
+        notebook = Gtk.Notebook()
         notebook.props.show_tabs = False
         window.add(notebook)
         window.show_all()
diff --git a/pitivi/timeline/curve.py b/pitivi/timeline/curve.py
index 201a426..0043395 100644
--- a/pitivi/timeline/curve.py
+++ b/pitivi/timeline/curve.py
@@ -22,9 +22,9 @@
 """
 Custom canvas item for track object keyframe curves."""
 
-import goocanvas
-import gobject
-import gtk
+from gi.repository import GooCanvas
+from gi.repository import GObject
+from gi.repository import Gtk
 
 from pitivi.utils.receiver import receiver, handler
 from pitivi.utils.timeline import View, Controller, Zoomable
@@ -33,7 +33,7 @@ from pitivi.utils.misc import between
 
 
 def intersect(b1, b2):
-    return goocanvas.Bounds(max(b1.x1, b2.x1), max(b1.y1, b2.y1),
+    return GooCanvas.CanvasBounds(max(b1.x1, b2.x1), max(b1.y1, b2.y1),
         min(b1.x2, b2.x2), min(b1.y2, b2.y2))
 
 KW_WIDTH = 10
@@ -51,10 +51,10 @@ KW_LABEL_VPAD = 4
 KW_LABEL_HPAD2 = KW_LABEL_VPAD / 2
 KW_LABEL_VPAD2 = KW_LABEL_VPAD / 2
 CURVE_STROKE_WIDTH = 2.0
-HAND = gtk.gdk.Cursor(gtk.gdk.HAND2)
+HAND = Gdk.Cursor.new(Gdk.HAND2)
 
 
-class Curve(goocanvas.ItemSimple, goocanvas.Item, View, Zoomable):
+class Curve(GooCanvas.CanvasItemSimple, GooCanvas.CanvasItem, View, Zoomable):
 
     __gtype_name__ = 'Curve'
 
@@ -139,7 +139,8 @@ class Curve(goocanvas.ItemSimple, goocanvas.Item, View, Zoomable):
         self.keyframes = {}
         self.height = float(height)
         self.element = element
-        self.props.pointer_events = goocanvas.EVENTS_STROKE
+        # FIXME PyGI port
+        #self.props.pointer_events = GooCanvas.EVENTS_STROKE
         self.interpolator = interpolator
         self._focused_kf = None
         self.normal()
@@ -156,7 +157,7 @@ class Curve(goocanvas.ItemSimple, goocanvas.Item, View, Zoomable):
         self._max = value - (CURVE_STROKE_WIDTH / 2)
         self._range = self._max - self._min
         self.changed(True)
-    height = gobject.property(_get_height, _set_height, type=float)
+    height = GObject.property(_get_height, _set_height, type=float)
 
 ## element callbacks
 
@@ -192,13 +193,13 @@ class Curve(goocanvas.ItemSimple, goocanvas.Item, View, Zoomable):
     def zoomChanged(self):
         self.changed(True)
 
-## goocanvas item methods
+## GooCanvas item methods
 
     def do_simple_update(self, cr):
         cr.identity_matrix()
         if self.element.factory:
             self.visible_width = self.nsToPixel(self.element.duration)
-            self.bounds = goocanvas.Bounds(0, 0,
+            self.bounds = GooCanvas.CanvasBounds(0, 0,
                 self.visible_width + KW_LABEL_X_OVERFLOW,
                 self.height + KW_LABEL_Y_OVERFLOW)
 
@@ -221,7 +222,7 @@ class Curve(goocanvas.ItemSimple, goocanvas.Item, View, Zoomable):
             cr.save()
             # set clipping region to the visible portion of the clip
             vis_bounds = intersect(
-                goocanvas.Bounds(
+                GooCanvas.CanvasBounds(
                     self.bounds.x1, self.bounds.y1 + KW_LABEL_Y_OVERFLOW,
                     self.bounds.x2 - KW_LABEL_X_OVERFLOW, self.bounds.y2), bounds)
             vis_width = vis_bounds.x2 - vis_bounds.x1
diff --git a/pitivi/timeline/layer.py b/pitivi/timeline/layer.py
index 646f49c..c7fcecf 100644
--- a/pitivi/timeline/layer.py
+++ b/pitivi/timeline/layer.py
@@ -22,7 +22,7 @@
 
 from gi.repository import Gtk
 from gi.repository import Gdk
-import ges
+from gi.repository import GES
 from gi.repository import GObject
 
 from gettext import gettext as _
@@ -68,8 +68,8 @@ class BaseLayerControl(Gtk.VBox, Loggable):
         self.sep = SpacedSeparator()
         self.pack_start(self.sep, True, True, 0)
 
-        icon_mapping = {ges.TRACK_TYPE_AUDIO: "audio-x-generic",
-                        ges.TRACK_TYPE_VIDEO: "video-x-generic"}
+        icon_mapping = {GES.TrackType.AUDIO: "audio-x-generic",
+                        GES.TrackType.VIDEO: "video-x-generic"}
 
         # Folding button
         # TODO use images
@@ -111,9 +111,9 @@ class BaseLayerControl(Gtk.VBox, Loggable):
 
         # Upper bar
         upper = Gtk.HBox()
-        upper.pack_start(self.name_entry, True, True)
-        upper.pack_start(self.solo_button, False, False)
-        upper.pack_start(visible_option, False, False)
+        upper.pack_start(self.name_entry, True, True, 0)
+        upper.pack_start(self.solo_button, False, False, 0)
+        upper.pack_start(visible_option, False, False, 0)
 
         # Lower bar
         self.lower_hbox = Gtk.HBox()
@@ -293,19 +293,19 @@ class VideoLayerControl(BaseLayerControl):
     __gtype_name__ = 'VideoLayerControl'
 
     def __init__(self, app, layer):
-        BaseLayerControl.__init__(self, app, layer, ges.TRACK_TYPE_VIDEO)
+        BaseLayerControl.__init__(self, app, layer, GES.TrackType.VIDEO)
 
         opacity = Gtk.Label(label=_("Opacity:"))
 
         # Opacity scale
         opacity_adjust = Gtk.Adjustment(value=100, upper=100, step_incr=5, page_incr=10)
-        opacity_scale = Gtk.HScale(opacity_adjust)
+        opacity_scale = Gtk.HScale(adjustment=opacity_adjust)
         opacity_scale.set_value_pos(Gtk.PositionType.LEFT)
         opacity_scale.set_digits(0)
         opacity_scale.set_tooltip_text(_("Change video opacity"))
 
-        self.lower_hbox.pack_start(opacity, False, False)
-        self.lower_hbox.pack_start(opacity_scale, True, True)
+        self.lower_hbox.pack_start(opacity, False, False, 0)
+        self.lower_hbox.pack_start(opacity_scale, True, True, 0)
         self.lower_hbox.show_all()
 
 
@@ -317,7 +317,7 @@ class AudioLayerControl(BaseLayerControl):
     __gtype_name__ = 'AudioLayerControl'
 
     def __init__(self, app, layer):
-        BaseLayerControl.__init__(self, app, layer, ges.TRACK_TYPE_AUDIO)
+        BaseLayerControl.__init__(self, app, layer, GES.TrackType.AUDIO)
 
         volume = Gtk.Label(label=_("Vol:"))
         volume_button = Gtk.VolumeButton(size=Gtk.IconSize.MENU)
@@ -325,15 +325,15 @@ class AudioLayerControl(BaseLayerControl):
         panning = Gtk.Label(label=_("Pan:"))
         # Volume scale
         panning_adjust = Gtk.Adjustment(value=0, lower=-100, upper=100, step_incr=5, page_incr=10)
-        panning_scale = Gtk.HScale(panning_adjust)
+        panning_scale = Gtk.HScale(adjustment=panning_adjust)
         panning_scale.set_value_pos(Gtk.PositionType.LEFT)
         panning_scale.set_digits(0)
         panning_scale.set_tooltip_text(_("Change audio panning"))
 
-        self.lower_hbox.pack_start(volume, False, False)
-        self.lower_hbox.pack_start(volume_button, False, False)
-        self.lower_hbox.pack_start(panning, False, False)
-        self.lower_hbox.pack_start(panning_scale, True, True)
+        self.lower_hbox.pack_start(volume, False, False, 0)
+        self.lower_hbox.pack_start(volume_button, False, False, 0)
+        self.lower_hbox.pack_start(panning, False, False, 0)
+        self.lower_hbox.pack_start(panning_scale, True, True, 0)
         self.lower_hbox.show_all()
 
 
diff --git a/pitivi/timeline/ruler.py b/pitivi/timeline/ruler.py
index 8c8115a..5d1f1ae 100644
--- a/pitivi/timeline/ruler.py
+++ b/pitivi/timeline/ruler.py
@@ -22,12 +22,13 @@
 """
 Widget for the complex view ruler
 """
-
-import gobject
-import gtk
-import gst
 import cairo
 
+from gi.repository import Gtk
+from gi.repository import Gdk
+from gi.repository import Gst
+from gi.repository import GObject
+
 from gettext import gettext as _
 
 from pitivi.utils.pipeline import Seeker
@@ -40,15 +41,15 @@ def setCairoColor(cr, color):
     cr.set_source_rgb(float(color.red), float(color.green), float(color.blue))
 
 
-class ScaleRuler(gtk.DrawingArea, Zoomable, Loggable):
+class ScaleRuler(Gtk.DrawingArea, Zoomable, Loggable):
 
     __gsignals__ = {
         "button-press-event": "override",
         "button-release-event": "override",
         "motion-notify-event": "override",
         "scroll-event": "override",
-        "seek": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
-                [gobject.TYPE_UINT64])
+        "seek": (GObject.SignalFlags.RUN_LAST, None,
+                [GObject.TYPE_UINT64])
         }
 
     border = 0
@@ -57,7 +58,7 @@ class ScaleRuler(gtk.DrawingArea, Zoomable, Loggable):
     subdivide = ((1, 1.0), (2, 0.5), (10, .25))
 
     def __init__(self, instance, hadj):
-        gtk.DrawingArea.__init__(self)
+        GObject.GObject.__init__(self)
         Zoomable.__init__(self)
         Loggable.__init__(self)
         self.log("Creating new ScaleRuler")
@@ -65,9 +66,9 @@ class ScaleRuler(gtk.DrawingArea, Zoomable, Loggable):
         self._seeker = Seeker()
         self.hadj = hadj
         hadj.connect("value-changed", self._hadjValueChangedCb)
-        self.add_events(gtk.gdk.POINTER_MOTION_MASK |
-            gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK |
-            gtk.gdk.SCROLL_MASK)
+        self.add_events(Gdk.EventMask.POINTER_MOTION_MASK |
+            Gdk.EventMask.BUTTON_PRESS_MASK | Gdk.EventMask.BUTTON_RELEASE_MASK |
+            Gdk.EventMask.SCROLL_MASK)
 
         self.pixbuf = None
 
@@ -82,8 +83,8 @@ class ScaleRuler(gtk.DrawingArea, Zoomable, Loggable):
         self.need_update = True
         self.min_frame_spacing = 5.0
         self.frame_height = 5.0
-        self.frame_rate = gst.Fraction(1 / 1)
-        self.ns_per_frame = float(1 / self.frame_rate) * gst.SECOND
+        self.frame_rate = Gst.Fraction(1 / 1)
+        self.ns_per_frame = float(1 / self.frame_rate) * Gst.SECOND
         self.connect('draw', self.drawCb)
         self.connect('configure-event', self.configureEventCb)
 
@@ -103,7 +104,7 @@ class ScaleRuler(gtk.DrawingArea, Zoomable, Loggable):
         self.position = value
         self.queue_draw()
 
-## gtk.Widget overrides
+## Gtk.Widget overrides
     def configureEventCb(self, widget, event, data=None):
         self.debug("Configuring, height %d, width %d",
             widget.get_allocated_width(), widget.get_allocated_height())
@@ -168,21 +169,21 @@ class ScaleRuler(gtk.DrawingArea, Zoomable, Loggable):
         return False
 
     def do_scroll_event(self, event):
-        if event.scroll.state & gtk.gdk.CONTROL_MASK:
+        if event.scroll.state & Gdk.ModifierType.CONTROL_MASK:
             # Control + scroll = zoom
-            if event.scroll.direction == gtk.gdk.SCROLL_UP:
+            if event.scroll.direction == Gdk.ScrollDirection.UP:
                 Zoomable.zoomIn()
                 self.app.gui.timeline_ui.zoomed_fitted = False
-            elif event.scroll.direction == gtk.gdk.SCROLL_DOWN:
+            elif event.scroll.direction == Gdk.ScrollDirection.DOWN:
                 Zoomable.zoomOut()
                 self.app.gui.timeline_ui.zoomed_fitted = False
         else:
             # No modifier key held down, just scroll
-            if event.scroll.direction == gtk.gdk.SCROLL_UP or\
-                event.scroll.direction == gtk.gdk.SCROLL_LEFT:
+            if event.scroll.direction == Gdk.ScrollDirection.UP or\
+                event.scroll.direction == Gdk.ScrollDirection.LEFT:
                 self.app.gui.timeline_ui.scroll_left()
-            elif event.scroll.direction == gtk.gdk.SCROLL_DOWN or\
-                event.scroll.direction == gtk.gdk.SCROLL_RIGHT:
+            elif event.scroll.direction == Gdk.ScrollDirection.DOWN or\
+                event.scroll.direction == Gdk.ScrollDirection.RIGHT:
                 self.app.gui.timeline_ui.scroll_right()
 
     def setProjectFrameRate(self, rate):
@@ -190,7 +191,7 @@ class ScaleRuler(gtk.DrawingArea, Zoomable, Loggable):
         Set the lowest scale based on project framerate
         """
         self.frame_rate = rate
-        self.ns_per_frame = float(1 / self.frame_rate) * gst.SECOND
+        self.ns_per_frame = float(1 / self.frame_rate) * Gst.SECOND
         self.scale[0] = float(2 / rate)
         self.scale[1] = float(5 / rate)
         self.scale[2] = float(10 / rate)
@@ -199,12 +200,12 @@ class ScaleRuler(gtk.DrawingArea, Zoomable, Loggable):
 
     def drawBackground(self, cr):
         style = self.get_style_context()
-        setCairoColor(cr, style.get_background_color(gtk.StateFlags.NORMAL))
+        setCairoColor(cr, style.get_background_color(Gtk.StateFlags.NORMAL))
         cr.rectangle(0, 0, cr.get_target().get_width(), cr.get_target().get_height())
         cr.fill()
-        offset = int(self.nsToPixel(gst.CLOCK_TIME_NONE)) - self.pixbuf_offset
+        offset = int(self.nsToPixel(Gst.CLOCK_TIME_NONE)) - self.pixbuf_offset
         if offset > 0:
-            setCairoColor(cr, style.get_background_color(gtk.StateFlags.ACTIVE))
+            setCairoColor(cr, style.get_background_color(Gtk.StateFlags.ACTIVE))
             cr.rectangle(0, 0, int(offset), cr.get_target().get_height())
             cr.fill()
 
@@ -229,7 +230,7 @@ class ScaleRuler(gtk.DrawingArea, Zoomable, Loggable):
         paintpos = int(paintpos - 0.5) + 0.5
         height = int(cr.get_target().get_height() * (1 - height))
         style = self.get_style_context()
-        setCairoColor(cr, style.get_color(gtk.STATE_NORMAL))
+        setCairoColor(cr, style.get_color(Gtk.StateType.NORMAL))
         cr.set_line_width(1)
         cr.move_to(paintpos, height)
         cr.line_to(paintpos, cr.get_target().get_height())
@@ -249,7 +250,7 @@ class ScaleRuler(gtk.DrawingArea, Zoomable, Loggable):
 
     def drawTimes(self, cr, offset, spacing, scale):
         # figure out what the optimal offset is
-        interval = long(gst.SECOND * scale)
+        interval = long(Gst.SECOND * scale)
         seconds = self.pixelToNs(self.pixbuf_offset)
         paintpos = float(self.border) + 2
         if offset > 0:
@@ -257,10 +258,10 @@ class ScaleRuler(gtk.DrawingArea, Zoomable, Loggable):
             paintpos += spacing - offset
 
         while paintpos < cr.get_target().get_width():
-            if paintpos < self.nsToPixel(gst.CLOCK_TIME_NONE):
-                state = gtk.STATE_ACTIVE
+            if paintpos < self.nsToPixel(Gst.CLOCK_TIME_NONE):
+                state = Gtk.StateType.ACTIVE
             else:
-                state = gtk.STATE_NORMAL
+                state = Gtk.StateType.NORMAL
             timevalue = time_to_string(long(seconds))
             style = self.get_style_context()
             setCairoColor(cr, style.get_color(state))
@@ -286,14 +287,14 @@ class ScaleRuler(gtk.DrawingArea, Zoomable, Loggable):
         # INSENSITIVE is a dark shade of gray, but lacks contrast
         # SELECTED will be bright blue and more visible to represent frames
         style = self.get_style_context()
-        states = [style.get_background_color(gtk.StateFlags.ACTIVE),
-                  style.get_background_color(gtk.StateFlags.SELECTED)]
+        states = [style.get_background_color(Gtk.StateFlags.ACTIVE),
+                  style.get_background_color(Gtk.StateFlags.SELECTED)]
 
-        frame_num = int(self.pixelToNs(self.pixbuf_offset) * float(self.frame_rate) / gst.SECOND)
+        frame_num = int(self.pixelToNs(self.pixbuf_offset) * float(self.frame_rate) / Gst.SECOND)
         paintpos = self.pixbuf_offset - offset
         max_pos = cr.get_target().get_width() + self.pixbuf_offset
         while paintpos < max_pos:
-            paintpos = self.nsToPixel(1 / float(self.frame_rate) * gst.SECOND * frame_num)
+            paintpos = self.nsToPixel(1 / float(self.frame_rate) * Gst.SECOND * frame_num)
             setCairoColor(cr, states[(frame_num + 1) % 2])
             cr.rectangle(0.5 + paintpos - self.pixbuf_offset, y, frame_width, height)
             cr.fill()
diff --git a/pitivi/timeline/thumbnailer.py b/pitivi/timeline/thumbnailer.py
index 739bf16..d040132 100644
--- a/pitivi/timeline/thumbnailer.py
+++ b/pitivi/timeline/thumbnailer.py
@@ -22,13 +22,15 @@
 """
 Handle the creation, caching and display of thumbnails in the timeline.
 """
-
-import ges
-import gst
 import os
 import cairo
-import gobject
-import goocanvas
+
+from gi.repository import GES
+from gi.repository import Gst
+from gi.repository import GstBase
+from gi.repository import GooCanvas
+from gi.repository import GObject
+
 import collections
 import array
 import sqlite3
@@ -59,7 +61,7 @@ GlobalSettings.addConfigOption("thumbnailSpacingHint",
 GlobalSettings.addConfigOption("thumbnailPeriod",
     section="thumbnailing",
     key="thumbnail-period",
-    default=gst.SECOND,
+    default=Gst.SECOND,
     notify=True)
 
 PreferencesDialog.addNumericPreference("thumbnailSpacingHint",
@@ -76,14 +78,14 @@ PreferencesDialog.addChoicePreference("thumbnailPeriod",
         # are not supported by ngettext and their plurality is ambiguous
         # in many languages.
         # See http://www.gnu.org/software/hello/manual/gettext/Plural-forms.html
-        (_("1/100 second"), gst.SECOND / 100),
-        (_("1/10 second"), gst.SECOND / 10),
-        (_("1/4 second"), gst.SECOND / 4),
-        (_("1/2 second"), gst.SECOND / 2),
-        (_("1 second"), gst.SECOND),
-        (_("5 seconds"), 5 * gst.SECOND),
-        (_("10 seconds"), 10 * gst.SECOND),
-        (_("minute"), 60 * gst.SECOND)),
+        (_("1/100 second"), Gst.SECOND / 100),
+        (_("1/10 second"), Gst.SECOND / 10),
+        (_("1/4 second"), Gst.SECOND / 4),
+        (_("1/2 second"), Gst.SECOND / 2),
+        (_("1 second"), Gst.SECOND),
+        (_("5 seconds"), 5 * Gst.SECOND),
+        (_("10 seconds"), 10 * Gst.SECOND),
+        (_("minute"), 60 * Gst.SECOND)),
     description=_("The interval, in seconds, between thumbnails."))
 
 # this default works out to a maximum of ~ 1.78 MiB per factory, assuming:
@@ -134,7 +136,7 @@ class ThumbnailCache(object):
 
     def __init__(self, uri, size=100):
         object.__init__(self)
-        self.hash = utils.misc.hash_file(gst.uri_get_location(uri))
+        self.hash = utils.misc.hash_file(Gst.uri_get_location(uri))
         self.cache = {}
         self.queue = collections.deque()
         dbfile = os.path.join(settings.get_dir(os.path.join(settings.xdg_cache_home(), "thumbs")), self.hash)
@@ -211,11 +213,11 @@ def get_preview_for_object(instance, trackobject):
         # TODO: handle non-source factories
         # Note that we switch on the track_type, but we hash on the uri
         # itself.
-        if track_type == ges.TRACK_TYPE_AUDIO:
+        if track_type == GES.TrackType.AUDIO:
             # FIXME: RandomAccessAudioPreviewer doesn't work yet
             # previewers[key] = RandomAccessAudioPreviewer(instance, uri)
             previewers[key] = DefaultPreviewer(instance, uri)
-        elif track_type == ges.TRACK_TYPE_VIDEO:
+        elif track_type == GES.TrackType.VIDEO:
             if trackobject.get_timeline_object().is_image():
                 previewers[key] = StillImagePreviewer(instance, uri)
             else:
@@ -282,7 +284,7 @@ class RandomAccessPreviewer(Previewer):
         Previewer.__init__(self, instance, uri)
         self._queue = []
 
-        bin = gst.element_factory_make("playbin")
+        bin = Gst.ElementFactory.make("playbin", None)
         bin.props.uri = uri
 
         # assume 50 pixel height
@@ -451,17 +453,17 @@ class RandomAccessVideoPreviewer(RandomAccessPreviewer):
         self.tstep = Zoomable.pixelToNsAt(self.twidth, Zoomable.max_zoom)
 
         if self.framerate.num:
-            frame_duration = (gst.SECOND * self.framerate.denom) / self.framerate.num
+            frame_duration = (Gst.SECOND * self.framerate.denom) / self.framerate.num
             self.tstep = max(frame_duration, self.tstep)
 
     def bus_handler(self, unused_bus, message):
         # set the scaling method of the videoscale element to Lanczos
         element = message.src
-        if isinstance(element, gst.Element):
+        if isinstance(element, Gst.Element):
             factory = element.get_factory()
             if factory and "GstVideoScale" == factory.get_element_type().name:
                 element.props.method = 3
-        return gst.BUS_PASS
+        return Gst.BUS_PASS
 
     def _pipelineInit(self, factory, sbin):
         """
@@ -477,28 +479,28 @@ class RandomAccessVideoPreviewer(RandomAccessPreviewer):
         # Use a capsfilter to scale the video to the desired size
         # (fixed height and par, variable width)
         type = "video/x-raw, height=(int)%d, pixel-aspect-ratio=(fraction)1/1" % self.theight
-        caps = gst.caps_from_string(type)
-        capsfilter = gst.element_factory_make("capsfilter", "thumbnailcapsfilter")
+        caps = Gst.caps_from_string(type)
+        capsfilter = Gst.ElementFactory.make("capsfilter", "thumbnailcapsfilter")
         capsfilter.props.caps = caps
         cairosink = CairoSurfaceThumbnailSink()
         cairosink.connect("thumbnail", self._thumbnailCb)
 
         # Set up the thumbnailsink and add a sink pad
-        thumbnailsink = gst.Bin(name="thumbnailsink")
+        thumbnailsink = Gst.Bin(name="thumbnailsink")
         thumbnailsink.add(capsfilter)
         thumbnailsink.add(cairosink)
         capsfilter.link(cairosink)
-        sinkpad = gst.GhostPad.new(name="sink", target=(thumbnailsink.find_unlinked_pad(gst.PAD_SINK)))
+        sinkpad = Gst.GhostPad.new(name="sink", target=(thumbnailsink.find_unlinked_pad(Gst.PadDirection.SINK)))
         thumbnailsink.add_pad(sinkpad)
 
         # Connect sbin and thumbnailsink
         self.videopipeline.props.video_sink = thumbnailsink
 
-        self.videopipeline.set_state(gst.STATE_PAUSED)
+        self.videopipeline.set_state(Gst.State.PAUSED)
         # Wait for the pipeline to be prerolled so we can check the width
         # that the thumbnails will have and set the aspect ratio accordingly
         # as well as getting the framerate of the video:
-        if gst.STATE_CHANGE_SUCCESS == self.videopipeline.get_state(0)[0]:
+        if Gst.StateChangeReturn.SUCCESS == self.videopipeline.get_state(0)[0]:
             neg_caps = sinkpad.get_negotiated_caps()[0]
             self.aspect = neg_caps["width"] / float(self.theight)
             self.framerate = neg_caps["framerate"]
@@ -507,21 +509,21 @@ class RandomAccessVideoPreviewer(RandomAccessPreviewer):
             # correct values. Set sane defaults (this should never happen)
             self.warning("Couldn't preroll the pipeline")
             self.aspect = 16.0 / 9
-            self.framerate = gst.Fraction(24, 1)
+            self.framerate = Gst.Fraction(24, 1)
 
     def _segment_for_time(self, time):
         # quantize thumbnail timestamps to maximum granularity
         return utils.misc.quantize(time, self.tperiod)
 
     def _thumbnailCb(self, unused_thsink, pixbuf, timestamp):
-        gobject.idle_add(self._finishThumbnail, pixbuf, timestamp)
+        GObject.idle_add(self._finishThumbnail, pixbuf, timestamp)
 
     def _startThumbnail(self, timestamp):
         RandomAccessPreviewer._startThumbnail(self, timestamp)
         return self.videopipeline.seek(1.0,
-            gst.FORMAT_TIME, gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE,
-            gst.SEEK_TYPE_SET, timestamp,
-            gst.SEEK_TYPE_NONE, -1)
+            Gst.Format.TIME, Gst.SeekFlags.FLUSH | Gst.SeekFlags.ACCURATE,
+            Gst.SeekType.SET, timestamp,
+            Gst.SeekType.NONE, -1)
 
     def _connectSettings(self, settings):
         RandomAccessPreviewer._connectSettings(self, settings)
@@ -548,7 +550,7 @@ class StillImagePreviewer(RandomAccessVideoPreviewer):
 class RandomAccessAudioPreviewer(RandomAccessPreviewer):
 
     def __init__(self, instance, uri):
-        self.tdur = 30 * gst.SECOND
+        self.tdur = 30 * Gst.SECOND
         self.base_width = int(Zoomable.max_zoom)
         RandomAccessPreviewer.__init__(self, instance, uri)
 
@@ -560,7 +562,7 @@ class RandomAccessAudioPreviewer(RandomAccessPreviewer):
         self.spacing = 0
 
         self.audioSink = ArraySink()
-        conv = gst.element_factory_make("audioconvert")
+        conv = Gst.ElementFactory.make("audioconvert", None)
         self.audioPipeline = utils.pipeline({
             sbin: conv,
             conv: self.audioSink,
@@ -571,7 +573,7 @@ class RandomAccessAudioPreviewer(RandomAccessPreviewer):
         bus.connect("message::error", self._busMessageErrorCb)
 
         self._audio_cur = None
-        self.audioPipeline.set_state(gst.STATE_PAUSED)
+        self.audioPipeline.set_state(Gst.State.PAUSED)
 
     def _spacing(self):
         return 0
@@ -588,19 +590,19 @@ class RandomAccessAudioPreviewer(RandomAccessPreviewer):
         error, debug = message.parse_error()
         self.error("Event bus error: %s: %s", str(error), str(debug))
 
-        return gst.BUS_PASS
+        return Gst.BUS_PASS
 
     def _startThumbnail(self, (timestamp, duration)):
         RandomAccessPreviewer._startThumbnail(self, (timestamp, duration))
         self._audio_cur = timestamp, duration
         res = self.audioPipeline.seek(1.0,
-            gst.FORMAT_TIME,
-            gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE | gst.SEEK_FLAG_SEGMENT,
-            gst.SEEK_TYPE_SET, timestamp,
-            gst.SEEK_TYPE_SET, timestamp + duration)
+            Gst.FORMAT_TIME,
+            Gst.SeekFlags.FLUSH | Gst.SeekFlags.ACCURATE | Gst.SeekFlags.SEGMENT,
+            Gst.SeekType.SET, timestamp,
+            Gst.SeekType.SET, timestamp + duration)
         if not res:
             self.warning("seek failed %s", timestamp)
-        self.audioPipeline.set_state(gst.STATE_PLAYING)
+        self.audioPipeline.set_state(Gst.State.PLAYING)
 
         return res
 
@@ -624,7 +626,7 @@ class RandomAccessAudioPreviewer(RandomAccessPreviewer):
             cr.fill()
             surfaces.append(scaled)
         surfaces.append(surface)
-        gobject.idle_add(self._finishThumbnail, surfaces, self._audio_cur)
+        GObject.idle_add(self._finishThumbnail, surfaces, self._audio_cur)
 
     def _plotWaveform(self, cr, base_width):
         # clear background
@@ -703,24 +705,24 @@ class RandomAccessAudioPreviewer(RandomAccessPreviewer):
         self.emit("update", None)
 
 
-class CairoSurfaceThumbnailSink(gst.BaseSink):
+class CairoSurfaceThumbnailSink(GstBase.BaseSink):
     """
     GStreamer thumbnailing sink element.
 
-    Can be used in pipelines to generates gtk.gdk.Pixbuf automatically.
+    Can be used in pipelines to generates GdkPixbuf.Pixbuf automatically.
     """
 
     __gsignals__ = {
-        "thumbnail": (gobject.SIGNAL_RUN_LAST,
-                      gobject.TYPE_NONE,
-                      (gobject.TYPE_PYOBJECT, gobject.TYPE_UINT64))
+        "thumbnail": (GObject.SignalFlags.RUN_LAST,
+                      None,
+                      (GObject.TYPE_PYOBJECT, GObject.TYPE_UINT64))
         }
 
     __gsttemplates__ = (
-        gst.PadTemplate.new("sink",
-                         gst.PAD_SINK,
-                         gst.PAD_ALWAYS,
-                         gst.caps_from_string("video/x-raw,"
+        Gst.PadTemplate.new("sink",
+                         Gst.PadDirection.SINK,
+                         Gst.PadPresence.ALWAYS,
+                         Gst.caps_from_string("video/x-raw,"
                                   "bpp = (int) 32, depth = (int) 32,"
                                   "endianness = (int) BIG_ENDIAN,"
                                   "alpha_mask = (int) %i, "
@@ -737,7 +739,7 @@ class CairoSurfaceThumbnailSink(gst.BaseSink):
         )
 
     def __init__(self):
-        gst.BaseSink.__init__(self)
+        GstBase.BaseSink.__init__(self)
         self._width = 1
         self._height = 1
         self.set_sync(False)
@@ -752,8 +754,7 @@ class CairoSurfaceThumbnailSink(gst.BaseSink):
         return True
 
     def do_render(self, buf):
-        self.log("buffer %s %d" % (gst.TIME_ARGS(buf.timestamp),
-                                   len(buf.data)))
+        self.log("buffer %s %d" % (buf.timestamp, len(buf.data)))
         b = array.array("b")
         b.fromstring(buf)
         pixb = cairo.ImageSurface.create_for_data(b,
@@ -767,12 +768,12 @@ class CairoSurfaceThumbnailSink(gst.BaseSink):
             self.width * 4)
 
         self.emit("thumbnail", pixb, buf.timestamp)
-        return gst.FLOW_OK
+        return Gst.FLOW_OK
 
     def do_preroll(self, buf):
         return self.do_render(buf)
 
-gobject.type_register(CairoSurfaceThumbnailSink)
+GObject.type_register(CairoSurfaceThumbnailSink)
 
 
 def between(a, b, c):
@@ -780,7 +781,7 @@ def between(a, b, c):
 
 
 def intersect(b1, b2):
-    bounds = goocanvas.CanvasBounds()
+    bounds = GooCanvas.CanvasBounds()
     bounds.x1 = max(b1.x1, b2.x1)
     bounds.y1 = max(b1.y1, b2.y1)
     bounds.x2 = min(b1.x2, b2.x2)
@@ -788,7 +789,7 @@ def intersect(b1, b2):
     return bounds
 
 
-class Preview(goocanvas.ItemSimple, goocanvas.Item, Zoomable):
+class Preview(GooCanvas.CanvasItemSimple, GooCanvas.CanvasItem, Zoomable):
 
     """
     Custom canvas item for timeline object previews. This code is just a thin
@@ -816,7 +817,7 @@ class Preview(goocanvas.ItemSimple, goocanvas.Item, Zoomable):
     def _set_height(self, value):
         self._height = value
         self.changed(True)
-    height = gobject.property(_get_height, _set_height, type=float)
+    height = GObject.property(_get_height, _set_height, type=float)
 
 ## element callbacks
 
@@ -848,13 +849,13 @@ class Preview(goocanvas.ItemSimple, goocanvas.Item, Zoomable):
     def zoomChanged(self):
         self.changed(True)
 
-## goocanvas item methods
+## GooCanvas item methods
 
     def do_simple_update(self, cr):
         cr.identity_matrix()
         if issubclass(self.previewer.__class__, RandomAccessPreviewer):
             border_width = self.previewer._spacing()
-            self.boundz = goocanvas.CanvasBounds()
+            self.boundz = GooCanvas.CanvasBounds()
             self.boundz.x1 = border_width
             self.boundz.x2 = max(0, Zoomable.nsToPixel(self.element.get_duration()))
             self.boundz.y1 = 4
diff --git a/pitivi/timeline/timeline.py b/pitivi/timeline/timeline.py
index 02e3d87..ea3ad75 100644
--- a/pitivi/timeline/timeline.py
+++ b/pitivi/timeline/timeline.py
@@ -27,24 +27,22 @@
 import sys
 import time
 
-import gtk
-import gst
-import ges
-import glib
-import ruler
-import gobject
-import goocanvas
-
 from gi.repository import Gtk
+from gi.repository import Gst
+from gi.repository import GES
+from gi.repository import GObject
+from gi.repository import GooCanvas
+
 from gi.repository import Gdk
 
 from gettext import gettext as _
 from os.path import join
 
+from pitivi.timeline import ruler
 from pitivi.check import soft_deps
 from pitivi.effects import AUDIO_EFFECT, VIDEO_EFFECT
 from pitivi.autoaligner import AlignmentProgressDialog
-from pitivi.utils.misc import quote_uri
+from pitivi.utils.misc import quote_uri, print_ns
 from pitivi.utils.pipeline import PipelineError
 from pitivi.settings import GlobalSettings
 
@@ -93,9 +91,9 @@ PreferencesDialog.addNumericPreference('imageClipLength',
 
 
 # cursors to be used for resizing objects
-ARROW = gtk.gdk.Cursor(gtk.gdk.ARROW)
+ARROW = Gdk.Cursor.new(Gdk.CursorType.ARROW)
 # TODO: replace this with custom cursor
-PLAYHEAD_CURSOR = gtk.gdk.Cursor(gtk.gdk.SB_H_DOUBLE_ARROW)
+PLAYHEAD_CURSOR = Gdk.Cursor.new(Gdk.CursorType.SB_H_DOUBLE_ARROW)
 
 # Drag and drop constants/tuples
 # FIXME, rethink the way we handle that as it is quite 'hacky'
@@ -174,9 +172,9 @@ ui = '''
 '''
 
 
-class TimelineCanvas(goocanvas.Canvas, Zoomable, Loggable):
+class TimelineCanvas(GooCanvas.Canvas, Zoomable, Loggable):
     """
-        The goocanvas widget representing the timeline
+        The GooCanvas widget representing the timeline
     """
 
     __gtype_name__ = 'TimelineCanvas'
@@ -184,7 +182,7 @@ class TimelineCanvas(goocanvas.Canvas, Zoomable, Loggable):
     _tracks = None
 
     def __init__(self, instance, timeline=None):
-        goocanvas.Canvas.__init__(self)
+        GooCanvas.Canvas.__init__(self)
         Zoomable.__init__(self)
         Loggable.__init__(self)
         self.app = instance
@@ -205,22 +203,22 @@ class TimelineCanvas(goocanvas.Canvas, Zoomable, Loggable):
     def _createUI(self):
         self._cursor = ARROW
         root = self.get_root_item()
-        self.tracks = goocanvas.Group()
+        self.tracks = GooCanvas.CanvasGroup()
         self.tracks.set_simple_transform(0, 0, 1.0, 0)
         root.add_child(self.tracks, -1)
-        self._marquee = goocanvas.Rect(
+        self._marquee = GooCanvas.CanvasRect(
             parent=root,
             stroke_color_rgba=0x33CCFF66,
             fill_color_rgba=0x33CCFF66,
-            visibility=goocanvas.ITEM_INVISIBLE)
-        self._playhead = goocanvas.Rect(
+            visibility=GooCanvas.CanvasItemVisibility.INVISIBLE)
+        self._playhead = GooCanvas.CanvasRect(
             y=-10,
             parent=root,
             line_width=1,
             fill_color_rgba=0x000000FF,
             stroke_color_rgba=0xFFFFFFFF,
             width=3)
-        self._snap_indicator = goocanvas.Rect(
+        self._snap_indicator = GooCanvas.CanvasRect(
             parent=root, x=0, y=0, width=3, line_width=0.5,
             fill_color_rgba=0x85c0e6FF,
             stroke_color_rgba=0x294f95FF)
@@ -262,12 +260,12 @@ class TimelineCanvas(goocanvas.Canvas, Zoomable, Loggable):
         # FIXME GObject Introspection -> move to Gtk.StyleContext
         #self.style.apply_default_background(event.window,
             #True,
-            #gtk.STATE_ACTIVE,
+            #Gtk.StateType.ACTIVE,
             #event.area,
             #event.area.x, event.area.y,
             #event.area.width, event.area.height)
 
-        #goocanvas.Canvas.do_expose_event(self, event)
+        #GooCanvas.Canvas.do_expose_event(self, event)
 
 ## implements selection marquee
 
@@ -292,7 +290,7 @@ class TimelineCanvas(goocanvas.Canvas, Zoomable, Loggable):
 
         @returns: A list of L{Track}, L{TrackObject} tuples
         '''
-        bounds = goocanvas.CanvasBounds()
+        bounds = GooCanvas.CanvasBounds()
         bounds.x1 = x1
         bounds.x2 = x2
         bounds.y1 = y1
@@ -336,27 +334,27 @@ class TimelineCanvas(goocanvas.Canvas, Zoomable, Loggable):
 
     def _selectionStart(self, item, target, event):
         self._selecting = True
-        self._marquee.props.visibility = goocanvas.ITEM_VISIBLE
+        self._marquee.props.visibility = GooCanvas.CanvasItemVisibility.VISIBLE
         self._mousedown = self.from_event(event) + self._get_adjustment(False, True)
         self._marquee.props.width = 0
         self._marquee.props.height = 0
-        self.pointer_grab(self.get_root_item(), gtk.gdk.POINTER_MOTION_MASK |
-            gtk.gdk.BUTTON_RELEASE_MASK, self._cursor, event.time)
+        self.pointer_grab(self.get_root_item(), Gdk.EventMask.POINTER_MOTION_MASK |
+            Gdk.EventMask.BUTTON_RELEASE_MASK, self._cursor, event.time)
         return True
 
     def _selectionEnd(self, item, target, event):
         self.pointer_ungrab(self.get_root_item(), event.time)
         self._selecting = False
-        self._marquee.props.visibility = goocanvas.ITEM_INVISIBLE
+        self._marquee.props.visibility = GooCanvas.CanvasItemVisibility.INVISIBLE
         if not self._got_motion_notify:
             self._timeline.selection.setSelection([], 0)
             self.app.current.seeker.seek(Zoomable.pixelToNs(event.x))
         elif self._timeline is not None:
             self._got_motion_notify = False
             mode = 0
-            if event.get_state()[1] & gtk.gdk.SHIFT_MASK:
+            if event.get_state()[1] & Gdk.ModifierType.SHIFT_MASK:
                 mode = 1
-            if event.get_state()[1] & gtk.gdk.CONTROL_MASK:
+            if event.get_state()[1] & Gdk.ModifierType.CONTROL_MASK:
                 mode = 2
             selected = self._objectsUnderMarquee()
             self._timeline.selection.setSelection(self._objectsUnderMarquee(), mode)
@@ -405,10 +403,10 @@ class TimelineCanvas(goocanvas.Canvas, Zoomable, Loggable):
             self.debug("Snapping indicator at %d" % position)
             self._snap_indicator.props.x = Zoomable.nsToPixel(position)
             self._snap_indicator.props.height = self.height
-            self._snap_indicator.props.visibility = goocanvas.ITEM_VISIBLE
+            self._snap_indicator.props.visibility = GooCanvas.CanvasItemVisibility.VISIBLE
 
     def _snapEndedCb(self, *args):
-        self._snap_indicator.props.visibility = goocanvas.ITEM_INVISIBLE
+        self._snap_indicator.props.visibility = GooCanvas.CanvasItemVisibility.INVISIBLE
 
     def _buttonReleasedCb(self, canvas, event):
         # select clicked layer, if any
@@ -489,20 +487,20 @@ class TimelineCanvas(goocanvas.Canvas, Zoomable, Loggable):
             track.updateTrackObjects()
 
 
-class TimelineControls(gtk.VBox, Loggable):
+class TimelineControls(Gtk.VBox, Loggable):
     """
     Holds and manages the LayerControlWidgets
     """
 
     __gsignals__ = {
        "selection-changed": (
-            gobject.SIGNAL_RUN_LAST,
-            gobject.TYPE_NONE,
-            (gobject.TYPE_PYOBJECT,),)
+            GObject.SignalFlags.RUN_LAST,
+            None,
+            (GObject.TYPE_PYOBJECT,),)
        }
 
     def __init__(self, instance):
-        gtk.VBox.__init__(self)
+        GObject.GObject.__init__(self)
         Loggable.__init__(self)
         self.app = instance
         self._layer_controls = {}
@@ -510,8 +508,8 @@ class TimelineControls(gtk.VBox, Loggable):
         self._timeline = None
         self.set_spacing(0)
         self.separator_height = 0
-        self.type_map = {ges.TRACK_TYPE_AUDIO: AudioLayerControl,
-                         ges.TRACK_TYPE_VIDEO: VideoLayerControl}
+        self.type_map = {GES.TrackType.AUDIO: AudioLayerControl,
+                         GES.TrackType.VIDEO: VideoLayerControl}
         self.connect("size-allocate", self._sizeAllocatedCb)
         self.priority_block = sys.maxint
         self.priority_block_time = time.time()
@@ -520,8 +518,8 @@ class TimelineControls(gtk.VBox, Loggable):
         self.connect("drag_drop", self._dragDropCb)
         self.connect("drag_motion", self._dragMotionCb)
         self.connect("drag_leave", self._dragLeaveCb)
-        self.drag_dest_set(gtk.DEST_DEFAULT_ALL,
-                             [LAYER_CONTROL_TARGET_ENTRY], gtk.gdk.ACTION_MOVE)
+        self.drag_dest_set(Gtk.DestDefaults.ALL,
+                             [LAYER_CONTROL_TARGET_ENTRY], Gdk.DragAction.MOVE)
 
     def _sizeAllocatedCb(self, widget, alloc):
         if self.get_children():
@@ -560,12 +558,12 @@ class TimelineControls(gtk.VBox, Loggable):
         video_control = VideoLayerControl(self.app, layer)
         audio_control = AudioLayerControl(self.app, layer)
 
-        map = {ges.TRACK_TYPE_AUDIO: audio_control,
-               ges.TRACK_TYPE_VIDEO: video_control}
+        map = {GES.TrackType.AUDIO: audio_control,
+               GES.TrackType.VIDEO: video_control}
         self._layer_controls[layer] = map
 
-        self.pack_start(video_control, False, False)
-        self.pack_start(audio_control, False, False)
+        self.pack_start(video_control, False, False, 0)
+        self.pack_start(audio_control, False, False, 0)
 
         audio_control.show()
         video_control.show()
@@ -575,8 +573,8 @@ class TimelineControls(gtk.VBox, Loggable):
         self._updatePopupMenus()
 
     def _layerRemovedCb(self, timeline, layer):
-        audio_control = self._layer_controls[layer][ges.TRACK_TYPE_AUDIO]
-        video_control = self._layer_controls[layer][ges.TRACK_TYPE_VIDEO]
+        audio_control = self._layer_controls[layer][GES.TrackType.AUDIO]
+        video_control = self._layer_controls[layer][GES.TrackType.VIDEO]
 
         self.remove(audio_control)
         self.remove(video_control)
@@ -637,10 +635,10 @@ class TimelineControls(gtk.VBox, Loggable):
         last.updateMenuSensitivity(-1)
 
     def getHeightOfLayer(self, track_type, layer):
-        if track_type == ges.TRACK_TYPE_VIDEO:
-            return self._layer_controls[layer][ges.TRACK_TYPE_VIDEO].getControlHeight()
+        if track_type == GES.TrackType.VIDEO:
+            return self._layer_controls[layer][GES.TrackType.VIDEO].getControlHeight()
         else:
-            return self._layer_controls[layer][ges.TRACK_TYPE_AUDIO].getControlHeight()
+            return self._layer_controls[layer][GES.TrackType.AUDIO].getControlHeight()
 
     def getYOfLayer(self, track_type, layer):
         y = 0
@@ -701,8 +699,8 @@ class TimelineControls(gtk.VBox, Loggable):
         Enable this layer and disable all others
         """
         for key, controls in self._layer_controls.iteritems():
-            controls[ges.TRACK_TYPE_VIDEO].setSoloState(key == layer)
-            controls[ges.TRACK_TYPE_AUDIO].setSoloState(key == layer)
+            controls[GES.TrackType.VIDEO].setSoloState(key == layer)
+            controls[GES.TrackType.AUDIO].setSoloState(key == layer)
 
     def selectLayerControl(self, layer_control):
         """
@@ -717,16 +715,16 @@ class TimelineControls(gtk.VBox, Loggable):
         for key, controls in self._layer_controls.iteritems():
             # selected widget not in this layer
             if key != layer:
-                controls[ges.TRACK_TYPE_VIDEO].selected = False
-                controls[ges.TRACK_TYPE_AUDIO].selected = False
+                controls[GES.TrackType.VIDEO].selected = False
+                controls[GES.TrackType.AUDIO].selected = False
             # selected widget in this layer
             else:
                 if type(layer_control) is AudioLayerControl:
-                    controls[ges.TRACK_TYPE_VIDEO].selected = False
-                    controls[ges.TRACK_TYPE_AUDIO].selected = True
+                    controls[GES.TrackType.VIDEO].selected = False
+                    controls[GES.TrackType.AUDIO].selected = True
                 else:  # video
-                    controls[ges.TRACK_TYPE_VIDEO].selected = True
-                    controls[ges.TRACK_TYPE_AUDIO].selected = False
+                    controls[GES.TrackType.VIDEO].selected = True
+                    controls[GES.TrackType.AUDIO].selected = False
 
     def getSelectedLayer(self):
         return self._selected_layer
@@ -873,13 +871,13 @@ class TimelineControls(gtk.VBox, Loggable):
             counter += 1
 
 
-class InfoStub(gtk.HBox, Loggable):
+class InfoStub(Gtk.HBox, Loggable):
     """
     Box used to display information on the current state of the timeline
     """
 
     def __init__(self):
-        gtk.HBox.__init__(self)
+        GObject.GObject.__init__(self)
         Loggable.__init__(self)
         self.errors = []
         self._scroll_pos_ns = 0
@@ -888,22 +886,22 @@ class InfoStub(gtk.HBox, Loggable):
 
     def _makeUI(self):
         self.set_spacing(SPACING)
-        self.erroricon = gtk.image_new_from_stock(gtk.STOCK_DIALOG_WARNING,
-                                                  gtk.ICON_SIZE_SMALL_TOOLBAR)
+        self.erroricon = Gtk.Image.new_from_stock(Gtk.STOCK_DIALOG_WARNING,
+                                                  Gtk.IconSize.SMALL_TOOLBAR)
 
-        self.pack_start(self.erroricon, expand=False)
+        self.pack_start(self.erroricon, False, True, 0)
 
-        self.infolabel = gtk.Label(self._errorsmessage)
+        self.infolabel = Gtk.Label(label=self._errorsmessage)
         self.infolabel.set_alignment(0, 0.5)
 
-        self.questionbutton = gtk.Button()
-        self.infoicon = gtk.Image()
-        self.infoicon.set_from_stock(gtk.STOCK_INFO, gtk.ICON_SIZE_SMALL_TOOLBAR)
+        self.questionbutton = Gtk.Button()
+        self.infoicon = Gtk.Image()
+        self.infoicon.set_from_stock(Gtk.STOCK_INFO, Gtk.IconSize.SMALL_TOOLBAR)
         self.questionbutton.add(self.infoicon)
         self.questionbutton.connect("clicked", self._questionButtonClickedCb)
 
-        self.pack_start(self.infolabel, expand=True, fill=True)
-        self.pack_start(self.questionbutton, expand=False)
+        self.pack_start(self.infolabel, True, True, 0)
+        self.pack_start(self.questionbutton, False, True, 0)
 
     def addErrors(self, *args):
         self.errors.append(args)
@@ -934,7 +932,7 @@ class InfoStub(gtk.HBox, Loggable):
         self.show_all()
 
 
-class Timeline(gtk.Table, Loggable, Zoomable):
+class Timeline(Gtk.Table, Loggable, Zoomable):
     """
     Initiate and manage the timeline's user interface components.
 
@@ -943,7 +941,7 @@ class Timeline(gtk.Table, Loggable, Zoomable):
     """
 
     def __init__(self, instance, ui_manager):
-        gtk.Table.__init__(self, rows=2, columns=1, homogeneous=False)
+        Gtk.Table.__init__(self, rows=2, columns=1, homogeneous=False)
         Loggable.__init__(self)
         Zoomable.__init__(self)
         self.log("Creating Timeline")
@@ -956,7 +954,7 @@ class Timeline(gtk.Table, Loggable, Zoomable):
         self._factories = None
         self._finish_drag = False
         self._createUI()
-        self._framerate = gst.Fraction(1, 1)
+        self._framerate = Gst.Fraction(1, 1)
         self._timeline = None
 
         # Used to insert sources at the end of the timeline
@@ -979,65 +977,67 @@ class Timeline(gtk.Table, Loggable, Zoomable):
                 self._snapDistanceChangedCb)
 
     def _createUI(self):
-        self.leftSizeGroup = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
+        self.leftSizeGroup = Gtk.SizeGroup(Gtk.SizeGroupMode.HORIZONTAL)
         self.props.row_spacing = 2
         self.props.column_spacing = 2
-        self.hadj = gtk.Adjustment()
-        self.vadj = gtk.Adjustment()
+        self.hadj = Gtk.Adjustment()
+        self.vadj = Gtk.Adjustment()
 
         # zooming slider's "zoom fit" button
-        zoom_controls_hbox = gtk.HBox()
-        zoom_fit_btn = gtk.Button()
-        zoom_fit_btn.set_relief(gtk.RELIEF_NONE)
+        zoom_controls_hbox = Gtk.HBox()
+        zoom_fit_btn = Gtk.Button()
+        zoom_fit_btn.set_relief(Gtk.ReliefStyle.NONE)
         zoom_fit_btn.set_tooltip_text(ZOOM_FIT)
-        zoom_fit_icon = gtk.Image()
-        zoom_fit_icon.set_from_stock(gtk.STOCK_ZOOM_FIT, gtk.ICON_SIZE_BUTTON)
-        zoom_fit_btn_hbox = gtk.HBox()
-        zoom_fit_btn_hbox.pack_start(zoom_fit_icon, expand=False)
-        zoom_fit_btn_hbox.pack_start(gtk.Label(_("Zoom")), expand=False)
+        zoom_fit_icon = Gtk.Image()
+        zoom_fit_icon.set_from_stock(Gtk.STOCK_ZOOM_FIT, Gtk.IconSize.BUTTON)
+        zoom_fit_btn_hbox = Gtk.HBox()
+        zoom_fit_btn_hbox.pack_start(zoom_fit_icon, False, True, 0)
+        zoom_fit_btn_hbox.pack_start(Gtk.Label(_("Zoom")), False, True, 0)
         zoom_fit_btn.add(zoom_fit_btn_hbox)
         zoom_fit_btn.connect("clicked", self._zoomFitCb)
-        zoom_controls_hbox.pack_start(zoom_fit_btn, expand=False)
+        zoom_controls_hbox.pack_start(zoom_fit_btn, False, True, 0)
         # zooming slider
-        self._zoomAdjustment = gtk.Adjustment()
+        self._zoomAdjustment = Gtk.Adjustment()
         self._zoomAdjustment.set_value(Zoomable.getCurrentZoomLevel())
         self._zoomAdjustment.connect("value-changed", self._zoomAdjustmentChangedCb)
         self._zoomAdjustment.props.lower = 0
         self._zoomAdjustment.props.upper = Zoomable.zoom_steps
-        zoomslider = gtk.HScale(self._zoomAdjustment)
+        zoomslider = Gtk.HScale(adjustment=self._zoomAdjustment)
         zoomslider.props.draw_value = False
         zoomslider.set_tooltip_text(_("Zoom Timeline"))
         zoomslider.connect("scroll-event", self._zoomSliderScrollCb)
         zoomslider.set_size_request(100, 0)  # At least 100px wide for precision
-        zoom_controls_hbox.pack_start(zoomslider)
-        self.attach(zoom_controls_hbox, 0, 1, 0, 1, yoptions=0, xoptions=gtk.FILL)
+        zoom_controls_hbox.pack_start(zoomslider, True, True, 0)
+        self.attach(zoom_controls_hbox, 0, 1, 0, 1, yoptions=0, xoptions=Gtk.AttachOptions.FILL)
 
         # controls for tracks and layers
         self.controls = TimelineControls(self.app)
-        controlwindow = gtk.Viewport(None, None)
+        controlwindow = Gtk.Viewport(None, None)
         controlwindow.add(self.controls)
         controlwindow.set_size_request(-1, 1)
-        controlwindow.set_shadow_type(gtk.SHADOW_OUT)
-        scrolledwindow = gtk.ScrolledWindow()
+        controlwindow.set_shadow_type(Gtk.ShadowType.OUT)
+        scrolledwindow = Gtk.ScrolledWindow()
         scrolledwindow.add(controlwindow)
-        scrolledwindow.props.hscrollbar_policy = gtk.POLICY_NEVER
-        scrolledwindow.props.vscrollbar_policy = gtk.POLICY_ALWAYS
+        scrolledwindow.props.hscrollbar_policy = Gtk.PolicyType.NEVER
+        scrolledwindow.props.vscrollbar_policy = Gtk.PolicyType.ALWAYS
         scrolledwindow.props.vadjustment = self.vadj
         # We need ALWAYS policy for correct sizing, but we don't want the
         # scrollbar to be visible. Yay gtk3!
         scrollbar = scrolledwindow.get_vscrollbar()
+
         def scrollbar_show_cb(scrollbar):
             scrollbar.hide()
+
         scrollbar.connect("show", scrollbar_show_cb)
         scrollbar.hide()
-        self.attach(scrolledwindow, 0, 1, 1, 2, xoptions=gtk.FILL)
+        self.attach(scrolledwindow, 0, 1, 1, 2, xoptions=Gtk.AttachOptions.FILL)
 
         # timeline ruler
         self.ruler = ruler.ScaleRuler(self.app, self.hadj)
         self.ruler.set_size_request(0, 25)
         self.ruler.connect("key-press-event", self._keyPressEventCb)
-        rulerframe = gtk.Frame()
-        rulerframe.set_shadow_type(gtk.SHADOW_OUT)
+        rulerframe = Gtk.Frame()
+        rulerframe.set_shadow_type(Gtk.ShadowType.OUT)
         rulerframe.add(self.ruler)
         self.attach(rulerframe, 1, 2, 0, 1, yoptions=0)
 
@@ -1047,8 +1047,8 @@ class Timeline(gtk.Table, Loggable, Zoomable):
         self.attach(self._canvas, 1, 2, 1, 2)
 
         # scrollbar
-        self._hscrollbar = gtk.HScrollbar(self.hadj)
-        self._vscrollbar = gtk.VScrollbar(self.vadj)
+        self._hscrollbar = Gtk.HScrollbar(self.hadj)
+        self._vscrollbar = Gtk.VScrollbar(self.vadj)
         self.attach(self._hscrollbar, 1, 2, 2, 3, yoptions=0)
         self.attach(self._vscrollbar, 2, 3, 1, 2, xoptions=0)
         self.hadj.connect("value-changed", self._updateScrollPosition)
@@ -1063,13 +1063,13 @@ class Timeline(gtk.Table, Loggable, Zoomable):
 
         # toolbar actions
         actions = (
-            ("ZoomIn", gtk.STOCK_ZOOM_IN, None,
+            ("ZoomIn", Gtk.STOCK_ZOOM_IN, None,
             "<Control>plus", ZOOM_IN, self._zoomInCb),
 
-            ("ZoomOut", gtk.STOCK_ZOOM_OUT, None,
+            ("ZoomOut", Gtk.STOCK_ZOOM_OUT, None,
             "<Control>minus", ZOOM_OUT, self._zoomOutCb),
 
-            ("ZoomFit", gtk.STOCK_ZOOM_FIT, None,
+            ("ZoomFit", Gtk.STOCK_ZOOM_FIT, None,
             "<Control>0", ZOOM_FIT, self._zoomFitCb),
 
             ("Screenshot", None, _("Export current frame..."),
@@ -1077,18 +1077,18 @@ class Timeline(gtk.Table, Loggable, Zoomable):
                     "position as an image file."), self._screenshotCb),
 
             # Alternate keyboard shortcuts to the actions above
-            ("ControlEqualAccel", gtk.STOCK_ZOOM_IN, None,
+            ("ControlEqualAccel", Gtk.STOCK_ZOOM_IN, None,
             "<Control>equal", ZOOM_IN, self._zoomInCb),
 
-            ("ControlKPAddAccel", gtk.STOCK_ZOOM_IN, None,
+            ("ControlKPAddAccel", Gtk.STOCK_ZOOM_IN, None,
             "<Control>KP_Add", ZOOM_IN, self._zoomInCb),
 
-            ("ControlKPSubtractAccel", gtk.STOCK_ZOOM_OUT, None,
+            ("ControlKPSubtractAccel", Gtk.STOCK_ZOOM_OUT, None,
             "<Control>KP_Subtract", ZOOM_OUT, self._zoomOutCb),
         )
 
         selection_actions = (
-            ("DeleteObj", gtk.STOCK_DELETE, None,
+            ("DeleteObj", Gtk.STOCK_DELETE, None,
             "Delete", DELETE, self.deleteSelected),
 
             ("UnlinkObj", "pitivi-unlink", None,
@@ -1108,7 +1108,7 @@ class Timeline(gtk.Table, Loggable, Zoomable):
         )
 
         playhead_actions = (
-            ("PlayPause", gtk.STOCK_MEDIA_PLAY, None,
+            ("PlayPause", Gtk.STOCK_MEDIA_PLAY, None,
             "space", _("Start Playback"), self.playPause),
 
             ("Split", "pitivi-split", _("Split"),
@@ -1124,15 +1124,15 @@ class Timeline(gtk.Table, Loggable, Zoomable):
             "R", NEXTKEYFRAME, self._nextKeyframeCb),
         )
 
-        actiongroup = gtk.ActionGroup("timelinepermanent")
+        actiongroup = Gtk.ActionGroup("timelinepermanent")
         actiongroup.add_actions(actions)
         self.ui_manager.insert_action_group(actiongroup, 0)
 
-        self.selection_actions = gtk.ActionGroup("timelineselection")
+        self.selection_actions = Gtk.ActionGroup("timelineselection")
         self.selection_actions.add_actions(selection_actions)
         self.selection_actions.set_sensitive(False)
         self.ui_manager.insert_action_group(self.selection_actions, -1)
-        self.playhead_actions = gtk.ActionGroup("timelineplayhead")
+        self.playhead_actions = Gtk.ActionGroup("timelineplayhead")
         self.playhead_actions.add_actions(playhead_actions)
         self.ui_manager.insert_action_group(self.playhead_actions, -1)
 
@@ -1140,9 +1140,9 @@ class Timeline(gtk.Table, Loggable, Zoomable):
 
         # drag and drop
 
-        self._canvas.drag_dest_set(gtk.DEST_DEFAULT_MOTION | gtk.DEST_DEFAULT_HIGHLIGHT,
+        self._canvas.drag_dest_set(Gtk.DestDefaults.MOTION | Gtk.DestDefaults.HIGHLIGHT,
                                    [FILESOURCE_TARGET_ENTRY, EFFECT_TARGET_ENTRY],
-                                   gtk.gdk.ACTION_COPY)
+                                   Gdk.DragAction.COPY)
 
         self._canvas.drag_dest_add_text_targets()
 
@@ -1156,25 +1156,25 @@ class Timeline(gtk.Table, Loggable, Zoomable):
     def _keyPressEventCb(self, unused_widget, event):
         kv = event.keyval
         self.debug("kv:%r", kv)
-        if kv not in [gtk.keysyms.Left, gtk.keysyms.Right]:
+        if kv not in [Gdk.KEY_Left, Gdk.KEY_Right]:
             return False
         mod = event.get_state()
         try:
-            if mod & gtk.gdk.CONTROL_MASK:
+            if mod & Gdk.ModifierType.CONTROL_MASK:
                 now = self._project.pipeline.getPosition()
-                ltime, rtime = self._project.timeline.edges.closest(now)
+                ltime, rtime = self._project.timeline.edGES.closest(now)
 
-            if kv == gtk.keysyms.Left:
-                if mod & gtk.gdk.SHIFT_MASK:
-                    self._seeker.seekRelative(0 - gst.SECOND)
-                elif mod & gtk.gdk.CONTROL_MASK:
+            if kv == Gdk.KEY_Left:
+                if mod & Gdk.ModifierType.SHIFT_MASK:
+                    self._seeker.seekRelative(0 - Gst.SECOND)
+                elif mod & Gdk.ModifierType.CONTROL_MASK:
                     self._seeker.seek(ltime + 1)
                 else:
                     self.app.current.pipeline.stepFrame(self._framerate, -1)
-            elif kv == gtk.keysyms.Right:
-                if mod & gtk.gdk.SHIFT_MASK:
-                    self._seeker.seekRelative(gst.SECOND)
-                elif mod & gtk.gdk.CONTROL_MASK:
+            elif kv == Gdk.KEY_Right:
+                if mod & Gdk.ModifierType.SHIFT_MASK:
+                    self._seeker.seekRelative(Gst.SECOND)
+                elif mod & Gdk.ModifierType.CONTROL_MASK:
                     self._seeker.seek(rtime + 1)
                 else:
                     self.app.current.pipeline.stepFrame(self._framerate, 1)
@@ -1196,7 +1196,7 @@ class Timeline(gtk.Table, Loggable, Zoomable):
                 focus = self._temp_objects[0]
                 if self._move_context is  None:
                     self._move_context = EditingContext(focus,
-                            self.timeline, ges.EDIT_MODE_NORMAL, ges.EDGE_NONE,
+                            self.timeline, GES.EditMode.EDIT_NORMAL, GES.Edge.EDGE_NONE,
                             set(self._temp_objects[1:]), self.app.settings)
 
                 self._move_temp_source(x, y)
@@ -1212,7 +1212,7 @@ class Timeline(gtk.Table, Loggable, Zoomable):
         """
         self.debug("Drag leave")
         self._canvas.handler_block_by_func(self._dragMotionCb)
-        gobject.timeout_add(75, self._dragCleanUp, context)
+        GObject.timeout_add(75, self._dragCleanUp, context)
 
     def _dragCleanUp(self, context):
         """
@@ -1276,13 +1276,13 @@ class Timeline(gtk.Table, Loggable, Zoomable):
                 # Which means, it has the corresponding media_type
                 for tckobj in tlobj.get_track_objects():
                     track = tckobj.get_track()
-                    if track.get_property("track_type") == ges.TRACK_TYPE_AUDIO and \
+                    if track.get_property("track_type") == GES.TrackType.AUDIO and \
                             media_type == AUDIO_EFFECT or \
-                            track.get_property("track_type") == ges.TRACK_TYPE_VIDEO and \
+                            track.get_property("track_type") == GES.TrackType.VIDEO and \
                             media_type == VIDEO_EFFECT:
                         #Actually add the effect
                         self.app.action_log.begin("add effect")
-                        effect = ges.TrackParseLaunchEffect(bin_description=bin_desc)
+                        effect = GES.TrackParseLaunchEffect(bin_description=bin_desc)
                         tlobj.add_track_object(effect)
                         track.add_object(effect)
                         self.app.gui.clipconfig.effect_expander.updateAll()
@@ -1313,10 +1313,10 @@ class Timeline(gtk.Table, Loggable, Zoomable):
         Returns a list containing the full path and the mimetype if successful,
         returns none otherwise.
         """
-        chooser = gtk.FileChooserDialog(_("Save As..."), self.app.gui,
-            action=gtk.FILE_CHOOSER_ACTION_SAVE,
-            buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
-            gtk.STOCK_SAVE, gtk.RESPONSE_OK))
+        chooser = Gtk.FileChooserDialog(_("Save As..."), self.app.gui,
+            action=Gtk.FileChooserAction.SAVE,
+            buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
+            Gtk.STOCK_SAVE, Gtk.ResponseType.OK))
         chooser.set_icon_name("pitivi")
         chooser.set_select_multiple(False)
         chooser.set_current_name(_("Untitled"))
@@ -1325,12 +1325,12 @@ class Timeline(gtk.Table, Loggable, Zoomable):
         formats = {_("PNG image"): ["image/png", ("png",)],
             _("JPEG image"): ["image/jpeg", ("jpg", "jpeg")]}
         for format in formats:
-            filt = gtk.FileFilter()
+            filt = Gtk.FileFilter()
             filt.set_name(format)
             filt.add_mime_type(formats.get(format)[0])
             chooser.add_filter(filt)
         response = chooser.run()
-        if response == gtk.RESPONSE_OK:
+        if response == Gtk.ResponseType.OK:
             chosen_format = formats.get(filt.get_name())
             chosen_ext = chosen_format[1][0]
             chosen_mime = chosen_format[0]
@@ -1350,7 +1350,7 @@ class Timeline(gtk.Table, Loggable, Zoomable):
         layers = self.timeline.get_layers()
 
         if (len(layers) == 0):
-            layer = ges.TimelineLayer()
+            layer = GES.TimelineLayer()
             layer.props.auto_transition = True
             self.timeline.add_layer(layer)
             layers = [layer]
@@ -1381,12 +1381,12 @@ class Timeline(gtk.Table, Loggable, Zoomable):
 
         for uri in self.app.gui.medialibrary.getSelectedItems():
             info = self._project.medialibrary.getInfoFromUri(uri)
-            src = ges.TimelineFileSource(uri=uri)
+            src = GES.TimelineFileSource(uri=uri)
             src.props.start = duration
             # Set image duration
             # FIXME: after GES Materials are merged, check if image instead
             if src.props.duration == 0:
-                src.set_duration(long(self._settings.imageClipLength) * gst.SECOND / 1000)
+                src.set_duration(long(self._settings.imageClipLength) * Gst.SECOND / 1000)
             duration += info.get_duration()
             layer.add_object(src)
             id = src.connect("track-object-added", self._trackObjectsCreatedCb, src, x, y)
@@ -1398,7 +1398,7 @@ class Timeline(gtk.Table, Loggable, Zoomable):
         # TrackObject-s creation is short enough so we are all good when the
         # first TrackObject is added to the TimelineObject
         if tlobj.is_image():
-            tlobj.set_duration(long(self._settings.imageClipLength) * gst.SECOND / 1000)
+            tlobj.set_duration(long(self._settings.imageClipLength) * Gst.SECOND / 1000)
         self._temp_objects.insert(0, tlobj)
         tlobj.disconnect(self._creating_tckobjs_sigid[tlobj])
         del self._creating_tckobjs_sigid[tlobj]
@@ -1415,30 +1415,30 @@ class Timeline(gtk.Table, Loggable, Zoomable):
 ## Zooming and Scrolling
 
     def _scrollEventCb(self, canvas, event):
-        if event.state & gtk.gdk.SHIFT_MASK:
+        if event.get_state() & Gdk.ModifierType.SHIFT_MASK:
             # shift + scroll => vertical (up/down) scroll
-            if event.direction == gtk.gdk.SCROLL_UP:
+            if event.direction == Gdk.ScrollDirection.UP:
                 self.scroll_up()
-            elif event.direction == gtk.gdk.SCROLL_DOWN:
+            elif event.direction == Gdk.ScrollDirection.DOWN:
                 self.scroll_down()
-            event.state &= ~gtk.gdk.SHIFT_MASK
-        elif event.state & gtk.gdk.CONTROL_MASK:
+            event.props.state &= ~Gdk.SHIFT_MASK
+        elif event.get_state() & Gdk.ModifierType.CONTROL_MASK:
             # zoom + scroll => zooming (up: zoom in)
-            if event.direction == gtk.gdk.SCROLL_UP:
+            if event.direction == Gdk.ScrollDirection.UP:
                 Zoomable.zoomIn()
                 self.log("Setting 'zoomed_fitted' to False")
                 self.zoomed_fitted = False
                 return True
-            elif event.direction == gtk.gdk.SCROLL_DOWN:
+            elif event.direction == Gdk.ScrollDirection.DOWN:
                 Zoomable.zoomOut()
                 self.log("Setting 'zoomed_fitted' to False")
                 self.zoomed_fitted = False
                 return True
             return False
         else:
-            if event.direction == gtk.gdk.SCROLL_UP:
+            if event.direction == Gdk.ScrollDirection.UP:
                 self.scroll_left()
-            elif event.direction == gtk.gdk.SCROLL_DOWN:
+            elif event.direction == Gdk.ScrollDirection.DOWN:
                 self.scroll_right()
         return True
 
@@ -1476,9 +1476,9 @@ class Timeline(gtk.Table, Loggable, Zoomable):
 
     def _zoomSliderScrollCb(self, unused_widget, event):
         value = self._zoomAdjustment.get_value()
-        if event.direction in [gtk.gdk.SCROLL_UP, gtk.gdk.SCROLL_RIGHT]:
+        if event.direction in [Gdk.ScrollDirection.UP, Gdk.ScrollDirection.RIGHT]:
             self._zoomAdjustment.set_value(value + 1)
-        elif event.direction in [gtk.gdk.SCROLL_DOWN, gtk.gdk.SCROLL_LEFT]:
+        elif event.direction in [Gdk.ScrollDirection.DOWN, Gdk.ScrollDirection.LEFT]:
             self._zoomAdjustment.set_value(value - 1)
 
     def zoomChanged(self):
@@ -1511,7 +1511,7 @@ class Timeline(gtk.Table, Loggable, Zoomable):
     def positionChangedCb(self, seeker, position):
         self.ruler.timelinePositionChanged(position)
         self._canvas.timelinePositionChanged(position)
-        if self.app.current.pipeline.getState() == gst.STATE_PLAYING:
+        if self.app.current.pipeline.getState() == Gst.State.PLAYING:
             self.scrollToPlayhead()
 
     def scrollToPlayhead(self):
@@ -1532,7 +1532,7 @@ class Timeline(gtk.Table, Loggable, Zoomable):
         if position > self.hadj.props.upper:
             # we can't perform the scroll because the canvas needs to be
             # updated
-            gobject.idle_add(self._scrollToPosition, position)
+            GObject.idle_add(self._scrollToPosition, position)
         else:
             self._scrollToPosition(position)
 
@@ -1550,18 +1550,18 @@ class Timeline(gtk.Table, Loggable, Zoomable):
         Set the zoom level so that the entire timeline is in view.
         """
         ruler_width = self.ruler.get_allocation().width
-        # Add gst.SECOND - 1 to the timeline duration to make sure the
+        # Add Gst.SECOND - 1 to the timeline duration to make sure the
         # last second of the timeline will be in view.
         duration = self.timeline.get_duration()
         if duration == 0:
             self.debug("The timeline duration is 0, impossible to calculate zoom")
             return
 
-        timeline_duration = duration + gst.SECOND - 1
-        timeline_duration_s = int(timeline_duration / gst.SECOND)
+        timeline_duration = duration + Gst.SECOND - 1
+        timeline_duration_s = int(timeline_duration / Gst.SECOND)
 
         self.debug("duration: %s, timeline duration: %s" % (duration,
-           gst.TIME_ARGS(timeline_duration)))
+           print_ns(timeline_duration)))
 
         ideal_zoom_ratio = float(ruler_width) / timeline_duration_s
         nearest_zoom_level = Zoomable.computeZoomLevel(ideal_zoom_ratio)
@@ -1866,7 +1866,7 @@ class Timeline(gtk.Table, Loggable, Zoomable):
     def insertEnd(self, sources):
         """
         Add source at the end of the timeline
-        @type sources: An L{ges.TimelineSource}
+        @type sources: An L{GES.TimelineSource}
         @param x2: A list of sources to add to the timeline
         """
         self.app.action_log.begin("add clip")
@@ -1885,7 +1885,7 @@ class Timeline(gtk.Table, Loggable, Zoomable):
             # We need to wait (100ms is enoug for sure) for TrackObject-s to
             # be added to the Tracks
             # FIXME remove this "hack" when Materials are merged
-            glib.timeout_add(100, self._finalizeSourceAdded)
+            GObject.timeout_add(100, self._finalizeSourceAdded)
             self.app.action_log.commit()
 
             # Update zoom level if needed
@@ -1907,7 +1907,7 @@ class Timeline(gtk.Table, Loggable, Zoomable):
 
         # Set the duration of the clip if it is an image
         if hasattr(source,"is_image") and source.is_image():
-            source.set_duration(long(self._settings.imageClipLength) * gst.SECOND / 1000)
+            source.set_duration(long(self._settings.imageClipLength) * Gst.SECOND / 1000)
 
         # Handle the case where we just inserted the first clip
         if len(layer.get_objects()) == 1:
diff --git a/pitivi/timeline/track.py b/pitivi/timeline/track.py
index c290822..d15d689 100644
--- a/pitivi/timeline/track.py
+++ b/pitivi/timeline/track.py
@@ -20,20 +20,19 @@
 # Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 # Boston, MA 02110-1301, USA.
 
-import goocanvas
-import ges
-import gtk
-import gtk.gdk
-import os.path
-import pango
 import cairo
+import os.path
 
-import pitivi.configure as configure
+from gi.repository import GooCanvas
+from gi.repository import GES
+from gi.repository import Gdk
+from gi.repository import GdkPixbuf
+from gi.repository import Pango
 
 from gettext import gettext as _
 
+import pitivi.configure as configure
 from pitivi.dialogs.prefs import PreferencesDialog
-
 from pitivi.utils.loggable import Loggable
 from pitivi.utils.ui import Point, info_name
 from pitivi.settings import GlobalSettings
@@ -45,12 +44,12 @@ from thumbnailer import Preview
 
 #--------------------------------------------------------------#
 #                       Private stuff                          #
-LEFT_SIDE = gtk.gdk.Cursor(gtk.gdk.LEFT_SIDE)
-RIGHT_SIDE = gtk.gdk.Cursor(gtk.gdk.RIGHT_SIDE)
-ARROW = gtk.gdk.Cursor(gtk.gdk.ARROW)
-TRIMBAR_PIXBUF = gtk.gdk.pixbuf_new_from_file(
+LEFT_SIDE = Gdk.Cursor.new(Gdk.CursorType.LEFT_SIDE)
+RIGHT_SIDE = Gdk.Cursor.new(Gdk.CursorType.RIGHT_SIDE)
+ARROW = Gdk.Cursor.new(Gdk.CursorType.ARROW)
+TRIMBAR_PIXBUF = GdkPixbuf.Pixbuf.new_from_file(
     os.path.join(configure.get_pixmap_dir(), "trimbar-normal.png"))
-TRIMBAR_PIXBUF_FOCUS = gtk.gdk.pixbuf_new_from_file(
+TRIMBAR_PIXBUF_FOCUS = GdkPixbuf.Pixbuf.new_from_file(
     os.path.join(configure.get_pixmap_dir(), "trimbar-focused.png"))
 NAME_HOFFSET = 10
 NAME_VOFFSET = 5
@@ -121,10 +120,10 @@ GlobalSettings.addConfigOption('clipFontColor',
 
 
 def text_size(text):
-    logical = pango.Rectangle()
-    tmp = pango.Rectangle()
+    logical = Pango.Rectangle()
+    tmp = Pango.Rectangle()
     text.get_natural_extents(tmp, logical)
-    pango.extents_to_pixels(logical, tmp)
+    Pango.extents_to_pixels(logical, tmp)
     return tmp.width, tmp.height
 
 
@@ -230,9 +229,9 @@ class TrackObjectController(Controller):
 
     def _getMode(self):
         if self._shift_down:
-            return ges.EDIT_MODE_RIPPLE
+            return GES.EditMode.EDIT_RIPPLE
         elif self._control_down:
-            return ges.EDIT_MODE_ROLL
+            return GES.EditMode.EDIT_ROLL
         return self.default_mode
 
     def key_press(self, keyval):
@@ -244,7 +243,7 @@ class TrackObjectController(Controller):
             self._context.setMode(self._getMode())
 
 
-class TrimHandle(View, goocanvas.Image, Loggable, Zoomable):
+class TrimHandle(View, GooCanvas.CanvasImage, Loggable, Zoomable):
 
     """A component of a TrackObject which manage's the source's edit
     points"""
@@ -255,12 +254,12 @@ class TrimHandle(View, goocanvas.Image, Loggable, Zoomable):
         self.timeline = timeline
         self.movable = True
         self.current_pixbuf = TRIMBAR_PIXBUF
-        goocanvas.Image.__init__(self,
+        GooCanvas.CanvasImage.__init__(self,
             pixbuf=self.current_pixbuf,
             line_width=0,
-            pointer_events=goocanvas.EVENTS_FILL,
+            pointer_events=GooCanvas.CanvasPointerEvents.FILL,
             **kwargs)
-        View.__init__(self, instance, ges.EDIT_MODE_TRIM)
+        View.__init__(self, instance, GES.EditMode.EDIT_TRIM)
         Zoomable.__init__(self)
         Loggable.__init__(self)
 
@@ -288,7 +287,7 @@ class TrimHandle(View, goocanvas.Image, Loggable, Zoomable):
         self.props.pixbuf = self.current_pixbuf.scale_simple(
                                                 self.current_pixbuf.get_width(),
                                                 self.height,
-                                                gtk.gdk.INTERP_BILINEAR)
+                                                GdkPixbuf.InterpType.BILINEAR)
 
 
 class StartHandle(TrimHandle):
@@ -309,7 +308,7 @@ class StartHandle(TrimHandle):
                 elem = self._view.element
 
             self._context = EditingContext(elem, self._view.timeline,
-                ges.EDIT_MODE_TRIM, ges.EDGE_START, set([]),
+                GES.EditMode.EDIT_TRIM, GES.Edge.EDGE_START, set([]),
                 self.app.settings)
             self._context.connect("clip-trim", self.clipTrimCb)
             self._context.connect("clip-trim-finished", self.clipTrimFinishedCb)
@@ -342,7 +341,7 @@ class EndHandle(TrimHandle):
             else:
                 elem = self._view.element
             self._context = EditingContext(elem, self._view.timeline,
-                ges.EDIT_MODE_TRIM, ges.EDGE_END, set([]),
+                GES.EditMode.EDIT_TRIM, GES.Edge.EDGE_END, set([]),
                 self.app.settings)
             self._context.connect("clip-trim", self.clipTrimCb)
             self._context.connect("clip-trim-finished", self.clipTrimFinishedCb)
@@ -357,7 +356,28 @@ class EndHandle(TrimHandle):
             self._view.app.gui.viewer.clipTrimPreviewFinished()
 
 
-class TrackObject(View, goocanvas.Group, Zoomable, Loggable):
+#FIXME PyGI Missing anotation in GooItem(bug 677013), reimplement
+def raise_new(self, above):
+    parent = self.get_parent()
+    if parent is None or above == self:
+        return
+    n_children = parent.get_n_children()
+    for i in range(n_children):
+        child = parent.get_child(i)
+        if (child == self):
+            item_pos = i
+        if (child == above):
+            above_pos = i
+    if above is None:
+        above_pos = n_children - 1
+    if (above_pos > item_pos):
+        parent.move_child(item_pos, above_pos)
+
+
+setattr(GooCanvas.CanvasItem, "raise_", raise_new)
+
+
+class TrackObject(View, GooCanvas.CanvasGroup, Zoomable, Loggable):
 
     class Controller(TrackObjectController):
 
@@ -370,7 +390,7 @@ class TrackObject(View, goocanvas.Group, Zoomable, Loggable):
             TrackObjectController.drag_start(self, item, target, event)
 
             self._context = EditingContext(self._view.element,
-                self._view.timeline, ges.EDIT_MODE_NORMAL, ges.EDGE_NONE,
+                self._view.timeline, GES.EditMode.EDIT_NORMAL, GES.Edge.EDGE_NONE,
                 self._view.timeline.selection.getSelectedTrackObjs(),
                 self.app.settings)
 
@@ -378,15 +398,15 @@ class TrackObject(View, goocanvas.Group, Zoomable, Loggable):
 
         def _getMode(self):
             if self._shift_down:
-                return ges.EDIT_MODE_RIPPLE
-            return ges.EDIT_MODE_NORMAL
+                return GES.EditMode.EDIT_RIPPLE
+            return GES.EditMode.EDIT_NORMAL
 
         def click(self, pos):
             timeline = self._view.timeline
             element = self._view.element
-            if self._last_event.get_state()[1] & gtk.gdk.SHIFT_MASK:
+            if self._last_event.get_state()[1] & Gdk.ModifierType.SHIFT_MASK:
                 timeline.selection.setToObj(element, SELECT_BETWEEN)
-            elif self._last_event.get_state()[1] & gtk.gdk.CONTROL_MASK:
+            elif self._last_event.get_state()[1] & Gdk.ModifierType.CONTROL_MASK:
                 if element.selected:
                     mode = UNSELECT
                 else:
@@ -399,7 +419,7 @@ class TrackObject(View, goocanvas.Group, Zoomable, Loggable):
                 timeline.selection.setToObj(element, SELECT)
 
     def __init__(self, instance, element, track, timeline, utrack):
-        goocanvas.Group.__init__(self)
+        GooCanvas.CanvasGroup.__init__(self)
         View.__init__(self, instance)
         Zoomable.__init__(self)
         Loggable.__init__(self)
@@ -414,14 +434,14 @@ class TrackObject(View, goocanvas.Group, Zoomable, Loggable):
         self._settings = None
         self.movable = True
 
-        self.bg = goocanvas.Rect(height=self.height, line_width=1)
+        self.bg = GooCanvas.CanvasRect(height=self.height, line_width=1)
 
-        self.name = goocanvas.Text(
+        self.name = GooCanvas.CanvasText(
             x=NAME_HOFFSET + NAME_PADDING,
             y=NAME_VOFFSET + NAME_PADDING,
             operator=cairo.OPERATOR_ADD,
-            alignment=pango.ALIGN_LEFT)
-        self.namebg = goocanvas.Rect(
+            alignment=Pango.Alignment.LEFT)
+        self.namebg = GooCanvas.CanvasRect(
             radius_x=2,
             radius_y=2,
             x=NAME_HOFFSET,
@@ -431,8 +451,8 @@ class TrackObject(View, goocanvas.Group, Zoomable, Loggable):
         self.start_handle = StartHandle(self.app, element, timeline, height=self.height)
         self.end_handle = EndHandle(self.app, element, timeline, height=self.height)
 
-        self._selec_indic = goocanvas.Rect(
-            visibility=goocanvas.ITEM_INVISIBLE,
+        self._selec_indic = GooCanvas.CanvasRect(
+            visibility=GooCanvas.CanvasItemVisibility.INVISIBLE,
             line_width=0.0,
             height=self.height)
 
@@ -467,12 +487,12 @@ class TrackObject(View, goocanvas.Group, Zoomable, Loggable):
     def setExpanded(self, expanded):
         self._expanded = expanded
         if not self._expanded:
-            self.preview.props.visibility = goocanvas.ITEM_INVISIBLE
-            self.namebg.props.visibility = goocanvas.ITEM_INVISIBLE
+            self.preview.props.visibility = GooCanvas.CanvasItemVisibility.INVISIBLE
+            self.namebg.props.visibility = GooCanvas.CanvasItemVisibility.INVISIBLE
             self.name.props.y = 0
         else:
-            self.preview.props.visibility = goocanvas.ITEM_VISIBLE
-            self.namebg.props.visibility = goocanvas.ITEM_VISIBLE
+            self.preview.props.visibility = GooCanvas.CanvasItemVisibility.VISIBLE
+            self.namebg.props.visibility = GooCanvas.CanvasItemVisibility.VISIBLE
             self.name.props.y = NAME_VOFFSET + NAME_PADDING
 
     def getExpanded(self):
@@ -486,8 +506,8 @@ class TrackObject(View, goocanvas.Group, Zoomable, Loggable):
 ## Public API
 
     def focus(self):
-        self.start_handle.props.visibility = goocanvas.ITEM_VISIBLE
-        self.end_handle.props.visibility = goocanvas.ITEM_VISIBLE
+        self.start_handle.props.visibility = GooCanvas.CanvasItemVisibility.VISIBLE
+        self.end_handle.props.visibility = GooCanvas.CanvasItemVisibility.VISIBLE
         self.raise_(None)
         for transition in self.utrack.transitions:
             # This is required to ensure that transitions always show on top
@@ -495,8 +515,8 @@ class TrackObject(View, goocanvas.Group, Zoomable, Loggable):
             transition.raise_(None)
 
     def unfocus(self):
-        self.start_handle.props.visibility = goocanvas.ITEM_INVISIBLE
-        self.end_handle.props.visibility = goocanvas.ITEM_INVISIBLE
+        self.start_handle.props.visibility = GooCanvas.CanvasItemVisibility.INVISIBLE
+        self.end_handle.props.visibility = GooCanvas.CanvasItemVisibility.INVISIBLE
 
     def zoomChanged(self):
         self._update()
@@ -591,23 +611,23 @@ class TrackObject(View, goocanvas.Group, Zoomable, Loggable):
         # Note that element is a track.Selected object,
         # whereas self.element is a GES object (ex: TrackVideoTransition)
         if element.selected:
-            if isinstance(self.element, ges.TrackTransition):
-                if isinstance(self.element, ges.TrackVideoTransition):
+            if isinstance(self.element, GES.TrackTransition):
+                if isinstance(self.element, GES.TrackVideoTransition):
                     self.app.gui.trans_list.activate(self.element)
-            elif isinstance(self.element, ges.TrackTitleSource):
+            elif isinstance(self.element, GES.TrackTitleSource):
                 self.app.gui.switchContextTab("title editor")
                 self.app.gui.title_editor.set_source(self.element.get_timeline_object())
             else:
-                if self.element.get_track().get_property("track_type") == ges.TRACK_TYPE_VIDEO:
+                if self.element.get_track().get_property("track_type") == GES.TrackType.VIDEO:
                     has = False
                     tlobj = self.element.get_timeline_object()
                     trackobjs = tlobj.get_track_objects()
                     for trackobj in trackobjs:
-                        if isinstance(trackobj, ges.TrackTextOverlay):
+                        if isinstance(trackobj, GES.TrackTextOverlay):
                             has = True
                             title = trackobj
                     if not has:
-                        title = ges.TrackTextOverlay()
+                        title = GES.TrackTextOverlay()
                         title.set_text("")
                         title.set_start(self.element.get_start())
                         title.set_duration(self.element.get_duration())
@@ -616,10 +636,10 @@ class TrackObject(View, goocanvas.Group, Zoomable, Loggable):
                     self.app.gui.title_editor.set_source(title)
                 self.app.gui.trans_list.deactivate()
                 self.app.gui.switchContextTab()
-            self._selec_indic.props.visibility = goocanvas.ITEM_VISIBLE
+            self._selec_indic.props.visibility = GooCanvas.CanvasItemVisibility.VISIBLE
         else:
             self.app.gui.title_editor.set_source(None)
-            self._selec_indic.props.visibility = goocanvas.ITEM_INVISIBLE
+            self._selec_indic.props.visibility = GooCanvas.CanvasItemVisibility.INVISIBLE
 
     def _update(self):
         # Calculating the new position
@@ -640,8 +660,8 @@ class TrackObject(View, goocanvas.Group, Zoomable, Loggable):
         # get y position for layer
         y = self.app.gui.timeline_ui.controls.getYOfLayer(track_type, layer)
         # get relative y for audio
-        if track_type == ges.TRACK_TYPE_AUDIO:
-            y -= self.app.gui.timeline_ui.controls.getHeightOfTrack(ges.TRACK_TYPE_VIDEO)
+        if track_type == GES.TrackType.AUDIO:
+            y -= self.app.gui.timeline_ui.controls.getHeightOfTrack(GES.TrackType.VIDEO)
 
         # Setting new position
         self.set_simple_transform(x, y, 1, 0)
@@ -664,9 +684,9 @@ class TrackObject(View, goocanvas.Group, Zoomable, Loggable):
                 self.namebg.props.height = self.nameheight + NAME_PADDING2X
                 self.namebg.props.width = min(w - NAME_HOFFSET,
                     self.namewidth + NAME_PADDING2X)
-                self.namebg.props.visibility = goocanvas.ITEM_VISIBLE
+                self.namebg.props.visibility = GooCanvas.CanvasItemVisibility.VISIBLE
             else:
-                self.namebg.props.visibility = goocanvas.ITEM_INVISIBLE
+                self.namebg.props.visibility = GooCanvas.CanvasItemVisibility.INVISIBLE
 
         self.app.gui.timeline_ui._canvas.regroupTracks()
         self.app.gui.timeline_ui.unsureVadjHeight()
@@ -680,12 +700,12 @@ class TrackTransition(TrackObject):
         TrackObject.__init__(self, instance, element, track, timeline, utrack)
         for thing in (self.bg, self._selec_indic, self.namebg, self.name):
             self.add_child(thing, -1)
-        if isinstance(element, ges.TrackVideoTransition):
+        if isinstance(element, GES.TrackVideoTransition):
             element.connect("notify::transition-type", self._changeVideoTransitionCb)
         self.movable = False
 
     def _setElement(self, element):
-        if isinstance(element, ges.TrackVideoTransition):
+        if isinstance(element, GES.TrackVideoTransition):
             self.name.props.text = element.props.transition_type.value_nick
 
     def _getColor(self):
@@ -713,7 +733,7 @@ class TrackTitleSource(TrackObject):
     def _setElement(self, element):
         if self.element:
             text = self.element.get_text()
-            _, _, t, _ = pango.parse_markup(text, -1, u'\x00')
+            _, _, t, _ = Pango.parse_markup(text, -1, u'\x00')
             #TODO trim text, first line etc
             self.name.props.text = t
             twidth, theight = text_size(self.name)
@@ -747,20 +767,20 @@ class TrackFileSource(TrackObject):
             self._update()
 
     def _getColor(self):
-        if self.element.get_track().get_property("track-type") == ges.TRACK_TYPE_AUDIO:
+        if self.element.get_track().get_property("track-type") == GES.TrackType.AUDIO:
             return self.settings.audioClipBg
         else:
             return self.settings.videoClipBg
 
 
-class Track(goocanvas.Group, Zoomable, Loggable):
+class Track(GooCanvas.CanvasGroup, Zoomable, Loggable):
     """
     Groups all TrackObjects of one Track
     """
     __gtype_name__ = 'Track'
 
     def __init__(self, instance, track, timeline=None):
-        goocanvas.Group.__init__(self)
+        GooCanvas.CanvasGroup.__init__(self)
         Zoomable.__init__(self)
         Loggable.__init__(self)
         self.app = instance
@@ -811,19 +831,19 @@ class Track(goocanvas.Group, Zoomable, Loggable):
     track = property(getTrack, setTrack, None, "The timeline property")
 
     def _objectAddedCb(self, unused_timeline, track_object):
-        if isinstance(track_object, ges.TrackTransition):
+        if isinstance(track_object, GES.TrackTransition):
             self._transitionAdded(track_object)
-        elif isinstance(track_object, ges.TrackTitleSource):
+        elif isinstance(track_object, GES.TrackTitleSource):
             w = TrackTitleSource(self.app, track_object, self.track, self.timeline, self)
             self.widgets[track_object] = w
             self.add_child(w, -1)
-        elif isinstance(track_object, ges.TrackFileSource):
+        elif isinstance(track_object, GES.TrackFileSource):
             w = TrackFileSource(self.app, track_object, self.track, self.timeline, self)
             self.widgets[track_object] = w
             self.add_child(w, -1)
 
     def _objectRemovedCb(self, unused_timeline, track_object):
-        if not isinstance(track_object, ges.TrackEffect) and track_object in self.widgets:
+        if not isinstance(track_object, GES.TrackEffect) and track_object in self.widgets:
             w = self.widgets[track_object]
             del self.widgets[track_object]
             self.remove_child(self.find_child(w))
diff --git a/pitivi/titleeditor.py b/pitivi/titleeditor.py
index aba55b0..17262b6 100644
--- a/pitivi/titleeditor.py
+++ b/pitivi/titleeditor.py
@@ -23,11 +23,14 @@
 Shows title editor
 """
 import os
-import gtk
-import pango
-import ges
-import gst
-import gobject
+
+from gi.repository import Gtk
+from gi.repository import Gdk
+from gi.repository import Pango
+from gi.repository import GES
+from gi.repository import Gst
+from gi.repository import GObject
+from gi.repository import GdkPixbuf
 
 from gettext import gettext as _
 from xml.sax import saxutils
@@ -37,64 +40,175 @@ from pitivi.configure import get_ui_dir, get_pixmap_dir
 from pitivi.utils.loggable import Loggable
 from pitivi.utils.signal import Signallable
 from pitivi.utils.pipeline import Seeker
-INVISIBLE = gtk.gdk.pixbuf_new_from_file(os.path.join(get_pixmap_dir(), "invisible.png"))
+INVISIBLE = GdkPixbuf.Pixbuf.new_from_file(os.path.join(get_pixmap_dir(), "invisible.png"))
+
+
+# FIXME Fix Pango so we do NOT need that dirty reimplementation
+# Pango.AttrList
+class AttrIterator():
+    def __init__(self, attributes=[]):
+        self.attributes = attributes
+        self.attribute_stack = []
+        self.start_index = 0
+        self.end_index = 0
+        if not self.next():
+            self.end_index = 2 ** 32 - 1
+
+    def next(self):
+        if len(self.attributes) == 0 and len(self.attribute_stack) == 0:
+            return False
+        self.start_index = self.end_index
+        self.end_index = 2 ** 32 - 1
+
+        to_remove = []
+        for attr in self.attribute_stack:
+            if attr.end_index == self.start_index:
+                to_remove.append(attr)
+            else:
+                self.end_index = min(self.end_index, attr.end_index)
+
+        while len(to_remove) > 0:
+            attr = to_remove[0]
+            self.attribute_stack.remove(to_remove[0])
+            try:
+                to_remove.remove(attr)
+            except:
+                pass
+
+        while len(self.attributes) != 0 and \
+              self.attributes[0].start_index == self.start_index:
+            if self.attributes[0].end_index > self.start_index:
+                self.attribute_stack.append(self.attributes[0])
+                self.end_index = min(self.end_index, self.attributes[0].end_index)
+            self.attributes = self.attributes[1:]
+        if len(self.attributes) > 0:
+            self.end_index = min(self.end_index, self.attributes[0].start_index)
+        return True
+
+    def range(self):
+        return (self.start_index, self.end_index)
+
+    def get_font(self):
+        tmp_list1 = self.attribute_stack
+        fontdesc = Pango.FontDescription()
+        for attr in self.attribute_stack:
+            if attr.klass.type == Pango.AttrType.FONT_DESC:
+                tmp_list1.remove(attr)
+                attr.__class__ = Pango.AttrFontDesc
+                fontdesc = attr.desc
+        return (fontdesc, None, self.attribute_stack)
+
+
+def get_iterator(self):
+    tmplist = []
+
+    def fil(val, data):
+        tmplist.append(val)
+        return False
+
+    self.filter(fil, None)
+    return AttrIterator(tmplist)
+
+
+setattr(Pango.AttrList, 'get_iterator', get_iterator)
+
+
+class AttrFamily(Pango.Attribute):
+    pass
+
+Pango.AttrFamily = AttrFamily
+
+
+class AttrStyle(Pango.Attribute):
+    pass
+
+
+Pango.AttrStyle = AttrStyle
+
+
+class AttrVariant(Pango.Attribute):
+    pass
+
+
+Pango.AttrVariant = AttrVariant
+
+
+class AttrWeight(Pango.Attribute):
+    pass
+
+
+Pango.AttrWeight = AttrWeight
+
+
+class AttrVariant(Pango.Attribute):
+    pass
+
+
+Pango.AttrVariant = AttrVariant
+
+
+class AttrStretch(Pango.Attribute):
+    pass
+
+
+Pango.AttrStretch = AttrStretch
 
 
-class PangoBuffer(gtk.TextBuffer):
+class PangoBuffer(Gtk.TextBuffer):
     desc_to_attr_table = {
-        'family': [pango.AttrFamily, ""],
-        'size': [pango.AttrSize, 14 * 1024],
-        'style': [pango.AttrStyle, pango.STYLE_NORMAL],
-        'variant': [pango.AttrVariant, pango.VARIANT_NORMAL],
-        'weight': [pango.AttrWeight, pango.WEIGHT_NORMAL],
-        'stretch': [pango.AttrStretch, pango.STRETCH_NORMAL]}
+        'family': [Pango.AttrFamily, ""],
+        'size': [Pango.AttrSize, 14 * 1024],
+        'style': [Pango.AttrStyle, Pango.Style.NORMAL],
+        'variant': [Pango.AttrVariant, Pango.Variant.NORMAL],
+        'weight': [Pango.AttrWeight, Pango.Weight.NORMAL],
+        'stretch': [Pango.AttrStretch, Pango.Stretch.NORMAL]}
     # pango ATTR TYPE :(pango attr property / tag property)
     pango_translation_properties = {
-        pango.ATTR_SIZE: 'size',
-        pango.ATTR_WEIGHT: 'weight',
-        pango.ATTR_UNDERLINE: 'underline',
-        pango.ATTR_STRETCH: 'stretch',
-        pango.ATTR_VARIANT: 'variant',
-        pango.ATTR_STYLE: 'style',
-        pango.ATTR_SCALE: 'scale',
-        pango.ATTR_FAMILY: 'family',
-        pango.ATTR_STRIKETHROUGH: 'strikethrough',
-        pango.ATTR_RISE: 'rise'}
+        Pango.AttrType.SIZE: 'size',
+        Pango.AttrType.WEIGHT: 'weight',
+        Pango.AttrType.UNDERLINE: 'underline',
+        Pango.AttrType.STRETCH: 'stretch',
+        Pango.AttrType.VARIANT: 'variant',
+        Pango.AttrType.STYLE: 'style',
+        Pango.AttrType.SCALE: 'scale',
+        Pango.AttrType.FAMILY: 'family',
+        Pango.AttrType.STRIKETHROUGH: 'strikethrough',
+        Pango.AttrType.RISE: 'rise'}
     pango_type_table = {
-        pango.ATTR_SIZE: pango.AttrInt,
-        pango.ATTR_WEIGHT: pango.AttrInt,
-        pango.ATTR_UNDERLINE: pango.AttrInt,
-        pango.ATTR_STRETCH: pango.AttrInt,
-        pango.ATTR_VARIANT: pango.AttrInt,
-        pango.ATTR_STYLE: pango.AttrInt,
-        pango.ATTR_SCALE: pango.AttrFloat,
-        pango.ATTR_FAMILY: pango.AttrString,
-        pango.ATTR_FONT_DESC: pango.AttrFontDesc,
-        pango.ATTR_STRIKETHROUGH: pango.AttrInt,
-        pango.ATTR_BACKGROUND: pango.AttrColor,
-        pango.ATTR_FOREGROUND: pango.AttrColor,
-        pango.ATTR_RISE: pango.AttrInt}
+        Pango.AttrType.SIZE: Pango.AttrInt,
+        Pango.AttrType.WEIGHT: Pango.AttrInt,
+        Pango.AttrType.UNDERLINE: Pango.AttrInt,
+        Pango.AttrType.STRETCH: Pango.AttrInt,
+        Pango.AttrType.VARIANT: Pango.AttrInt,
+        Pango.AttrType.STYLE: Pango.AttrInt,
+        Pango.AttrType.SCALE: Pango.AttrFloat,
+        Pango.AttrType.FAMILY: Pango.AttrString,
+        Pango.AttrType.FONT_DESC: Pango.AttrFontDesc,
+        Pango.AttrType.STRIKETHROUGH: Pango.AttrInt,
+        Pango.AttrType.BACKGROUND: Pango.AttrColor,
+        Pango.AttrType.FOREGROUND: Pango.AttrColor,
+        Pango.AttrType.RISE: Pango.AttrInt}
 
     attval_to_markup = {
-        'underline': {pango.UNDERLINE_SINGLE: 'single',
-                      pango.UNDERLINE_DOUBLE: 'double',
-                      pango.UNDERLINE_LOW: 'low',
-                      pango.UNDERLINE_NONE: 'none'
+        'underline': {Pango.Underline.SINGLE: 'single',
+                      Pango.Underline.DOUBLE: 'double',
+                      Pango.Underline.LOW: 'low',
+                      Pango.Underline.NONE: 'none'
                       },
-        'stretch': {pango.STRETCH_ULTRA_EXPANDED: 'ultraexpanded',
-                    pango.STRETCH_EXPANDED: 'expanded',
-                    pango.STRETCH_EXTRA_EXPANDED: 'extraexpanded',
-                    pango.STRETCH_EXTRA_CONDENSED: 'extracondensed',
-                    pango.STRETCH_ULTRA_CONDENSED: 'ultracondensed',
-                    pango.STRETCH_CONDENSED: 'condensed',
-                    pango.STRETCH_NORMAL: 'normal',
+        'stretch': {Pango.Stretch.ULTRA_EXPANDED: 'ultraexpanded',
+                    Pango.Stretch.EXPANDED: 'expanded',
+                    Pango.Stretch.EXTRA_EXPANDED: 'extraexpanded',
+                    Pango.Stretch.EXTRA_CONDENSED: 'extracondensed',
+                    Pango.Stretch.ULTRA_CONDENSED: 'ultracondensed',
+                    Pango.Stretch.CONDENSED: 'condensed',
+                    Pango.Stretch.NORMAL: 'normal',
                     },
-        'variant': {pango.VARIANT_NORMAL: 'normal',
-                    pango.VARIANT_SMALL_CAPS: 'smallcaps',
+        'variant': {Pango.Variant.NORMAL: 'normal',
+                    Pango.Variant.SMALL_CAPS: 'smallcaps',
                     },
-        'style': {pango.STYLE_NORMAL: 'normal',
-                  pango.STYLE_OBLIQUE: 'oblique',
-                  pango.STYLE_ITALIC: 'italic',
+        'style': {Pango.Style.NORMAL: 'normal',
+                  Pango.Style.OBLIQUE: 'oblique',
+                  Pango.Style.ITALIC: 'italic',
                   },
         'stikethrough': {1: 'true',
                          True: 'true',
@@ -105,16 +219,16 @@ class PangoBuffer(gtk.TextBuffer):
     def __init__(self):
         self.tagdict = {}
         self.tags = {}
-        gtk.TextBuffer.__init__(self)
+        GObject.GObject.__init__(self)
 
     def set_text(self, txt):
-        gtk.TextBuffer.set_text(self, "")
-        suc, self.parsed, self.txt, self.separator = pango.parse_markup(txt, -1, u'\x00')
+        Gtk.TextBuffer.set_text(self, "")
+        suc, self.parsed, self.txt, self.separator = Pango.parse_markup(txt, -1, u'\x00')
         if not suc:
             oldtxt = txt
             txt = saxutils.escape(txt)
             self.warn("Marked text is not correct. Escape %s to %s", oldtxt, txt)
-            suc, self.parsed, self.txt, self.separator = pango.parse_markup(txt, -1, u'\x00')
+            suc, self.parsed, self.txt, self.separator = Pango.parse_markup(txt, -1, u'\x00')
         self.attrIter = self.parsed.get_iterator()
         self.add_iter_to_buffer()
         while self.attrIter.next():
@@ -155,7 +269,7 @@ class PangoBuffer(gtk.TextBuffer):
                 a.start_index = start_index
                 a.end_index = end_index
                 a.klass = klass
-                if a.type == pango.ATTR_FOREGROUND:
+                if a.type == Pango.AttrType.FOREGROUND:
                     gdkcolor = self.pango_color_to_gdk(a.color)
                     key = 'foreground%s' % self.color_to_hex(gdkcolor)
                     if not key in self.tags:
@@ -164,7 +278,7 @@ class PangoBuffer(gtk.TextBuffer):
                         self.tagdict[self.tags[key]] = {}
                         self.tagdict[self.tags[key]]['foreground'] = "#%s" % self.color_to_hex(gdkcolor)
                     tags.append(self.tags[key])
-                if a.type == pango.ATTR_BACKGROUND:
+                if a.type == Pango.AttrType.BACKGROUND:
                     gdkcolor = self.pango_color_to_gdk(a.color)
                     key = 'background%s' % self.color_to_hex(gdkcolor)
                     if not key in self.tags:
@@ -262,7 +376,7 @@ class PangoBuffer(gtk.TextBuffer):
             start = self.get_start_iter()
         if not end:
             end = self.get_end_iter()
-        txt = unicode(gtk.TextBuffer.get_text(self, start, end, True))
+        txt = unicode(Gtk.TextBuffer.get_text(self, start, end, True))
         #Important step, split that no tags overlap
         tagdict = self.split_overlap(tagdict)
         cuts = {}
@@ -316,7 +430,7 @@ class PangoBuffer(gtk.TextBuffer):
         return attrs
 
     def pango_color_to_gdk(self, pc):
-        return gtk.gdk.Color(pc.red, pc.green, pc.blue)
+        return Gdk.Color(pc.red, pc.green, pc.blue)
 
     def color_to_hex(self, color):
         hexstring = ""
@@ -376,8 +490,8 @@ class PangoBuffer(gtk.TextBuffer):
 class InteractivePangoBuffer(PangoBuffer):
     def __init__(self, normal_button=None, toggle_widget_alist=[]):
         """
-        An interactive interface to allow marking up a gtk.TextBuffer.
-        txt is initial text, with markup.  buf is the gtk.TextBuffer
+        An interactive interface to allow marking up a Gtk.TextBuffer.
+        txt is initial text, with markup.  buf is the Gtk.TextBuffer
         normal_button is a widget whose clicked signal will make us normal
         toggle_widget_alist is a list that looks like this:
             [(widget,(font, attr)), (widget2, (font, attr))]
@@ -402,8 +516,8 @@ class InteractivePangoBuffer(PangoBuffer):
 
     def setup_widget_from_pango(self, widg, markupstring):
         """setup widget from a pango markup string"""
-        #font = pango.FontDescription(fontstring)
-        suc, a, t, s = pango.parse_markup(markupstring, -1, u'\x00')
+        #font = Pango.FontDescription(fontstring)
+        suc, a, t, s = Pango.parse_markup(markupstring, -1, u'\x00')
         ai = a.get_iterator()
         font, lang, attrs = ai.get_font()
 
@@ -479,7 +593,7 @@ class TitleEditor(Loggable):
 
         #Creat UI
         self._createUI()
-        self.textbuffer = gtk.TextBuffer()
+        self.textbuffer = Gtk.TextBuffer()
         self.pangobuffer = InteractivePangoBuffer()
         self.textarea.set_buffer(self.pangobuffer)
 
@@ -493,7 +607,7 @@ class TitleEditor(Loggable):
         self.pangobuffer.setup_widget_from_pango(self.bt["underline"], "<u>underline</u>")
 
     def _createUI(self):
-        builder = gtk.Builder()
+        builder = Gtk.Builder()
         builder.add_from_file(os.path.join(get_ui_dir(), "titleeditor.ui"))
         builder.connect_signals(self)
         self.widget = builder.get_object("box1")
@@ -545,14 +659,14 @@ class TitleEditor(Loggable):
         self.source.set_background(color_int)
 
     def _frontTextColorButtonCb(self, widget):
-        suc, a, t, s = pango.parse_markup("<span color='" + widget.get_color().to_string() + "'>color</span>", -1, u'\x00')
+        suc, a, t, s = Pango.parse_markup("<span color='" + widget.get_color().to_string() + "'>color</span>", -1, u'\x00')
         ai = a.get_iterator()
         font, lang, attrs = ai.get_font()
         tags = self.pangobuffer.get_tags_from_attrs(None, None, attrs)
         self.pangobuffer.apply_tag_to_selection(tags[0])
 
     def _backTextColorButtonCb(self, widget):
-        suc, a, t, s = pango.parse_markup("<span background='" + widget.get_color().to_string() + "'>color</span>", -1, u'\x00')
+        suc, a, t, s = Pango.parse_markup("<span background='" + widget.get_color().to_string() + "'>color</span>", -1, u'\x00')
         ai = a.get_iterator()
         font, lang, attrs = ai.get_font()
         tags = self.pangobuffer.get_tags_from_attrs(None, None, attrs)
@@ -563,7 +677,7 @@ class TitleEditor(Loggable):
         font_face = " ".join(font_desc[:-1])
         font_size = str(int(font_desc[-1]) * 1024)
         text = "<span face='" + font_face + "'><span size='" + font_size + "'>text</span></span>"
-        suc, a, t, s = pango.parse_markup(text, -1, u'\x00')
+        suc, a, t, s = Pango.parse_markup(text, -1, u'\x00')
         ai = a.get_iterator()
         font, lang, attrs = ai.get_font()
         tags = self.pangobuffer.get_tags_from_attrs(font, None, attrs)
@@ -612,7 +726,7 @@ class TitleEditor(Loggable):
             if hasattr(self.source, "get_background"):
                 self.bt["back_color"].set_visible(True)
                 color = self.source.get_background()
-                color = gtk.gdk.RGBA(color / 256 ** 2 % 256 / 255.,
+                color = Gdk.RGBA(color / 256 ** 2 % 256 / 255.,
                                      color / 256 ** 1 % 256 / 255.,
                                      color / 256 ** 0 % 256 / 255.,
                                      color / 256 ** 3 % 256 / 255.)
@@ -637,10 +751,10 @@ class TitleEditor(Loggable):
             for name, obj in self.settings.items():
                 if obj == updated_obj:
                     if name == "valignment":
-                        self.source.set_valignment(getattr(ges.TextVAlign, obj.get_active_id().upper()))
+                        self.source.set_valignment(getattr(GES.TextVAlign, obj.get_active_id().upper()))
                         self.settings["ypos"].set_visible(obj.get_active_id() == "position")
                     elif name == "halignment":
-                        self.source.set_halignment(getattr(ges.TextHAlign, obj.get_active_id().upper()))
+                        self.source.set_halignment(getattr(GES.TextHAlign, obj.get_active_id().upper()))
                         self.settings["xpos"].set_visible(obj.get_active_id() == "position")
                     elif name == "xpos":
                         self.settings["halignment"].set_active_id("position")
@@ -672,9 +786,9 @@ class TitleEditor(Loggable):
             self.set_sensitive(True)
 
     def _createCb(self, unused_button):
-        source = ges.TimelineTitleSource()
+        source = GES.TimelineTitleSource()
         source.set_text("")
-        source.set_duration(long(gst.SECOND * 5))
+        source.set_duration(long(Gst.SECOND * 5))
         #Show insert infobar only if created new source
         self.info_bar_insert.show()
         self.set_source(source, True)
@@ -707,10 +821,10 @@ class TitleEditor(Loggable):
         if event.button == 1:
             self._drag_events = [(event.x, event.y)]
             #Update drag by drag event change, but not too often
-            self.timeout = gobject.timeout_add(100, self.drag_update_event)
+            self.timeout = GObject.timeout_add(100, self.drag_update_event)
             #If drag goes out for 0.3 second, and do not come back, consider drag end
             self._drag_updated = True
-            self.timeout = gobject.timeout_add(1000, self.drag_posible_end_event)
+            self.timeout = GObject.timeout_add(1000, self.drag_posible_end_event)
 
     def drag_posible_end_event(self):
         if self._drag_updated:
@@ -742,7 +856,7 @@ class TitleEditor(Loggable):
             return False
 
     def drag_notify_event(self, widget, event):
-        if len(self._drag_events) > 0 and event.get_state() & gtk.gdk.BUTTON1_MASK:
+        if len(self._drag_events) > 0 and event.get_state() & Gdk.ModifierType.BUTTON1_MASK:
             self._drag_updated = True
             self._drag_events.append((event.x, event.y))
             st = self._drag_events[0]
diff --git a/pitivi/transitions.py b/pitivi/transitions.py
index 1e1333e..09b460e 100644
--- a/pitivi/transitions.py
+++ b/pitivi/transitions.py
@@ -20,11 +20,13 @@
 # Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 # Boston, MA 02110-1301, USA.
 
-import ges
 import glib
-import gtk
 import os
-import gobject
+
+from gi.repository import GES
+from gi.repository import Gtk
+from gi.repository import GObject
+from gi.repository import GdkPixbuf
 
 from gettext import gettext as _
 
@@ -39,17 +41,17 @@ from pitivi.utils.ui import SPACING, PADDING
  COL_ICON) = range(4)
 
 
-class TransitionsListWidget(Signallable, gtk.VBox, Loggable):
+class TransitionsListWidget(Signallable, Gtk.VBox, Loggable):
 
     def __init__(self, instance, uiman):
-        gtk.VBox.__init__(self)
+        GObject.GObject.__init__(self)
         Loggable.__init__(self)
         Signallable.__init__(self)
 
         self.app = instance
         self.element = None
         self._pixdir = os.path.join(get_pixmap_dir(), "transitions")
-        icon_theme = gtk.icon_theme_get_default()
+        icon_theme = Gtk.IconTheme.get_default()
         self._question_icon = icon_theme.load_icon("dialog-question", 48, 0)
 
         #Tooltip handling
@@ -57,30 +59,30 @@ class TransitionsListWidget(Signallable, gtk.VBox, Loggable):
         self._current_tooltip_icon = None
 
         #Searchbox
-        self.searchbar = gtk.HBox()
+        self.searchbar = Gtk.HBox()
         self.searchbar.set_spacing(SPACING)
         self.searchbar.set_border_width(3)  # Prevents being flush against the notebook
-        searchStr = gtk.Label(_("Search:"))
-        self.searchEntry = gtk.Entry()
-        self.searchEntry.set_icon_from_stock(gtk.ENTRY_ICON_SECONDARY, "gtk-clear")
-        self.searchbar.pack_start(searchStr, expand=False)
-        self.searchbar.pack_end(self.searchEntry, expand=True)
+        searchStr = Gtk.Label(label=_("Search:"))
+        self.searchEntry = Gtk.Entry()
+        self.searchEntry.set_icon_from_stock(Gtk.EntryIconPosition.SECONDARY, "gtk-clear")
+        self.searchbar.pack_start(searchStr, False, True, 0)
+        self.searchbar.pack_end(self.searchEntry, True, True, 0)
 
-        self.props_widgets = gtk.VBox()
-        borderTable = gtk.Table(rows=2, columns=3)
+        self.props_widgets = Gtk.VBox()
+        borderTable = Gtk.Table(rows=2, columns=3)
 
-        self.border_mode_normal = gtk.RadioButton(group=None, label=_("Normal"))
-        self.border_mode_loop = gtk.RadioButton(group=self.border_mode_normal, label=_("Loop"))
+        self.border_mode_normal = Gtk.RadioButton(group=None, label=_("Normal"))
+        self.border_mode_loop = Gtk.RadioButton(group=self.border_mode_normal, label=_("Loop"))
         self.border_mode_normal.set_active(True)
-        self.borderScale = gtk.HScale()
+        self.borderScale = Gtk.HScale()
         self.borderScale.set_draw_value(False)
 
-        borderTable.attach(self.border_mode_normal, 0, 1, 0, 1, xoptions=gtk.FILL, yoptions=gtk.FILL)
-        borderTable.attach(self.border_mode_loop, 1, 2, 0, 1, xoptions=gtk.FILL, yoptions=gtk.FILL)
+        borderTable.attach(self.border_mode_normal, 0, 1, 0, 1, xoptions=Gtk.AttachOptions.FILL, yoptions=Gtk.AttachOptions.FILL)
+        borderTable.attach(self.border_mode_loop, 1, 2, 0, 1, xoptions=Gtk.AttachOptions.FILL, yoptions=Gtk.AttachOptions.FILL)
         # The ypadding is a hack to make the slider widget align with the radiobuttons.
         borderTable.attach(self.borderScale, 2, 3, 0, 2, ypadding=SPACING * 2)
 
-        self.invert_checkbox = gtk.CheckButton(_("Reverse direction"))
+        self.invert_checkbox = Gtk.CheckButton(_("Reverse direction"))
         self.invert_checkbox.set_border_width(SPACING)
 
         self.props_widgets.add(borderTable)
@@ -89,8 +91,8 @@ class TransitionsListWidget(Signallable, gtk.VBox, Loggable):
         # Set the default values
         self._borderTypeChangedCb()
 
-        self.infobar = gtk.InfoBar()
-        txtlabel = gtk.Label()
+        self.infobar = Gtk.InfoBar()
+        txtlabel = Gtk.Label()
         txtlabel.set_padding(PADDING, PADDING)
         txtlabel.set_line_wrap(True)
         txtlabel.set_text(
@@ -100,16 +102,16 @@ class TransitionsListWidget(Signallable, gtk.VBox, Loggable):
         self.infobar.add(txtlabel)
         self.infobar.show_all()
 
-        self.storemodel = gtk.ListStore(str, str, str, gtk.gdk.Pixbuf)
+        self.storemodel = Gtk.ListStore(str, str, str, GdkPixbuf.Pixbuf)
 
-        self.iconview_scrollwin = gtk.ScrolledWindow()
-        self.iconview_scrollwin.set_shadow_type(gtk.SHADOW_ETCHED_IN)
+        self.iconview_scrollwin = Gtk.ScrolledWindow()
+        self.iconview_scrollwin.set_shadow_type(Gtk.ShadowType.ETCHED_IN)
         # FIXME: the "never" horizontal scroll policy in GTK2 messes up iconview
         # Re-enable this when we switch to GTK3
         # See also http://python.6.n6.nabble.com/Cannot-shrink-width-of-scrolled-textview-tp1945060.html
-        #self.iconview_scrollwin.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+        #self.iconview_scrollwin.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
 
-        self.iconview = gtk.IconView(self.storemodel)
+        self.iconview = Gtk.IconView(self.storemodel)
         self.iconview.set_pixbuf_column(COL_ICON)
         # We don't show text because we have a searchbar and the names are ugly
         #self.iconview.set_text_column(COL_NAME_TEXT)
@@ -129,12 +131,12 @@ class TransitionsListWidget(Signallable, gtk.VBox, Loggable):
         self.border_mode_loop.connect("released", self._borderTypeChangedCb)
 
         # Speed-up startup by only checking available transitions on idle
-        gobject.idle_add(self._loadAvailableTransitionsCb)
+        GObject.idle_add(self._loadAvailableTransitionsCb)
 
-        self.pack_start(self.infobar, expand=False)
-        self.pack_start(self.searchbar, expand=False)
-        self.pack_start(self.iconview_scrollwin, expand=True)
-        self.pack_start(self.props_widgets, expand=False)
+        self.pack_start(self.infobar, False, True, 0)
+        self.pack_start(self.searchbar, False, True, 0)
+        self.pack_start(self.iconview_scrollwin, True, True, 0)
+        self.pack_start(self.props_widgets, False, True, 0)
 
         # Create the filterModel for searching
         self.modelFilter = self.storemodel.filter_new()
@@ -195,14 +197,14 @@ class TransitionsListWidget(Signallable, gtk.VBox, Loggable):
         if widget == self.border_mode_loop:
             self.borderScale.set_range(50000, 500000)
             self.borderScale.clear_marks()
-            self.borderScale.add_mark(50000, gtk.POS_BOTTOM, _("Slow"))
-            self.borderScale.add_mark(200000, gtk.POS_BOTTOM, _("Fast"))
-            self.borderScale.add_mark(500000, gtk.POS_BOTTOM, _("Epileptic"))
+            self.borderScale.add_mark(50000, Gtk.PositionType.BOTTOM, _("Slow"))
+            self.borderScale.add_mark(200000, Gtk.PositionType.BOTTOM, _("Fast"))
+            self.borderScale.add_mark(500000, Gtk.PositionType.BOTTOM, _("Epileptic"))
         else:
             self.borderScale.set_range(0, 25000)
             self.borderScale.clear_marks()
-            self.borderScale.add_mark(0, gtk.POS_BOTTOM, _("Sharp"))
-            self.borderScale.add_mark(25000, gtk.POS_BOTTOM, _("Smooth"))
+            self.borderScale.add_mark(0, Gtk.PositionType.BOTTOM, _("Sharp"))
+            self.borderScale.add_mark(25000, Gtk.PositionType.BOTTOM, _("Smooth"))
 
     def _searchEntryChangedCb(self, entry):
         self.modelFilter.refilter()
@@ -266,7 +268,7 @@ class TransitionsListWidget(Signallable, gtk.VBox, Loggable):
         # Number 0 means "no transition", so we might just as well skip it.
         for i in range(1, 513):
             try:
-                transition = ges.VideoStandardTransitionType(i)
+                transition = GES.VideoStandardTransitionType(i)
             except ValueError:
                 # We hit a gap in the enum
                 pass
@@ -280,7 +282,7 @@ class TransitionsListWidget(Signallable, gtk.VBox, Loggable):
         # Now that the UI is fully ready, enable searching
         self.modelFilter.set_visible_func(self._setRowVisible, data=None)
         # Alphabetical/name sorting instead of based on the ID number
-        #self.storemodel.set_sort_column_id(COL_NAME_TEXT, gtk.SORT_ASCENDING)
+        #self.storemodel.set_sort_column_id(COL_NAME_TEXT, Gtk.SortType.ASCENDING)
 
     def activate(self, element):
         """
@@ -342,7 +344,7 @@ class TransitionsListWidget(Signallable, gtk.VBox, Loggable):
         name = transition_nick + ".png"
         icon = None
         try:
-            icon = gtk.gdk.pixbuf_new_from_file(os.path.join(self._pixdir, name))
+            icon = GdkPixbuf.Pixbuf.new_from_file(os.path.join(self._pixdir, name))
         except:
             icon = self._question_icon
         return icon
diff --git a/pitivi/undo/effect.py b/pitivi/undo/effect.py
index 79808ff..aaf9db4 100644
--- a/pitivi/undo/effect.py
+++ b/pitivi/undo/effect.py
@@ -23,7 +23,7 @@
 # the Free Software Foundation; either version 3, or (at your option)
 # any later version.
 
-import gobject
+from gi.repository import GObject
 
 from pitivi.undo.undo import UndoableAction
 from pitivi.effects import PROPS_TO_IGNORE
@@ -62,11 +62,11 @@ class EffectGstElementPropertyChangeTracker:
         if gst_element in self._tracked_effects:
             return
 
-        for prop in gobject.list_properties(gst_element):
+        for prop in GObject.list_properties(gst_element):
             gst_element.connect('notify::' + prop.name,
                                 self._propertyChangedCb,
                                 gst_element)
-            if prop.flags & gobject.PARAM_READABLE:
+            if prop.flags & GObject.PARAM_READABLE:
                 properties[prop.name] = gst_element.get_property(prop.name)
         self._tracked_effects[gst_element] = properties
 
@@ -134,16 +134,16 @@ class TrackEffectAdded(UndoableAction):
 
     def undo(self):
         element = self.track_object.getElement()
-        props = gobject.list_properties(element)
+        props = GObject.list_properties(element)
         self.effect_props = [(prop.name, element.get_property(prop.name))
                               for prop in props
-                              if prop.flags & gobject.PARAM_WRITABLE
+                              if prop.flags & GObject.PARAM_WRITABLE
                               and prop.name not in PROPS_TO_IGNORE]
-        gnl_props = gobject.list_properties(self.track_object.gnl_object)
+        gnl_props = GObject.list_properties(self.track_object.gnl_object)
         gnl_obj = self.track_object.gnl_object
         self.gnl_obj_props = [(prop.name, gnl_obj.get_property(prop.name))
                               for prop in gnl_props
-                              if prop.flags & gobject.PARAM_WRITABLE]
+                              if prop.flags & GObject.PARAM_WRITABLE]
 
         self.timeline_object.removeTrackObject(self.track_object)
         self.track_object.track.removeTrackObject(self.track_object)
@@ -167,17 +167,17 @@ class TrackEffectRemoved(UndoableAction):
 
     def do(self):
         element = self.track_object.getElement()
-        props = gobject.list_properties(element)
+        props = GObject.list_properties(element)
         self.effect_props = [(prop.name, element.get_property(prop.name))
                               for prop in props
-                              if prop.flags & gobject.PARAM_WRITABLE
+                              if prop.flags & GObject.PARAM_WRITABLE
                               and prop.name not in PROPS_TO_IGNORE]
 
-        gnl_props = gobject.list_properties(self.track_object.gnl_object)
+        gnl_props = GObject.list_properties(self.track_object.gnl_object)
         gnl_obj = self.track_object.gnl_object
         self.gnl_obj_props = [(prop.name, gnl_obj.get_property(prop.name))
                               for prop in gnl_props
-                              if prop.flags & gobject.PARAM_WRITABLE]
+                              if prop.flags & GObject.PARAM_WRITABLE]
 
         self.timeline_object.removeTrackObject(self.track_object)
         self.track_object.track.removeTrackObject(self.track_object)
diff --git a/pitivi/utils/extract.py b/pitivi/utils/extract.py
index 6c02c59..2c760a0 100644
--- a/pitivi/utils/extract.py
+++ b/pitivi/utils/extract.py
@@ -18,7 +18,7 @@
 # You should have received a copy of the GNU Lesser 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 gst
+# Boston, MA 02110-1301, USA.from gi.repository import Gst
 
 """
 Classes for extracting decoded contents of streams into Python
@@ -28,7 +28,7 @@ Code derived from ui/previewer.py.
 
 # FIXME reimplement after GES port
 
-import gst
+from gi.repository import Gst
 from collections import deque
 #from pitivi.elements.singledecodebin import SingleDecodeBin
 #from pitivi.elements.extractionsink import ExtractionSink
@@ -153,9 +153,9 @@ class RandomAccessAudioExtractor(RandomAccessExtractor):
         # This audiorate element ensures that the extracted raw-data
         # timeline matches the timestamps used for seeking, even if the
         # audio source has gaps or other timestamp abnormalities.
-        audiorate = gst.element_factory_make("audiorate")
-        conv = gst.element_factory_make("audioconvert")
-        q = gst.element_factory_make("queue")
+        audiorate = Gst.ElementFactory.make("audiorate")
+        conv = Gst.ElementFactory.make("audioconvert")
+        q = Gst.ElementFactory.make("queue")
         self.audioPipeline = pipeline({
             sbin: audiorate,
             audiorate: conv,
@@ -168,11 +168,11 @@ class RandomAccessAudioExtractor(RandomAccessExtractor):
         self._donecb_id = bus.connect("message::async-done",
                                       self._busMessageAsyncDoneCb)
 
-        self.audioPipeline.set_state(gst.STATE_PAUSED)
+        self.audioPipeline.set_state(Gst.State.PAUSED)
         # The audiopipeline.set_state() method does not take effect
         # immediately, but the extraction process (and in particular
         # self._startSegment) will not work properly until
-        # self.audioPipeline reaches the desired state (STATE_PAUSED).
+        # self.audioPipeline reaches the desired state (State.PAUSED).
         # To ensure that this is the case, we wait until the ASYNC_DONE
         # message is received before setting self._ready = True,
         # which enables extraction to proceed.
@@ -181,7 +181,7 @@ class RandomAccessAudioExtractor(RandomAccessExtractor):
         error, debug = message.parse_error()
         self.error("Event bus error: %s; %s", error, debug)
 
-        return gst.BUS_PASS
+        return Gst.BUS_PASS
 
     def _busMessageAsyncDoneCb(self, bus, message):
         self.debug("Pipeline is ready for seeking")
@@ -194,13 +194,13 @@ class RandomAccessAudioExtractor(RandomAccessExtractor):
         self.debug("processing segment with timestamp=%i and duration=%i",
                    timestamp, duration)
         res = self.audioPipeline.seek(1.0,
-            gst.FORMAT_TIME,
-            gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE,
-            gst.SEEK_TYPE_SET, timestamp,
-            gst.SEEK_TYPE_SET, timestamp + duration)
+            Gst.FORMAT_TIME,
+            Gst.SeekFlags.FLUSH | Gst.SeekFlags.ACCURATE,
+            Gst.SeekType.SET, timestamp,
+            Gst.SeekType.SET, timestamp + duration)
         if not res:
             self.warning("seek failed %s", timestamp)
-        self.audioPipeline.set_state(gst.STATE_PLAYING)
+        self.audioPipeline.set_state(Gst.State.PLAYING)
 
         return res
 
diff --git a/pitivi/utils/misc.py b/pitivi/utils/misc.py
index 59b3094..4b2f582 100644
--- a/pitivi/utils/misc.py
+++ b/pitivi/utils/misc.py
@@ -23,9 +23,9 @@
 # set of utility functions
 
 import sys
-import gobject
-import gst
-import gtk
+from gi.repository import GObject
+from gi.repository import Gst
+from gi.repository import Gtk
 import hashlib
 import os
 import struct
@@ -62,6 +62,16 @@ def between(a, b, c):
     return (a <= b) and (b <= c)
 
 
+def print_ns(time):
+    if time == Gst.CLOCK_TIME_NONE:
+        return "CLOCK_TIME_NONE"
+
+    return str(time / (Gst.SECOND * 60 * 60)) + ':' + \
+           str((time / (Gst.SECOND * 60)) % 60) + ':' + \
+           str((time / Gst.SECOND) % 60) + ':' + \
+           str(time % Gst.SECOND)
+
+
 def call_false(function, *args, **kwargs):
     """ Helper function for calling an arbitrary function once in the gobject
         mainloop.  Any positional or keyword arguments after the function will
@@ -78,14 +88,14 @@ def call_false(function, *args, **kwargs):
 
 def bin_contains(bin, element):
     """ Returns True if the bin contains the given element, the search is recursive """
-    if not isinstance(bin, gst.Bin):
+    if not isinstance(bin, Gst.Bin):
         return False
-    if not isinstance(element, gst.Element):
+    if not isinstance(element, Gst.Element):
         return False
     for elt in bin:
         if element is elt:
             return True
-        if isinstance(elt, gst.Bin) and bin_contains(elt, element):
+        if isinstance(elt, Gst.Bin) and bin_contains(elt, element):
             return True
     return False
 
@@ -127,9 +137,9 @@ def uri_is_valid(uri):
     @param uri: The location to check
     @type uri: C{URI}
     """
-    return (gst.uri_is_valid(uri) and
-            gst.uri_get_protocol(uri) == "file" and
-            len(os.path.basename(gst.uri_get_location(uri))) > 0)
+    return (Gst.uri_is_valid(uri) and
+            Gst.uri_get_protocol(uri) == "file" and
+            len(os.path.basename(Gst.uri_get_location(uri))) > 0)
 
 
 def uri_is_reachable(uri):
@@ -145,7 +155,7 @@ def uri_is_reachable(uri):
             # Translators: "non local" means the project is not stored
             # on a local filesystem
             _("%s doesn't yet handle non-local projects") % APPNAME)
-    return os.path.isfile(gst.uri_get_location(uri))
+    return os.path.isfile(Gst.uri_get_location(uri))
 
 
 def get_filesystem_encoding():
@@ -232,14 +242,14 @@ def get_controllable_properties(element):
     * The GstObject
     * The GParamspec
     """
-    log.debug("utils", "element %r, %d", element, isinstance(element, gst.Bin))
+    log.debug("utils", "element %r, %d", element, isinstance(element, Gst.Bin))
     res = []
-    if isinstance(element, gst.Bin):
+    if isinstance(element, Gst.Bin):
         for child in element.elements():
             res.extend(get_controllable_properties(child))
     else:
-        for prop in gobject.list_properties(element):
-            if prop.flags & gst.PARAM_CONTROLLABLE:
+        for prop in GObject.list_properties(element):
+            if prop.flags & Gst.PARAM_CONTROLLABLE:
                 log.debug("utils", "adding property %r", prop)
                 res.append((element, prop))
     return res
@@ -250,31 +260,31 @@ def linkDynamic(element, target):
     def pad_added(bin, pad, target):
         compatpad = target.get_compatible_pad(pad)
         if compatpad:
-            pad.link_full(compatpad, gst.PAD_LINK_CHECK_NOTHING)
+            pad.link_full(compatpad, Gst.PAD_LINK_CHECK_NOTHING)
     element.connect("pad-added", pad_added, target)
 
 
 def element_make_many(*args):
-    return tuple((gst.element_factory_make(arg) for arg in args))
+    return tuple((Gst.ElementFactory.make(arg) for arg in args))
 
 
 def pipeline(graph):
     E = graph.iteritems()
     V = graph.iterkeys()
-    p = gst.Pipeline()
+    p = Gst.Pipeline()
     p.add(*V)
     for u, v in E:
         if v:
             try:
                 u.link(v)
-            except gst.LinkError:
+            except Gst.LinkError:
                 linkDynamic(u, v)
     return p
 
 
 def filter_(caps):
-    f = gst.element_factory_make("capsfilter")
-    f.props.caps = gst.caps_from_string(caps)
+    f = Gst.ElementFactory.make("capsfilter")
+    f.props.caps = Gst.caps_from_string(caps)
     return f
 
 
@@ -400,7 +410,7 @@ def show_user_manual():
     time_now = int(time.time())
     for uri in (APPMANUALURL_OFFLINE, APPMANUALURL_ONLINE):
         try:
-            gtk.show_uri(None, uri, time_now)
+            Gtk.show_uri(None, uri, time_now)
             return
         except Exception, e:
             log.debug("utils", "Failed loading URI %s: %s", uri, e)
diff --git a/pitivi/utils/pipeline.py b/pitivi/utils/pipeline.py
index 96a7196..113a27d 100644
--- a/pitivi/utils/pipeline.py
+++ b/pitivi/utils/pipeline.py
@@ -28,10 +28,11 @@ High-level pipelines
 """
 from pitivi.utils.loggable import Loggable
 from pitivi.utils.signal import Signallable
+from pitivi.utils.misc import print_ns
 
-import gobject
-import gst
-import ges
+from gi.repository import GObject
+from gi.repository import Gst
+from gi.repository import GES
 
 
 # FIXME : define/document a proper hierarchy
@@ -72,13 +73,13 @@ class Seeker(Signallable, Loggable):
         self.format = None
         self._time = None
 
-    def seek(self, position, format=gst.FORMAT_TIME, on_idle=False):
+    def seek(self, position, format=Gst.Format.TIME, on_idle=False):
         self.format = format
         self.position = position
 
         if self.pending_seek_id is None:
             if on_idle:
-                gobject.idle_add(self._seekTimeoutCb)
+                GObject.idle_add(self._seekTimeoutCb)
             else:
                 self._seekTimeoutCb()
             self.pending_seek_id = self._scheduleSeek(self.timeout, self._seekTimeoutCb)
@@ -87,7 +88,7 @@ class Seeker(Signallable, Loggable):
         if self.pending_seek_id is None:
             self._time = time
             if on_idle:
-                gobject.idle_add(self._seekTimeoutCb, True)
+                GObject.idle_add(self._seekTimeoutCb, True)
             else:
                 self._seekTimeoutCb()
             self.pending_seek_id = self._scheduleSeek(self.timeout, self._seekTimeoutCb, True)
@@ -96,14 +97,14 @@ class Seeker(Signallable, Loggable):
         self.seekRelative(0, on_idle)
 
     def _scheduleSeek(self, timeout, callback, relative=False):
-        return gobject.timeout_add(timeout, callback, relative)
+        return GObject.timeout_add(timeout, callback, relative)
 
     def _seekTimeoutCb(self, relative=False):
         self.pending_seek_id = None
         if relative:
             try:
                 self.emit('seek-relative', self._time)
-            except:
+            except PipelineError:
                 self.error("Error while seeking %s relative", self._time)
                 # if an exception happened while seeking, properly
                 # reset ourselves
@@ -115,9 +116,9 @@ class Seeker(Signallable, Loggable):
             format, self.format = self.format, None
             try:
                 self.emit('seek', position, format)
-            except:
+            except PipelineError:
                 self.error("Error while seeking to position:%s format: %r",
-                          gst.TIME_ARGS(position), format)
+                          print_ns(position), format)
                 # if an exception happened while seeking, properly
                 # reset ourselves
                 return False
@@ -163,7 +164,7 @@ class SimplePipeline(Signallable, Loggable):
         self._listening = False  # for the position handler
         self._listeningInterval = 300  # default 300ms
         self._listeningSigId = 0
-        self._duration = gst.CLOCK_TIME_NONE
+        self._duration = Gst.CLOCK_TIME_NONE
 
     def release(self):
         """
@@ -179,7 +180,7 @@ class SimplePipeline(Signallable, Loggable):
         self._bus.disconnect_by_func(self._busMessageCb)
         self._bus.remove_signal_watch()
 
-        self._pipeline.setState(gst.STATE_NULL)
+        self._pipeline.setState(Gst.State.NULL)
         self._bus = None
 
     def flushSeek(self):
@@ -193,15 +194,15 @@ class SimplePipeline(Signallable, Loggable):
         """
         Set the L{Pipeline} to the given state.
 
-        @raises PipelineError: If the C{gst.Pipeline} could not be changed to
+        @raises PipelineError: If the C{Gst.Pipeline} could not be changed to
         the requested state.
         """
         self.debug("state:%r" % state)
         res = self._pipeline.set_state(state)
-        if res == gst.STATE_CHANGE_FAILURE:
+        if res == Gst.StateChangeReturn.FAILURE:
             # reset to NULL
-            self._pipeline.set_state(gst.STATE_NULL)
-            raise PipelineError("Failure changing state of the gst.Pipeline to %r, currently reset to NULL" % state)
+            self._pipeline.set_state(Gst.State.NULL)
+            raise PipelineError("Failure changing state of the Gst.Pipeline to %r, currently reset to NULL" % state)
 
     def getState(self):
         """
@@ -221,13 +222,13 @@ class SimplePipeline(Signallable, Loggable):
         """
         Sets the L{Pipeline} to PLAYING
         """
-        self.setState(gst.STATE_PLAYING)
+        self.setState(Gst.State.PLAYING)
 
     def pause(self):
         """
         Sets the L{Pipeline} to PAUSED
         """
-        self.setState(gst.STATE_PAUSED)
+        self.setState(Gst.State.PAUSED)
 
         # When the pipeline has been paused we need to update the
         # timeline/playhead position, as the 'position' signal
@@ -243,23 +244,23 @@ class SimplePipeline(Signallable, Loggable):
         """
         Sets the L{Pipeline} to READY
         """
-        self.setState(gst.STATE_READY)
+        self.setState(Gst.State.READY)
 
     def togglePlayback(self):
-        if self.getState() == gst.STATE_PLAYING:
+        if self.getState() == Gst.State.PLAYING:
             self.pause()
         else:
             self.play()
 
     #{ Position and Seeking methods
 
-    def getPosition(self, format=gst.FORMAT_TIME):
+    def getPosition(self, format=Gst.Format.TIME):
         """
         Get the current position of the L{Pipeline}.
 
         @param format: The format to return the current position in
-        @type format: C{gst.Format}
-        @return: The current position or gst.CLOCK_TIME_NONE
+        @type format: C{Gst.Format}
+        @return: The current position or Gst.CLOCK_TIME_NONE
         @rtype: L{long}
         @raise PipelineError: If the position couldn't be obtained.
         """
@@ -273,10 +274,10 @@ class SimplePipeline(Signallable, Loggable):
         if not res:
             raise PipelineError("Couldn't get position")
 
-        self.log("Got position %s" % gst.TIME_ARGS(cur))
+        self.log("Got position %s" % print_ns(cur))
         return cur
 
-    def getDuration(self, format=gst.FORMAT_TIME):
+    def getDuration(self, format=Gst.Format.TIME):
         """
         Get the duration of the C{Pipeline}.
         """
@@ -291,7 +292,7 @@ class SimplePipeline(Signallable, Loggable):
         if not res:
             raise PipelineError("Couldn't get duration")
 
-        self.log("Got duration %s" % gst.TIME_ARGS(dur))
+        self.log("Got duration %s" % print_ns(dur))
         if self._duration != dur:
             self.emit("duration-changed", dur)
 
@@ -317,7 +318,7 @@ class SimplePipeline(Signallable, Loggable):
         self._listening = True
         self._listeningInterval = interval
         # if we're in paused or playing, switch it on
-        self._listenToPosition(self.getState() == gst.STATE_PLAYING)
+        self._listenToPosition(self.getState() == Gst.State.PLAYING)
         return True
 
     def deactivatePositionListener(self):
@@ -332,7 +333,7 @@ class SimplePipeline(Signallable, Loggable):
     def _positionListenerCb(self):
         try:
             cur = self.getPosition()
-            if cur != gst.CLOCK_TIME_NONE:
+            if cur != Gst.CLOCK_TIME_NONE:
                 self.emit('position', cur)
         finally:
             return True
@@ -342,34 +343,34 @@ class SimplePipeline(Signallable, Loggable):
         # i.e. it does NOT check for current state
         if listen:
             if self._listening and self._listeningSigId == 0:
-                self._listeningSigId = gobject.timeout_add(self._listeningInterval,
+                self._listeningSigId = GObject.timeout_add(self._listeningInterval,
                     self._positionListenerCb)
         elif self._listeningSigId != 0:
-            gobject.source_remove(self._listeningSigId)
+            GObject.source_remove(self._listeningSigId)
             self._listeningSigId = 0
 
-    def simple_seek(self, position, format=gst.FORMAT_TIME):
+    def simple_seek(self, position, format=Gst.Format.TIME):
         """
         Seeks in the L{Pipeline} to the given position.
 
         @param position: Position to seek to
         @type position: L{long}
         @param format: The C{Format} of the seek position
-        @type format: C{gst.Format}
+        @type format: C{Gst.Format}
         @raise PipelineError: If seek failed
         """
-        if format == gst.FORMAT_TIME:
-            self.debug("position : %s" % gst.TIME_ARGS(position))
+        if format == Gst.Format.TIME:
+            self.debug("position : %s" % print_ns(position))
         else:
             self.debug("position : %d , format:%d" % (position, format))
 
         # clamp between [0, duration]
-        if format == gst.FORMAT_TIME:
+        if format == Gst.Format.TIME:
             position = max(0, min(position, self.getDuration()) - 1)
 
-        res = self._pipeline.seek(1.0, format, gst.SEEK_FLAG_FLUSH,
-                                  gst.SEEK_TYPE_SET, position,
-                                  gst.SEEK_TYPE_NONE, -1)
+        res = self._pipeline.seek(1.0, format, Gst.SeekFlags.FLUSH,
+                                  Gst.SeekType.SET, position,
+                                  Gst.SeekType.NONE, -1)
         if not res:
             self.debug("seeking failed")
             raise PipelineError("seek failed")
@@ -385,37 +386,37 @@ class SimplePipeline(Signallable, Loggable):
     ## Private methods
 
     def _busMessageCb(self, unused_bus, message):
-        if message.type == gst.MESSAGE_EOS:
+        if message.type == Gst.MessageType.EOS:
             self.pause()
             self.emit('eos')
-        elif message.type == gst.MESSAGE_STATE_CHANGED:
+        elif message.type == Gst.MessageType.STATE_CHANGED:
             prev, new, pending = message.parse_state_changed()
 
             if message.src == self._pipeline:
                 self.debug("Pipeline change state prev:%r, new:%r, pending:%r" % (prev, new, pending))
 
-                emit_state_change = pending == gst.STATE_VOID_PENDING
-                if prev == gst.STATE_READY and new == gst.STATE_PAUSED:
+                emit_state_change = pending == Gst.State.VOID_PENDING
+                if prev == Gst.State.READY and new == Gst.State.PAUSED:
                     # trigger duration-changed
                     try:
                         self.getDuration()
                     except PipelineError:
                         # no sinks??
                         pass
-                elif prev == gst.STATE_PAUSED and new == gst.STATE_PLAYING:
+                elif prev == Gst.State.PAUSED and new == Gst.State.PLAYING:
                     self._listenToPosition(True)
-                elif prev == gst.STATE_PLAYING and new == gst.STATE_PAUSED:
+                elif prev == Gst.State.PLAYING and new == Gst.State.PAUSED:
                     self._listenToPosition(False)
 
                 if emit_state_change:
                     self.emit('state-change', new)
 
-        elif message.type == gst.MESSAGE_ERROR:
+        elif message.type == Gst.MessageType.ERROR:
             error, detail = message.parse_error()
             self._handleErrorMessage(error, detail, message.src)
-        elif message.type == gst.MESSAGE_DURATION:
+        elif message.type == Gst.MessageType.DURATION:
             self.debug("Duration might have changed, querying it")
-            gobject.idle_add(self._queryDurationAsync)
+            GObject.idle_add(self._queryDurationAsync)
         else:
             if self._has_sync_bus_handler is False:
                 # Pass message async to the sync bus handler
@@ -434,7 +435,7 @@ class SimplePipeline(Signallable, Loggable):
         self.emit('error', error.message, detail)
 
     def _busSyncMessageHandler(self, unused_bus, message, unused_user_data):
-        if message.type == gst.MESSAGE_ELEMENT:
+        if message.type == Gst.MessageType.ELEMENT:
             if message.has_name('prepare-window-handle'):
                 # handle element message synchronously
                 self.emit('window-handle-message', message)
@@ -442,12 +443,12 @@ class SimplePipeline(Signallable, Loggable):
                 #FIXME wrong anotation dont allow none, reported as bug b681139
                 #self._bus.set_sync_handler(None, None)
                 self._has_sync_bus_handler = False
-        return gst.BUS_PASS
+        return Gst.BusSyncReply.PASS
 
 
-class Pipeline(ges.TimelinePipeline, SimplePipeline):
+class Pipeline(GES.TimelinePipeline, SimplePipeline):
     """
-    Helper to handle ges.TimelinePipeline through the SimplePipeline API
+    Helper to handle GES.TimelinePipeline through the SimplePipeline API
     and handle the Seeker properly
 
     Signals:
@@ -458,21 +459,21 @@ class Pipeline(ges.TimelinePipeline, SimplePipeline):
     """
 
     __gsignals__ = {
-        "state-change": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
-                        (gobject.TYPE_INT,)),
-        "position": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
-                        (gobject.TYPE_UINT64,)),
-        "duration-changed": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
-                        (gobject.TYPE_UINT64,)),
-        "eos": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
+        "state-change": (GObject.SignalFlags.RUN_LAST, None,
+                        (GObject.TYPE_INT,)),
+        "position": (GObject.SignalFlags.RUN_LAST, None,
+                        (GObject.TYPE_UINT64,)),
+        "duration-changed": (GObject.SignalFlags.RUN_LAST, None,
+                        (GObject.TYPE_UINT64,)),
+        "eos": (GObject.SignalFlags.RUN_LAST, None,
                         ()),
-        "error": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
-                        (gobject.TYPE_STRING, gobject.TYPE_STRING)),
-        "window-handle-message": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
-                        (gobject.TYPE_PYOBJECT,))}
+        "error": (GObject.SignalFlags.RUN_LAST, None,
+                        (GObject.TYPE_STRING, GObject.TYPE_STRING)),
+        "window-handle-message": (GObject.SignalFlags.RUN_LAST, None,
+                        (GObject.TYPE_PYOBJECT,))}
 
     def __init__(self, pipeline=None):
-        ges.TimelinePipeline.__init__(self)
+        GES.TimelinePipeline.__init__(self)
         SimplePipeline.__init__(self, self)
 
         self._seeker = Seeker()
@@ -501,12 +502,12 @@ class Pipeline(ges.TimelinePipeline, SimplePipeline):
         Seek backwards or forwards a certain amount of frames (frames_offset).
         This clamps the playhead to the project frames.
         """
-        cur_frame = int(round(self.getPosition() * framerate.num / float(gst.SECOND * framerate.denom), 2))
+        cur_frame = int(round(self.getPosition() * framerate.num / float(Gst.SECOND * framerate.denom), 2))
         new_frame = cur_frame + frames_offset
-        new_pos = long(new_frame * gst.SECOND * framerate.denom / framerate.num)
+        new_pos = long(new_frame * Gst.SECOND * framerate.denom / framerate.num)
         Loggable.info(self, "From frame %d to %d at %f fps, seek to %s s" % (cur_frame,
                     new_frame, framerate.num / framerate.denom,
-                    new_pos / float(gst.SECOND)))
+                    new_pos / float(Gst.SECOND)))
         self.simple_seek(new_pos)
 
     def _seekCb(self, ruler, position, format):
diff --git a/pitivi/utils/ripple_update_group.py b/pitivi/utils/ripple_update_group.py
index 0f16539..239f7a3 100644
--- a/pitivi/utils/ripple_update_group.py
+++ b/pitivi/utils/ripple_update_group.py
@@ -79,7 +79,7 @@ class RippleUpdateGroup(object):
         """Add a widget to the list of vertexes.
 
         @param widget: The vertex to be added.
-        @type widget: gtk.Widget
+        @type widget: Gtk.Widget
         @param signal: A signal of the widget to be monitored.
         @type signal: str
         @param update_func: A callable object called when the vertex is visited.
@@ -96,9 +96,9 @@ class RippleUpdateGroup(object):
         """Add a directional edge from widget_a to widget_b.
 
         @param widget_a: The source vertex.
-        @type widget_a: gtk.Widget
+        @type widget_a: Gtk.Widget
         @param widget_b: The target vertex.
-        @type widget_b: gtk.Widget
+        @type widget_b: Gtk.Widget
         @param predicate: A callable object returning whether the edge may be
             traversed.
         @type predicate: function
diff --git a/pitivi/utils/system.py b/pitivi/utils/system.py
index f34e013..d7fa2b0 100644
--- a/pitivi/utils/system.py
+++ b/pitivi/utils/system.py
@@ -160,7 +160,7 @@ class System(Signallable, Loggable):
         """send a message to the desktop to be displayed to the user
         @arg title: C{str} the title of the message
         @arg message: C{str} the body of the message
-        @arg icon: C{gtk.gdk.Pixbuf} icon to be shown with the message
+        @arg icon: C{GdkPixbuf.Pixbuf} icon to be shown with the message
         """
         self.debug("desktopMessage(): %s, %s" % title % message)
         pass
@@ -175,7 +175,7 @@ class FreedesktopOrgSystem(System):
     def __init__(self):
         System.__init__(self)
         # FIXME Notifications disabled for the time being
-        # pynotify.init(APPNAME)
+        # Notify.init(APPNAME)
 
     def desktopIsMesageable(self):
         return True
@@ -185,8 +185,8 @@ class FreedesktopOrgSystem(System):
         System.desktopMessage(title, message, icon)
 
         # FIXME Notifications disabled for the time being
-        #notification = pynotify.Notification(title, message)
-        #if icon != None and isinstance(icon, gtk.gdk.Pixbuf):
+        #notification = Notify.Notification(title, message)
+        #if icon != None and isinstance(icon, GdkPixbuf.Pixbuf):
             #notification.set_icon_from_pixbuf(icon)
         #notification.show()
 
@@ -275,7 +275,7 @@ if os.name == 'posix':
         try:
             # FIXME Disable notifications for the time being as it causes
             # various errors and the implementation is not done yet
-            #import pynotify
+            #from gi.repository import Notify
             import dbus
             system_ = GnomeSystem
         except:
@@ -285,7 +285,7 @@ if os.name == 'posix':
         try:
             # FIXME Disable notifications for the time being as it causes
             # various errors and the implementation is not done yet
-            # import pynotify
+            # from gi.repository import Notify
             system_ = FreedesktopOrgSystem
         except:
             pass
diff --git a/pitivi/utils/timeline.py b/pitivi/utils/timeline.py
index eb6383e..9ed402c 100644
--- a/pitivi/utils/timeline.py
+++ b/pitivi/utils/timeline.py
@@ -20,9 +20,9 @@
 # Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 # Boston, MA 02110-1301, USA.
 
-import ges
-import gtk
-import gst
+from gi.repository import GES
+from gi.repository import Gdk
+from gi.repository import Gst
 
 from pitivi.utils.loggable import Loggable
 from pitivi.utils.signal import Signallable
@@ -51,12 +51,12 @@ class TimelineError(Exception):
 
 class Selection(Signallable):
     """
-    A collection of L{ges.TimelineObject}.
+    A collection of L{GES.TimelineObject}.
 
     Signals:
-     - C{selection-changed} : The contents of the L{ges.Selection} changed.
+     - C{selection-changed} : The contents of the L{GES.Selection} changed.
 
-    @ivar selected: Set of selected L{ges.TrackObject}
+    @ivar selected: Set of selected L{GES.TrackObject}
     @type selected: C{list}
     """
 
@@ -69,7 +69,7 @@ class Selection(Signallable):
 
     def setToObj(self, obj, mode):
         """
-        Convenience method for calling L{setSelection} with a single L{ges.TimelineObject}
+        Convenience method for calling L{setSelection} with a single L{GES.TimelineObject}
 
         @see: L{setSelection}
         """
@@ -80,7 +80,7 @@ class Selection(Signallable):
         Add the given timeline_object to the selection.
 
         @param timeline_object: The object to add
-        @type timeline_object: L{ges.TimelineObject}
+        @type timeline_object: L{GES.TimelineObject}
         @raises TimelineError: If the object is already controlled by this
         Selection.
         """
@@ -105,7 +105,7 @@ class Selection(Signallable):
         selection = set()
         for obj in objs:
             # FIXME GES break, handle the fact that we have unlinked objects in GES
-            if isinstance(obj, ges.TrackObject):
+            if isinstance(obj, GES.TrackObject):
                 selection.add(obj.get_timeline_object())
             else:
                 selection.add(obj)
@@ -126,15 +126,14 @@ class Selection(Signallable):
 
         for obj in old_selection - self.selected:
             for tckobj in obj.get_track_objects():
-                if not isinstance(tckobj, ges.TrackEffect) and not isinstance(tckobj, ges.TrackTextOverlay):
+                if not isinstance(tckobj, GES.TrackEffect) and not isinstance(tckobj, GES.TrackTextOverlay):
                     tckobj.selected.selected = False
 
         for obj in self.selected - old_selection:
             for tckobj in obj.get_track_objects():
-                if not isinstance(tckobj, ges.TrackEffect) and not isinstance(tckobj, ges.TrackTextOverlay):
+                if not isinstance(tckobj, GES.TrackEffect) and not isinstance(tckobj, GES.TrackTextOverlay):
                     tckobj.selected.selected = True
 
-
         self.emit("selection-changed")
 
     def getSelectedTrackObjs(self):
@@ -154,7 +153,7 @@ class Selection(Signallable):
         track_effects = []
         for timeline_object in self.selected:
             for track in timeline_object.get_track_objects():
-                if isinstance(track, ges.TrackEffect):
+                if isinstance(track, GES.TrackEffect):
                     track_effects.append(track)
 
         return track_effects
@@ -185,18 +184,18 @@ class EditingContext(Signallable):
         @param focus: the TimelineObject or TrackObject which is to be the
         main target of interactive editing, such as the object directly under the
         mouse pointer
-        @type focus: L{ges.TimelineObject} or L{ges.TrackObject}
+        @type focus: L{GES.TimelineObject} or L{GES.TrackObject}
 
         @param timeline: the timeline to edit
-        @type timeline: instance of L{ges.Timeline}
+        @type timeline: instance of L{GES.Timeline}
 
         @param edge: The edge on which the edition will happen, this parametter
         can be change during the time using the same context.
-        @type edge: L{ges.Edge}
+        @type edge: L{GES.Edge}
 
         @param mode: The mode in which the edition will happen, this parametter
         can be change during the time using the same context.
-        @type mode: L{ges.EditMode}
+        @type mode: L{GES.EditMode}
 
         @param other: a set of objects which are the secondary targets of
         interactive editing, such as objects in the current selection.
@@ -213,7 +212,7 @@ class EditingContext(Signallable):
         other.difference_update(set((focus,)))
 
         self.other = other
-        if isinstance(focus, ges.TrackObject):
+        if isinstance(focus, GES.TrackObject):
             self.focus = focus.get_timeline_object()
         else:
             self.focus = focus
@@ -232,28 +231,28 @@ class EditingContext(Signallable):
 
     def setMode(self, mode):
         """Set the current editing mode.
-        @param mode: the editing mode. Must be a ges.EditMode
+        @param mode: the editing mode. Must be a GES.EditMode
         """
         self.mode = mode
 
     def editTo(self, position, priority):
         position = max(0, position)
-        if self.edge in [ges.EDGE_START, ges.EDGE_END]:
+        if self.edge in [GES.Edge.EDGE_START, GES.Edge.EDGE_END]:
             priority = -1
         else:
             priority = max(0, priority)
 
         res = self.focus.edit([], priority, self.mode, self.edge, long(position))
-        if res and self.mode == ges.EDIT_MODE_TRIM:
-            if self.edge == ges.EDGE_START:
+        if res and self.mode == GES.EditMode.EDIT_TRIM:
+            if self.edge == GES.Edge.EDGE_START:
                 self.emit("clip-trim", self.focus, self.focus.props.in_point)
-            elif self.edge == ges.EDGE_END:
+            elif self.edge == GES.Edge.EDGE_END:
                 self.emit("clip-trim", self.focus, self.focus.props.duration)
 
 
 #-------------------------- Interfaces ----------------------------------------#
 
-ARROW = gtk.gdk.Cursor(gtk.gdk.ARROW)
+ARROW = Gdk.Cursor.new(Gdk.CursorType.ARROW)
 
 
 class Controller(Loggable):
@@ -373,9 +372,9 @@ class Controller(Loggable):
     def key_press_event(self, item, target, event):
         self._event_common(item, target, event)
         kv = event.keyval
-        if kv in (gtk.keysyms.Shift_L, gtk.keysyms.Shift_R):
+        if kv in (Gdk.KEY_Shift_L, Gdk.KEY_Shift_R):
             self._shift_down = True
-        elif kv in (gtk.keysyms.Control_L, gtk.keysyms.Control_R):
+        elif kv in (Gdk.KEY_Control_L, Gdk.KEY_Control_R):
             self._control_down = True
         return self.key_press(kv)
 
@@ -383,9 +382,9 @@ class Controller(Loggable):
     def key_release_event(self, item, target, event):
         self._event_common(item, target, event)
         kv = event.keyval
-        if kv in (gtk.keysyms.Shift_L, gtk.keysyms.Shift_R):
+        if kv in (Gdk.KEY_Shift_L, Gdk.KEY_Shift_R):
             self._shift_down = False
-        elif kv in (gtk.keysyms.Control_L, gtk.keysyms.Control_R):
+        elif kv in (Gdk.KEY_Control_L, Gdk.KEY_Control_R):
             self._control_down = False
         return self.key_release(kv)
 
@@ -399,8 +398,8 @@ class Controller(Loggable):
             self._vadj = self._canvas.app.gui.timeline_ui.vadj
         self._last_event = event
         _, s = event.get_state()
-        self._shift_down = s & gtk.gdk.SHIFT_MASK
-        self._control_down = s & gtk.gdk.CONTROL_MASK
+        self._shift_down = s & Gdk.ModifierType.SHIFT_MASK
+        self._control_down = s & Gdk.ModifierType.CONTROL_MASK
 
     def _drag_start(self, item, target, event):
         self.drag_start(item, target, event)
@@ -468,7 +467,7 @@ class View(object):
 
     Controller = Controller
 
-    def __init__(self, instance, default_mode=ges.EDIT_MODE_NORMAL):
+    def __init__(self, instance, default_mode=GES.EditMode.EDIT_NORMAL):
         object.__init__(self)
         self._controller = self.Controller(instance, default_mode, view=self)
 
@@ -581,14 +580,14 @@ class Zoomable(object):
         """
         Returns the pixel equivalent in nanoseconds according to the zoomratio
         """
-        return long(pixel * gst.SECOND / cls.zoomratio)
+        return long(pixel * Gst.SECOND / cls.zoomratio)
 
     @classmethod
     def pixelToNsAt(cls, pixel, ratio):
         """
         Returns the pixel equivalent in nanoseconds according to the zoomratio
         """
-        return long(pixel * gst.SECOND / ratio)
+        return long(pixel * Gst.SECOND / ratio)
 
     @classmethod
     def nsToPixel(cls, duration):
@@ -598,9 +597,9 @@ class Zoomable(object):
         """
         ## DIE YOU CUNTMUNCH CLOCK_TIME_NONE UBER STUPIDITY OF CRACK BINDINGS !!!!!!
         if duration == 18446744073709551615 or \
-               long(duration) == long(gst.CLOCK_TIME_NONE):
+               long(duration) == long(Gst.CLOCK_TIME_NONE):
             return 0
-        return int((float(duration) / gst.SECOND) * cls.zoomratio)
+        return int((float(duration) / Gst.SECOND) * cls.zoomratio)
 
     @classmethod
     def _zoomChanged(cls):
diff --git a/pitivi/utils/ui.py b/pitivi/utils/ui.py
index 6c1d5bc..88652dd 100644
--- a/pitivi/utils/ui.py
+++ b/pitivi/utils/ui.py
@@ -26,8 +26,8 @@ UI utilities. This file contain the UI constants, and various functions and
 classes that help with UI drawing around the application
 """
 import glib
-import gst
-import gtk
+from gi.repository import Gst
+from gi.repository import Gtk
 import os
 import cairo
 
@@ -37,7 +37,7 @@ from itertools import izip
 from urllib import unquote
 from gettext import ngettext, gettext as _
 from decimal import Decimal
-from gst.pbutils import DiscovererVideoInfo, DiscovererAudioInfo, DiscovererStreamInfo
+from gi.repository.GstPbutils import DiscovererVideoInfo, DiscovererAudioInfo, DiscovererStreamInfo
 
 from pitivi.utils.loggable import doLog, ERROR
 
@@ -75,15 +75,15 @@ TYPE_PITIVI_AUDIO_TRANSITION = 30
 TYPE_PITIVI_VIDEO_TRANSITION = 31
 TYPE_PITIVI_LAYER_CONTROL = 32
 
-FILE_TARGET_ENTRY = gtk.TargetEntry.new("text/plain", Gtk.TargetFlags.OTHER_APP, TYPE_TEXT_PLAIN)
-URI_TARGET_ENTRY = gtk.TargetEntry.new("text/uri-list", 0, TYPE_URI_LIST)
-FILESOURCE_TARGET_ENTRY = gtk.TargetEntry.new("pitivi/file-source", 0, TYPE_PITIVI_FILESOURCE)
-EFFECT_TARGET_ENTRY = gtk.TargetEntry.new("pitivi/effect", 0, TYPE_PITIVI_EFFECT)
-AUDIO_EFFECT_TARGET_ENTRY = gtk.TargetEntry.new("pitivi/audio-effect", 0, TYPE_PITIVI_AUDIO_EFFECT)
-VIDEO_EFFECT_TARGET_ENTRY = gtk.TargetEntry.new("pitivi/video-effect", 0, TYPE_PITIVI_VIDEO_EFFECT)
-AUDIO_TRANSITION_TARGET_ENTRY = gtk.TargetEntry.new("pitivi/audio-transition", 0, TYPE_PITIVI_AUDIO_TRANSITION)
-VIDEO_TRANSITION_TARGET_ENTRY = gtk.TargetEntry.new("pitivi/video-transition", 0, TYPE_PITIVI_VIDEO_TRANSITION)
-LAYER_CONTROL_TARGET_ENTRY = gtk.TargetEntry.new("pitivi/layer-control", 0, TYPE_PITIVI_LAYER_CONTROL)
+FILE_TARGET_ENTRY = Gtk.TargetEntry.new("text/plain", Gtk.TargetFlags.OTHER_APP, TYPE_TEXT_PLAIN)
+URI_TARGET_ENTRY = Gtk.TargetEntry.new("text/uri-list", 0, TYPE_URI_LIST)
+FILESOURCE_TARGET_ENTRY = Gtk.TargetEntry.new("pitivi/file-source", 0, TYPE_PITIVI_FILESOURCE)
+EFFECT_TARGET_ENTRY = Gtk.TargetEntry.new("pitivi/effect", 0, TYPE_PITIVI_EFFECT)
+AUDIO_EFFECT_TARGET_ENTRY = Gtk.TargetEntry.new("pitivi/audio-effect", 0, TYPE_PITIVI_AUDIO_EFFECT)
+VIDEO_EFFECT_TARGET_ENTRY = Gtk.TargetEntry.new("pitivi/video-effect", 0, TYPE_PITIVI_VIDEO_EFFECT)
+AUDIO_TRANSITION_TARGET_ENTRY = Gtk.TargetEntry.new("pitivi/audio-transition", 0, TYPE_PITIVI_AUDIO_TRANSITION)
+VIDEO_TRANSITION_TARGET_ENTRY = Gtk.TargetEntry.new("pitivi/video-transition", 0, TYPE_PITIVI_VIDEO_TRANSITION)
+LAYER_CONTROL_TARGET_ENTRY = Gtk.TargetEntry.new("pitivi/layer-control", 0, TYPE_PITIVI_LAYER_CONTROL)
 
 
 # ---------------------- ARGB color helper-------------------------------------#
@@ -233,9 +233,9 @@ def time_to_string(value):
 
     Format HH:MM:SS.XXX
     """
-    if value == gst.CLOCK_TIME_NONE:
+    if value == Gst.CLOCK_TIME_NONE:
         return "--:--:--.---"
-    ms = value / gst.MSECOND
+    ms = value / Gst.MSECOND
     sec = ms / 1000
     ms = ms % 1000
     mins = sec / 60
@@ -249,7 +249,7 @@ def beautify_length(length):
     """
     Converts the given time in nanoseconds to a human readable string
     """
-    sec = length / gst.SECOND
+    sec = length / Gst.SECOND
     mins = sec / 60
     sec = sec % 60
     hours = mins / 60
@@ -301,7 +301,7 @@ def beautify_ETA(length):
     Converts the given time in nanoseconds to a fuzzy estimate,
     intended for progress ETAs, not to indicate a clip's duration.
     """
-    sec = length / gst.SECOND
+    sec = length / Gst.SECOND
     mins = sec / 60
     sec = int(sec % 60)
     hours = int(mins / 60)
@@ -345,7 +345,7 @@ def roundedrec(context, x, y, w, h, r=10):
 
 #--------------------- Gtk widget helpers ------------------------------------#
 def model(columns, data):
-    ret = gtk.ListStore(*columns)
+    ret = Gtk.ListStore(*columns)
     for datum in data:
         ret.append(datum)
     return ret
@@ -374,7 +374,7 @@ def get_value_from_model(model, key):
     for row in model:
         if row[1] == key:
             return str(row[0])
-    if isinstance(key, gst.Fraction):
+    if isinstance(key, Gst.Fraction):
         return "%.3f" % Decimal(float(key.num) / key.denom)
     return str(key)
 
@@ -382,18 +382,18 @@ def get_value_from_model(model, key):
 # FIXME This should into a special file
 frame_rates = model((str, object), (
     # Translators: fps is for frames per second
-    (_("%d fps") % 12, gst.Fraction(12.0, 1.0)),
-    (_("%d fps") % 15, gst.Fraction(15.0, 1.0)),
-    (_("%d fps") % 20, gst.Fraction(20.0, 1.0)),
-    (_("%.3f fps") % 23.976, gst.Fraction(24000.0, 1001.0)),
-    (_("%d fps") % 24, gst.Fraction(24.0, 1.0)),
-    (_("%d fps") % 25, gst.Fraction(25.0, 1.0)),
-    (_("%.2f fps") % 29.97, gst.Fraction(30000.0, 1001.0)),
-    (_("%d fps") % 30, gst.Fraction(30.0, 1.0)),
-    (_("%d fps") % 50, gst.Fraction(50.0, 1.0)),
-    (_("%.2f fps") % 59.94, gst.Fraction(60000.0, 1001.0)),
-    (_("%d fps") % 60, gst.Fraction(60.0, 1.0)),
-    (_("%d fps") % 120, gst.Fraction(120.0, 1.0)),
+    (_("%d fps") % 12, Gst.Fraction(12.0, 1.0)),
+    (_("%d fps") % 15, Gst.Fraction(15.0, 1.0)),
+    (_("%d fps") % 20, Gst.Fraction(20.0, 1.0)),
+    (_("%.3f fps") % 23.976, Gst.Fraction(24000.0, 1001.0)),
+    (_("%d fps") % 24, Gst.Fraction(24.0, 1.0)),
+    (_("%d fps") % 25, Gst.Fraction(25.0, 1.0)),
+    (_("%.2f fps") % 29.97, Gst.Fraction(30000.0, 1001.0)),
+    (_("%d fps") % 30, Gst.Fraction(30.0, 1.0)),
+    (_("%d fps") % 50, Gst.Fraction(50.0, 1.0)),
+    (_("%.2f fps") % 59.94, Gst.Fraction(60000.0, 1001.0)),
+    (_("%d fps") % 60, Gst.Fraction(60.0, 1.0)),
+    (_("%d fps") % 120, Gst.Fraction(120.0, 1.0)),
 ))
 
 audio_rates = model((str, int), (
@@ -419,27 +419,27 @@ audio_channels = model((str, int), (
 # FIXME: are we sure the following tables correct?
 
 pixel_aspect_ratios = model((str, object), (
-    (_("Square"), gst.Fraction(1, 1)),
-    (_("480p"), gst.Fraction(10, 11)),
-    (_("480i"), gst.Fraction(8, 9)),
-    (_("480p Wide"), gst.Fraction(40, 33)),
-    (_("480i Wide"), gst.Fraction(32, 27)),
-    (_("576p"), gst.Fraction(12, 11)),
-    (_("576i"), gst.Fraction(16, 15)),
-    (_("576p Wide"), gst.Fraction(16, 11)),
-    (_("576i Wide"), gst.Fraction(64, 45)),
+    (_("Square"), Gst.Fraction(1, 1)),
+    (_("480p"), Gst.Fraction(10, 11)),
+    (_("480i"), Gst.Fraction(8, 9)),
+    (_("480p Wide"), Gst.Fraction(40, 33)),
+    (_("480i Wide"), Gst.Fraction(32, 27)),
+    (_("576p"), Gst.Fraction(12, 11)),
+    (_("576i"), Gst.Fraction(16, 15)),
+    (_("576p Wide"), Gst.Fraction(16, 11)),
+    (_("576i Wide"), Gst.Fraction(64, 45)),
 ))
 
 display_aspect_ratios = model((str, object), (
-    (_("Standard (4:3)"), gst.Fraction(4, 3)),
-    (_("DV (15:11)"), gst.Fraction(15, 11)),
-    (_("DV Widescreen (16:9)"), gst.Fraction(16, 9)),
-    (_("Cinema (1.37)"), gst.Fraction(11, 8)),
-    (_("Cinema (1.66)"), gst.Fraction(166, 100)),
-    (_("Cinema (1.85)"), gst.Fraction(185, 100)),
-    (_("Anamorphic (2.35)"), gst.Fraction(235, 100)),
-    (_("Anamorphic (2.39)"), gst.Fraction(239, 100)),
-    (_("Anamorphic (2.4)"), gst.Fraction(24, 10)),
+    (_("Standard (4:3)"), Gst.Fraction(4, 3)),
+    (_("DV (15:11)"), Gst.Fraction(15, 11)),
+    (_("DV Widescreen (16:9)"), Gst.Fraction(16, 9)),
+    (_("Cinema (1.37)"), Gst.Fraction(11, 8)),
+    (_("Cinema (1.66)"), Gst.Fraction(166, 100)),
+    (_("Cinema (1.85)"), Gst.Fraction(185, 100)),
+    (_("Anamorphic (2.35)"), Gst.Fraction(235, 100)),
+    (_("Anamorphic (2.39)"), Gst.Fraction(239, 100)),
+    (_("Anamorphic (2.4)"), Gst.Fraction(24, 10)),
 ))
 
 
diff --git a/pitivi/utils/widgets.py b/pitivi/utils/widgets.py
index e6a5276..efac183 100644
--- a/pitivi/utils/widgets.py
+++ b/pitivi/utils/widgets.py
@@ -25,14 +25,15 @@ A collection of helper classes and routines for:
     * Creating UI from GstElement-s
 """
 
-import gobject
-import gtk
 import os
-import ges
 import re
 import sys
-import gst
-import pango
+
+from gi.repository import Gtk
+from gi.repository import Gdk
+from gi.repository import Gst
+from gi.repository import Pango
+from gi.repository import GObject
 
 from gettext import gettext as _
 
@@ -69,12 +70,12 @@ class DynamicWidget(object):
             self.setWidgetValue(self.default)
 
 
-class DefaultWidget(gtk.Label, DynamicWidget):
+class DefaultWidget(Gtk.Label, DynamicWidget):
 
     """When all hope fails...."""
 
     def __init__(self, default=None, *unused, **kw_unused):
-        gtk.Label.__init__(self, _("Implement Me"))
+        GObject.GObject.__init__(self, _("Implement Me"))
         DynamicWidget.__init__(self, default)
 
     def connectValueChanged(self, callback, *args):
@@ -87,44 +88,44 @@ class DefaultWidget(gtk.Label, DynamicWidget):
         return self.get_text()
 
 
-class TextWidget(gtk.HBox, DynamicWidget):
+class TextWidget(Gtk.HBox, DynamicWidget):
 
-    """A gtk.Entry which emits a value-changed signal only when its input is
+    """A Gtk.Entry which emits a value-changed signal only when its input is
     valid (matches the provided regex). If the input is invalid, a warning
     icon is displayed."""
 
     __gtype_name__ = 'TextWidget'
     __gsignals__ = {
         "value-changed": (
-            gobject.SIGNAL_RUN_LAST,
-            gobject.TYPE_NONE,
+            GObject.SignalFlags.RUN_LAST,
+            None,
             (),)
     }
 
-    __INVALID__ = gtk.gdk.Color(0xFFFF, 0, 0)
-    __NORMAL__ = gtk.gdk.Color(0, 0, 0)
+    __INVALID__ = Gdk.Color(0xFFFF, 0, 0)
+    __NORMAL__ = Gdk.Color(0, 0, 0)
 
     def __init__(self, matches=None, choices=None, default=None):
         if not default:
             # In the case of text widgets, a blank default is an empty string
             default = ""
 
-        gtk.HBox.__init__(self)
+        GObject.GObject.__init__(self)
         DynamicWidget.__init__(self, default)
 
         self.set_border_width(0)
         self.set_spacing(0)
         if choices:
-            self.combo = gtk.combo_box_entry_new_text()
-            self.text = self.combo.child
+            self.combo = Gtk.combo_box_entry_new_text()
+            self.text = self.combo.get_child()
             self.combo.show()
-            self.pack_start(self.combo)
+            self.pack_start(self.combo, True, True, 0)
             for choice in choices:
                 self.combo.append_text(choice)
         else:
-            self.text = gtk.Entry()
+            self.text = Gtk.Entry()
             self.text.show()
-            self.pack_start(self.text)
+            self.pack_start(self.text, True, True, 0)
         self.matches = None
         self.last_valid = None
         self.valid = False
@@ -165,7 +166,7 @@ class TextWidget(gtk.HBox, DynamicWidget):
                 self.valid = True
             else:
                 if self.valid:
-                    self.text.set_icon_from_stock(1, gtk.STOCK_DIALOG_WARNING)
+                    self.text.set_icon_from_stock(1, Gtk.STOCK_DIALOG_WARNING)
                 self.valid = False
         elif self.send_signal:
             self.emit("value-changed")
@@ -183,37 +184,37 @@ class TextWidget(gtk.HBox, DynamicWidget):
         self.text.set_width_chars(width)
 
 
-class NumericWidget(gtk.HBox, DynamicWidget):
+class NumericWidget(Gtk.HBox, DynamicWidget):
 
-    """A gtk.HScale and a gtk.SpinButton which share an adjustment. The
+    """A Gtk.HScale and a Gtk.SpinButton which share an adjustment. The
     SpinButton is always displayed, while the HScale only appears if both
     lower and upper bounds are defined"""
 
     def __init__(self, upper=None, lower=None, default=None):
-        gtk.HBox.__init__(self)
+        GObject.GObject.__init__(self)
         DynamicWidget.__init__(self, default)
 
         self.spacing = SPACING
-        self.adjustment = gtk.Adjustment()
+        self.adjustment = Gtk.Adjustment()
         self.upper = upper
         self.lower = lower
         self._type = None
         if (upper != None) and (lower != None) and\
             (upper < 5000) and (lower > -5000):
-            self.slider = gtk.HScale(self.adjustment)
+            self.slider = Gtk.HScale(self.adjustment)
             self.pack_start(self.slider, fill=True, expand=True)
             self.slider.show()
             self.slider.props.draw_value = False
 
         if upper is None:
-            upper = gobject.G_MAXDOUBLE
+            upper = GObject.G_MAXDOUBLE
         if lower is None:
-            lower = gobject.G_MINDOUBLE
+            lower = GObject.G_MINDOUBLE
         range = upper - lower
         self.adjustment.props.lower = lower
         self.adjustment.props.upper = upper
-        self.spinner = gtk.SpinButton(adjustment=self.adjustment)
-        self.pack_end(self.spinner, expand=not hasattr(self, 'slider'))
+        self.spinner = Gtk.SpinButton(adjustment=self.adjustment)
+        self.pack_end(self.spinner, fille=True, expand=not hasattr(self, 'slider'), padding=0)
         self.spinner.show()
 
     def connectValueChanged(self, callback, *args):
@@ -235,7 +236,7 @@ class NumericWidget(gtk.HBox, DynamicWidget):
             step = 1.0
             page = 10.0
         elif type_ == float:
-            minimum, maximum = (gobject.G_MINDOUBLE, gobject.G_MAXDOUBLE)
+            minimum, maximum = (GObject.G_MINDOUBLE, GObject.G_MAXDOUBLE)
             step = 0.01
             page = 0.1
             self.spinner.props.digits = 2
@@ -285,7 +286,7 @@ class TimeWidget(TextWidget, DynamicWidget):
 
 class FractionWidget(TextWidget, DynamicWidget):
 
-    """A gtk.ComboBoxEntry """
+    """A Gtk.ComboBoxEntry """
 
     fraction_regex = re.compile(
         "^([0-9]*(\.[0-9]+)?)(([:/][0-9]*(\.[0-9]+)?)|M)?$")
@@ -340,7 +341,7 @@ class FractionWidget(TextWidget, DynamicWidget):
         if type(value) is str:
             value = self._parseText(value)
         elif not hasattr(value, "denom"):
-            value = gst.Fraction(value)
+            value = Gst.Fraction(value)
         if (value.denom / 1001) == 1:
             text = "%gM" % (value.num / 1000)
         else:
@@ -351,7 +352,7 @@ class FractionWidget(TextWidget, DynamicWidget):
     def getWidgetValue(self):
         if self.last_valid:
             return self._parseText(self.last_valid)
-        return gst.Fraction(1, 1)
+        return Gst.Fraction(1, 1)
 
     def _parseText(self, text):
         match = self.fraction_regex.match(text)
@@ -366,15 +367,15 @@ class FractionWidget(TextWidget, DynamicWidget):
                 denom = 1001
             elif groups[2][1:]:
                 denom = float(groups[2][1:])
-        return gst.Fraction(num, denom)
+        return Gst.Fraction(num, denom)
 
 
-class ToggleWidget(gtk.CheckButton, DynamicWidget):
+class ToggleWidget(Gtk.CheckButton, DynamicWidget):
 
-    """A gtk.CheckButton which supports the DynamicWidget interface."""
+    """A Gtk.CheckButton which supports the DynamicWidget interface."""
 
     def __init__(self, default=None):
-        gtk.CheckButton.__init__(self)
+        GObject.GObject.__init__(self)
         DynamicWidget.__init__(self, default)
 
     def connectValueChanged(self, callback, *args):
@@ -387,23 +388,23 @@ class ToggleWidget(gtk.CheckButton, DynamicWidget):
         return self.get_active()
 
 
-class ChoiceWidget(gtk.HBox, DynamicWidget):
+class ChoiceWidget(Gtk.HBox, DynamicWidget):
 
     """Abstractly, represents a choice between a list of named values. The
     association between value names and values is arbitrary. The current
-    implementation uses a gtk.ComboBoxText for simplicity."""
+    implementation uses a Gtk.ComboBoxText for simplicity."""
 
     def __init__(self, choices, default=None):
-        gtk.HBox.__init__(self)
+        GObject.GObject.__init__(self)
         DynamicWidget.__init__(self, default)
         self.choices = None
         self.values = None
-        self.contents = gtk.ComboBoxText()
-        self.pack_start(self.contents)
+        self.contents = Gtk.ComboBoxText()
+        self.pack_start(self.contents, True, True, 0)
         self.setChoices(choices)
         self.contents.show()
         cell = self.contents.get_cells()[0]
-        cell.props.ellipsize = pango.ELLIPSIZE_END
+        cell.props.ellipsize = Pango.EllipsizeMode.END
 
     def connectValueChanged(self, callback, *args):
         return self.contents.connect("changed", callback, *args)
@@ -420,7 +421,7 @@ class ChoiceWidget(gtk.HBox, DynamicWidget):
     def setChoices(self, choices):
         self.choices = [choice[0] for choice in choices]
         self.values = [choice[1] for choice in choices]
-        m = gtk.ListStore(str)
+        m = Gtk.ListStore(str)
         self.contents.set_model(m)
         for choice, value in choices:
             self.contents.append_text(_(choice))
@@ -430,7 +431,7 @@ class ChoiceWidget(gtk.HBox, DynamicWidget):
             self.contents.set_sensitive(True)
 
 
-class PresetChoiceWidget(gtk.HBox, DynamicWidget):
+class PresetChoiceWidget(Gtk.HBox, DynamicWidget):
 
     """A popup which manages preset settings on a group of widgets supporting
     the dynamic interface"""
@@ -469,7 +470,7 @@ class PresetChoiceWidget(gtk.HBox, DynamicWidget):
             return [w.getWidgetValue() for w in self.widgets if w]
 
     def __init__(self, presets, default=None):
-        gtk.HBox.__init__(self)
+        GObject.GObject.__init__(self)
         DynamicWidget.__init__(self, default)
         self._block_update = False
         self._widget_map = None
@@ -478,16 +479,16 @@ class PresetChoiceWidget(gtk.HBox, DynamicWidget):
         presets.connect("preset-added", self._presetAdded)
         presets.connect("preset-removed", self._presetRemoved)
 
-        self.combo = gtk.combo_box_new_text()
+        self.combo = Gtk.ComboBoxText()
         self.combo.set_row_separator_func(self._sep_func)
         for preset in presets:
             self.combo.append_text(preset[0])
         self.combo.append_text("-")
         self.combo.append_text(_("Custom"))
-        self.pack_start(self.combo)
+        self.pack_start(self.combo, True, True, 0)
         self._custom_row = len(presets) + 1
 
-        save_button = gtk.Button(stock=gtk.STOCK_SAVE)
+        save_button = Gtk.Button(stock=Gtk.STOCK_SAVE)
         self._save_button = save_button
         self.pack_start(save_button, False, False)
         save_button.connect("clicked", self._savePreset)
@@ -507,16 +508,16 @@ class PresetChoiceWidget(gtk.HBox, DynamicWidget):
         self._custom_row -= 1
 
     def _savePreset(self, unused_button):
-        d = gtk.Dialog(_("Save Preset"), None, gtk.DIALOG_MODAL,
-            buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE,
-                gtk.RESPONSE_OK))
-        input = gtk.Entry()
+        d = Gtk.Dialog(_("Save Preset"), None, Gtk.DialogFlags.MODAL,
+            buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_SAVE,
+                Gtk.ResponseType.OK))
+        input = Gtk.Entry()
         ca = d.get_content_area()
-        ca.pack_start(input)
+        ca.pack_start(input, True, True, 0)
         input.show()
         response = d.run()
 
-        if response == gtk.RESPONSE_OK:
+        if response == Gtk.ResponseType.OK:
             name = input.get_text()
             values = self._widget_map.unmap()
             self.presets.addPreset(name, values)
@@ -556,26 +557,26 @@ class PresetChoiceWidget(gtk.HBox, DynamicWidget):
         self.combo.set_active(preset_index)
 
 
-class PathWidget(gtk.FileChooserButton, DynamicWidget):
+class PathWidget(Gtk.FileChooserButton, DynamicWidget):
 
-    """A gtk.FileChooserButton which supports the DynamicWidget interface."""
+    """A Gtk.FileChooserButton which supports the DynamicWidget interface."""
 
     __gtype_name__ = 'PathWidget'
 
     __gsignals__ = {
-        "value-changed": (gobject.SIGNAL_RUN_LAST,
-            gobject.TYPE_NONE,
+        "value-changed": (GObject.SignalFlags.RUN_LAST,
+            None,
             ()),
     }
 
-    def __init__(self, action=gtk.FILE_CHOOSER_ACTION_OPEN, default=None):
+    def __init__(self, action=Gtk.FileChooserAction.OPEN, default=None):
         DynamicWidget.__init__(self, default)
-        self.dialog = gtk.FileChooserDialog(
+        self.dialog = Gtk.FileChooserDialog(
             action=action,
-            buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_CLOSE,
-             gtk.RESPONSE_CLOSE))
-        self.dialog.set_default_response(gtk.RESPONSE_OK)
-        gtk.FileChooserButton.__init__(self, self.dialog)
+            buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_CLOSE,
+             Gtk.ResponseType.CLOSE))
+        self.dialog.set_default_response(Gtk.ResponseType.OK)
+        GObject.GObject.__init__(self, self.dialog)
         self.set_title(_("Choose..."))
         self.dialog.connect("response", self._responseCb)
         self.uri = ""
@@ -591,16 +592,16 @@ class PathWidget(gtk.FileChooserButton, DynamicWidget):
         return self.uri
 
     def _responseCb(self, unused_dialog, response):
-        if response == gtk.RESPONSE_CLOSE:
+        if response == Gtk.ResponseType.CLOSE:
             self.uri = self.get_uri()
             self.emit("value-changed")
             self.dialog.hide()
 
 
-class ColorWidget(gtk.ColorButton, DynamicWidget):
+class ColorWidget(Gtk.ColorButton, DynamicWidget):
 
     def __init__(self, value_type=str, default=None):
-        gtk.ColorButton.__init__(self)
+        GObject.GObject.__init__(self)
         DynamicWidget.__init__(self, default)
         self.value_type = value_type
         self.set_use_alpha(True)
@@ -613,11 +614,11 @@ class ColorWidget(gtk.ColorButton, DynamicWidget):
         alpha = 0xFFFF
 
         if type_ is str:
-            color = gtk.gdk.Color(value)
+            color = Gdk.Color(value)
         elif (type_ is int) or (type_ is long):
             red, green, blue, alpha = unpack_color(value)
-            color = gtk.gdk.Color(red, green, blue)
-        elif type_ is gtk.gdk.Color:
+            color = Gdk.Color(red, green, blue)
+        elif type_ is Gdk.Color:
             color = value
         else:
             raise TypeError("%r is not something we can convert to a color" %
@@ -632,15 +633,15 @@ class ColorWidget(gtk.ColorButton, DynamicWidget):
             return pack_color_32(color.red, color.green, color.blue, alpha)
         if self.value_type is long:
             return pack_color_64(color.red, color.green, color.blue, alpha)
-        elif self.value_type is gtk.gdk.Color:
+        elif self.value_type is Gdk.Color:
             return color
         return color.to_string()
 
 
-class FontWidget(gtk.FontButton, DynamicWidget):
+class FontWidget(Gtk.FontButton, DynamicWidget):
 
     def __init__(self, default=None):
-        gtk.FontButton.__init__(self)
+        GObject.GObject.__init__(self)
         DynamicWidget.__init__(self, default)
         self.set_use_font(True)
 
@@ -654,10 +655,10 @@ class FontWidget(gtk.FontButton, DynamicWidget):
         return self.get_font_name()
 
 
-class ResolutionWidget(gtk.HBox, DynamicWidget):
+class ResolutionWidget(Gtk.HBox, DynamicWidget):
 
     def __init__(self, default=None):
-        gtk.HBox.__init__(self)
+        GObject.GObject.__init__(self)
         DynamicWidget.__init__(self, default)
         self.props.spacing = SPACING
 
@@ -665,9 +666,9 @@ class ResolutionWidget(gtk.HBox, DynamicWidget):
         self.dheight = 0
         self.dwidthWidget = NumericWidget(lower=0)
         self.dheightWidget = NumericWidget(lower=0)
-        self.pack_start(self.dwidthWidget)
-        self.pack_start(gtk.Label("x"))
-        self.pack_start(self.dheightWidget)
+        self.pack_start(self.dwidthWidget, True, True, 0)
+        self.pack_start(Gtk.Label("x", True, True, 0))
+        self.pack_start(self.dheightWidget, True, True, 0)
         self.setWidgetValue((320, 240))
         self.show_all()
 
@@ -705,27 +706,27 @@ if __name__ == '__main__':
         (ColorWidget, 0x336699FF, (int,)),
         (FontWidget, "Sans 9", ()),
         (FractionWidget, "30M",
-            (gst.FractionRange(gst.Fraction(1, 1),
-                gst.Fraction(30000, 1001)),)),
-        (FractionWidget, gst.Fraction(25000, 1001),
+            (Gst.FractionRange(Gst.Fraction(1, 1),
+                Gst.Fraction(30000, 1001)),)),
+        (FractionWidget, Gst.Fraction(25000, 1001),
             (
-                gst.FractionRange(
-                    gst.Fraction(1, 1),
-                    gst.Fraction(30000, 1001)
+                Gst.FractionRange(
+                    Gst.Fraction(1, 1),
+                    Gst.Fraction(30000, 1001)
                 ),
-                ("25:1", gst.Fraction(30, 1), "30M", ),
+                ("25:1", Gst.Fraction(30, 1), "30M", ),
             )
         ),
     )
 
-    W = gtk.Window()
-    v = gtk.VBox()
-    t = gtk.Table()
+    W = Gtk.Window()
+    v = Gtk.VBox()
+    t = Gtk.Table()
 
     for y, (klass, default, args) in enumerate(widgets):
         w = klass(*args)
         w.setWidgetValue(default)
-        l = gtk.Label(str(w.getWidgetValue()))
+        l = Gtk.Label(label=str(w.getWidgetValue()))
         w.connectValueChanged(valueChanged, w, l)
         w.show()
         l.show()
@@ -735,13 +736,13 @@ if __name__ == '__main__':
 
     W.add(t)
     W.show()
-    gtk.main()
+    Gtk.main()
 
 
 def make_property_widget(unused_element, prop, value=None):
     """ Creates a Widget for the given element property """
     # FIXME : implement the case for flags
-    type_name = gobject.type_name(prop.value_type.fundamental)
+    type_name = GObject.type_name(prop.value_type.fundamental)
 
     if value == None:
         value = prop.default_value
@@ -775,13 +776,13 @@ def make_property_widget(unused_element, prop, value=None):
     return widget
 
 
-class GstElementSettingsWidget(gtk.VBox, Loggable):
+class GstElementSettingsWidget(Gtk.VBox, Loggable):
     """
-    Widget to view/modify properties of a gst.Element
+    Widget to view/modify properties of a Gst.Element
     """
 
     def __init__(self):
-        gtk.VBox.__init__(self)
+        GObject.GObject.__init__(self)
         Loggable.__init__(self)
         self.element = None
         self.ignore = None
@@ -813,20 +814,20 @@ class GstElementSettingsWidget(gtk.VBox, Loggable):
             is_effect = True
             props = [prop for prop in self.element.list_children_properties() if not prop.name in self.ignore]
         else:
-            props = [prop for prop in gobject.list_properties(self.element) if not prop.name in self.ignore]
+            props = [prop for prop in GObject.list_properties(self.element) if not prop.name in self.ignore]
         if not props:
-            table = gtk.Table(rows=1, columns=1)
-            widget = gtk.Label(_("No properties."))
+            table = Gtk.Table(rows=1, columns=1)
+            widget = Gtk.Label(label=_("No properties."))
             widget.set_sensitive(False)
-            table.attach(widget, 0, 1, 0, 1, yoptions=gtk.FILL)
-            self.pack_start(table)
+            table.attach(widget, 0, 1, 0, 1, yoptions=Gtk.AttachOptions.FILL)
+            self.pack_start(table, True, True, 0)
             self.show_all()
             return
 
         if default_btn:
-            table = gtk.Table(rows=len(props), columns=3)
+            table = Gtk.Table(rows=len(props), columns=3)
         else:
-            table = gtk.Table(rows=len(props), columns=2)
+            table = Gtk.Table(rows=len(props), columns=2)
 
         table.set_row_spacings(SPACING)
         table.set_col_spacings(SPACING)
@@ -834,8 +835,8 @@ class GstElementSettingsWidget(gtk.VBox, Loggable):
 
         y = 0
         for prop in props:
-            if not prop.flags & gobject.PARAM_WRITABLE\
-              or not prop.flags & gobject.PARAM_READABLE:
+            if not prop.flags & GObject.PARAM_WRITABLE\
+              or not prop.flags & GObject.PARAM_READABLE:
                 continue
 
             if is_effect:
@@ -849,12 +850,12 @@ class GstElementSettingsWidget(gtk.VBox, Loggable):
             widget = make_property_widget(self.element, prop, prop_value)
             if isinstance(widget, ToggleWidget):
                 widget.set_label(prop.nick)
-                table.attach(widget, 0, 2, y, y + 1, yoptions=gtk.FILL)
+                table.attach(widget, 0, 2, y, y + 1, yoptions=Gtk.AttachOptions.FILL)
             else:
-                label = gtk.Label(prop.nick + ":")
+                label = Gtk.Label(label=prop.nick + ":")
                 label.set_alignment(0.0, 0.5)
-                table.attach(label, 0, 1, y, y + 1, xoptions=gtk.FILL, yoptions=gtk.FILL)
-                table.attach(widget, 1, 2, y, y + 1, yoptions=gtk.FILL)
+                table.attach(label, 0, 1, y, y + 1, xoptions=Gtk.AttachOptions.FILL, yoptions=Gtk.AttachOptions.FILL)
+                table.attach(widget, 1, 2, y, y + 1, yoptions=Gtk.AttachOptions.FILL)
 
             if hasattr(prop, 'blurb'):
                 widget.set_tooltip_text(prop.blurb)
@@ -864,22 +865,22 @@ class GstElementSettingsWidget(gtk.VBox, Loggable):
             # The "reset to default" button associated with this property
             if default_btn:
                 button = self._getResetToDefaultValueButton(prop, widget)
-                table.attach(button, 2, 3, y, y + 1, xoptions=gtk.FILL, yoptions=gtk.FILL)
+                table.attach(button, 2, 3, y, y + 1, xoptions=Gtk.AttachOptions.FILL, yoptions=Gtk.AttachOptions.FILL)
                 self.buttons[button] = widget
             self.element.connect('notify::' + prop.name, self._propertyChangedCb, widget)
 
             y += 1
 
-        self.pack_start(table)
+        self.pack_start(table, True, True, 0)
         self.show_all()
 
     def _propertyChangedCb(self, element, pspec, widget):
         widget.setWidgetValue(self.element.get_property(pspec.name))
 
     def _getResetToDefaultValueButton(self, prop, widget):
-        icon = gtk.Image()
-        icon.set_from_stock('gtk-clear', gtk.ICON_SIZE_MENU)
-        button = gtk.Button()
+        icon = Gtk.Image()
+        icon.set_from_stock('gtk-clear', Gtk.IconSize.MENU)
+        button = Gtk.Button()
         button.add(icon)
         button.set_tooltip_text(_("Reset to default value"))
         button.connect('clicked', self._defaultBtnClickedCb, widget)
@@ -894,7 +895,7 @@ class GstElementSettingsWidget(gtk.VBox, Loggable):
         """
         d = {}
         for prop, widget in self.properties.iteritems():
-            if not prop.flags & gobject.PARAM_WRITABLE\
+            if not prop.flags & GObject.PARAM_WRITABLE\
               or isinstance(widget, DefaultWidget):
                 continue
             value = widget.getWidgetValue()
@@ -905,14 +906,14 @@ class GstElementSettingsWidget(gtk.VBox, Loggable):
 
 class GstElementSettingsDialog(Loggable):
     """
-    Dialog window for viewing/modifying properties of a gst.Element
+    Dialog window for viewing/modifying properties of a Gst.Element
     """
 
     def __init__(self, elementfactory, properties={}):
         Loggable.__init__(self)
         self.debug("factory:%s, properties:%s", elementfactory, properties)
 
-        self.builder = gtk.Builder()
+        self.builder = Gtk.Builder()
         self.builder.add_from_file(os.path.join(get_ui_dir(),
             "elementsettingsdialog.ui"))
         self.builder.connect_signals(self)
@@ -937,8 +938,8 @@ class GstElementSettingsDialog(Loggable):
             # The height of the content is small enough, disable the scrollbars.
             default_height = -1
             scrolledwindow = self.builder.get_object("scrolledwindow1")
-            scrolledwindow.set_policy(gtk.POLICY_NEVER, gtk.POLICY_NEVER)
-            scrolledwindow.set_shadow_type(gtk.SHADOW_NONE)
+            scrolledwindow.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.NEVER)
+            scrolledwindow.set_shadow_type(Gtk.ShadowType.NONE)
         else:
             # If we need to scroll, set a reasonable height for the window.
             default_height = 600
@@ -963,10 +964,10 @@ class GstElementSettingsDialog(Loggable):
             widget.setWidgetToDefault()
 
 
-class BaseTabs(gtk.Notebook):
+class BaseTabs(Gtk.Notebook):
     def __init__(self, app, hide_hpaned=False):
         """ initialize """
-        gtk.Notebook.__init__(self)
+        GObject.GObject.__init__(self)
         self.set_border_width(SPACING)
 
         self.connect("create-window", self._createWindowCb)
@@ -978,10 +979,10 @@ class BaseTabs(gtk.Notebook):
         """ set up the gui """
         settings = self.get_settings()
         settings.props.gtk_dnd_drag_threshold = 1
-        self.set_tab_pos(gtk.POS_TOP)
+        self.set_tab_pos(Gtk.PositionType.TOP)
 
     def append_page(self, child, label):
-        gtk.Notebook.append_page(self, child, label)
+        Gtk.Notebook.append_page(self, child, label)
         self._set_child_properties(child, label)
         child.show()
         label.show()
@@ -994,10 +995,10 @@ class BaseTabs(gtk.Notebook):
 
     def _detachedComponentWindowDestroyCb(self, window, child,
             original_position, label):
-        notebook = window.child
+        notebook = window.get_child()
         position = notebook.child_get_property(child, "position")
         notebook.remove_page(position)
-        label = gtk.Label(label)
+        label = Gtk.Label(label=label)
         self.insert_page(child, label, original_position)
         self._set_child_properties(child, label)
         self.child_set_property(child, "detachable", True)
@@ -1008,14 +1009,14 @@ class BaseTabs(gtk.Notebook):
     def _createWindowCb(self, from_notebook, child, x, y):
         original_position = self.child_get_property(child, "position")
         label = self.child_get_property(child, "tab-label")
-        window = gtk.Window()
-        window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_UTILITY)
+        window = Gtk.Window()
+        window.set_type_hint(Gdk.WindowTypeHint.UTILITY)
 
         window.set_title(label)
         window.set_default_size(600, 400)
         window.connect("destroy", self._detachedComponentWindowDestroyCb,
                 child, original_position, label)
-        notebook = gtk.Notebook()
+        notebook = Gtk.Notebook()
         notebook.props.show_tabs = False
         window.add(notebook)
 
diff --git a/pitivi/viewer.py b/pitivi/viewer.py
index 33ef513..07f8f75 100644
--- a/pitivi/viewer.py
+++ b/pitivi/viewer.py
@@ -20,11 +20,17 @@
 # Boston, MA 02110-1301, USA.
 
 import platform
-import gobject
-import gtk
-import gst
+from gi.repository import Gtk
+from gi.repository import Gdk
+from gi.repository import Gst
+from gi.repository import GdkX11
+from gi.repository import GObject
+from gi.repository import GES
+GdkX11  # pyflakes
+from gi.repository import GstVideo
+GstVideo    # pyflakes
+from gi.repository import GdkPixbuf
 import cairo
-import ges
 
 from gettext import gettext as _
 from time import time
@@ -35,6 +41,7 @@ from pitivi.utils.pipeline import Seeker, SimplePipeline
 from pitivi.utils.ui import SPACING, hex_to_rgb
 from pitivi.utils.widgets import TimeWidget
 from pitivi.utils.loggable import Loggable
+from pitivi.utils.misc import print_ns
 
 GlobalSettings.addConfigSection("viewer")
 GlobalSettings.addConfigOption("viewerDocked", section="viewer",
@@ -63,7 +70,7 @@ GlobalSettings.addConfigOption("pointColor", section="viewer",
     default='49a0e0')
 
 
-class PitiviViewer(gtk.VBox, Loggable):
+class PitiviViewer(Gtk.VBox, Loggable):
     """
     A Widget to control and visualize a Pipeline
 
@@ -74,14 +81,14 @@ class PitiviViewer(gtk.VBox, Loggable):
     """
     __gtype_name__ = 'PitiviViewer'
     __gsignals__ = {
-        "activate-playback-controls": (gobject.SIGNAL_RUN_LAST,
-            gobject.TYPE_NONE, (gobject.TYPE_BOOLEAN,)),
+        "activate-playback-controls": (GObject.SignalFlags.RUN_LAST,
+            None, (GObject.TYPE_BOOLEAN,)),
     }
 
     INHIBIT_REASON = _("Currently playing")
 
     def __init__(self, app, undock_action=None):
-        gtk.VBox.__init__(self)
+        GObject.GObject.__init__(self)
         self.set_border_width(SPACING)
         self.app = app
         self.settings = app.settings
@@ -125,7 +132,7 @@ class PitiviViewer(gtk.VBox, Loggable):
         self.seeker = Seeker()
         self._disconnectFromPipeline()
         if self.pipeline:
-            self.pipeline.set_state(gst.STATE_NULL)
+            self.pipeline.set_state(Gst.State.NULL)
 
         self.pipeline = pipeline
         if self.pipeline:
@@ -177,70 +184,70 @@ class PitiviViewer(gtk.VBox, Loggable):
         """ Creates the Viewer GUI """
         # Drawing area
         # The aspect ratio gets overridden on startup by setDisplayAspectRatio
-        self.aframe = gtk.AspectFrame(xalign=0.5, yalign=1.0, ratio=4.0 / 3.0,
+        self.aframe = Gtk.AspectFrame(xalign=0.5, yalign=1.0, ratio=4.0 / 3.0,
                                       obey_child=False)
 
         self.internal = ViewerWidget(self.app.settings)
         self.internal.init_transformation_events()
         self.internal.show()
         self.aframe.add(self.internal)
-        self.pack_start(self.aframe, expand=True)
+        self.pack_start(self.aframe, True, True, 0)
 
-        self.external_window = gtk.Window()
-        vbox = gtk.VBox()
+        self.external_window = Gtk.Window()
+        vbox = Gtk.VBox()
         vbox.set_spacing(SPACING)
         self.external_window.add(vbox)
         self.external = ViewerWidget(self.app.settings)
-        vbox.pack_start(self.external)
+        vbox.pack_start(self.external, True, True, 0)
         self.external_window.connect("delete-event", self._externalWindowDeleteCb)
         self.external_window.connect("configure-event", self._externalWindowConfigureCb)
         self.external_vbox = vbox
         self.external_vbox.show_all()
 
         # Buttons/Controls
-        bbox = gtk.HBox()
-        boxalign = gtk.Alignment(xalign=0.5, yalign=0.5)
+        bbox = Gtk.HBox()
+        boxalign = Gtk.Alignment(xalign=0.5, yalign=0.5, xscale=0.0, yscale=0.0)
         boxalign.add(bbox)
-        self.pack_start(boxalign, expand=False)
+        self.pack_start(boxalign, False, True, 0)
 
-        self.goToStart_button = gtk.ToolButton(gtk.STOCK_MEDIA_PREVIOUS)
+        self.goToStart_button = Gtk.ToolButton(Gtk.STOCK_MEDIA_PREVIOUS)
         self.goToStart_button.connect("clicked", self._goToStartCb)
         self.goToStart_button.set_tooltip_text(_("Go to the beginning of the timeline"))
         self.goToStart_button.set_sensitive(False)
-        bbox.pack_start(self.goToStart_button, expand=False)
+        bbox.pack_start(self.goToStart_button, False, True, 0)
 
-        self.back_button = gtk.ToolButton(gtk.STOCK_MEDIA_REWIND)
+        self.back_button = Gtk.ToolButton(Gtk.STOCK_MEDIA_REWIND)
         self.back_button.connect("clicked", self._backCb)
         self.back_button.set_tooltip_text(_("Go back one second"))
         self.back_button.set_sensitive(False)
-        bbox.pack_start(self.back_button, expand=False)
+        bbox.pack_start(self.back_button, False, True, 0)
 
         self.playpause_button = PlayPauseButton()
         self.playpause_button.connect("play", self._playButtonCb)
-        bbox.pack_start(self.playpause_button, expand=False)
+        bbox.pack_start(self.playpause_button, False, True, 0)
         self.playpause_button.set_sensitive(False)
 
-        self.forward_button = gtk.ToolButton(gtk.STOCK_MEDIA_FORWARD)
+        self.forward_button = Gtk.ToolButton(Gtk.STOCK_MEDIA_FORWARD)
         self.forward_button.connect("clicked", self._forwardCb)
         self.forward_button.set_tooltip_text(_("Go forward one second"))
         self.forward_button.set_sensitive(False)
-        bbox.pack_start(self.forward_button, expand=False)
+        bbox.pack_start(self.forward_button, False, True, 0)
 
-        self.goToEnd_button = gtk.ToolButton(gtk.STOCK_MEDIA_NEXT)
+        self.goToEnd_button = Gtk.ToolButton(Gtk.STOCK_MEDIA_NEXT)
         self.goToEnd_button.connect("clicked", self._goToEndCb)
         self.goToEnd_button.set_tooltip_text(_("Go to the end of the timeline"))
         self.goToEnd_button.set_sensitive(False)
-        bbox.pack_start(self.goToEnd_button, expand=False)
+        bbox.pack_start(self.goToEnd_button, False, True, 0)
 
         # current time
         self.timecode_entry = TimeWidget()
         self.timecode_entry.setWidgetValue(0)
         self.timecode_entry.connect("value-changed", self._jumpToTimecodeCb)
         self.timecode_entry.connectFocusEvents(self._entryFocusInCb, self._entryFocusOutCb)
-        bbox.pack_start(self.timecode_entry, expand=False, padding=10)
+        bbox.pack_start(self.timecode_entry, False, 10, 0)
         self._haveUI = True
 
-        screen = gtk.gdk.screen_get_default()
+        screen = Gdk.Screen.get_default()
         height = screen.get_height()
         if height >= 800:
             # show the controls and force the aspect frame to have at least the same
@@ -279,7 +286,7 @@ class PitiviViewer(gtk.VBox, Loggable):
         else:
             self._setUiActive(True)
 
-    ## Control gtk.Button callbacks
+    ## Control Gtk.Button callbacks
 
     def setZoom(self, zoom):
         """
@@ -290,7 +297,7 @@ class PitiviViewer(gtk.VBox, Loggable):
             maxSize = self.target.area
             width = int(float(maxSize.width) * zoom)
             height = int(float(maxSize.height) * zoom)
-            area = gtk.gdk.Rectangle((maxSize.width - width) / 2,
+            area = ((maxSize.width - width) / 2,
                                      (maxSize.height - height) / 2,
                                      width, height)
             self.sink.set_render_rectangle(*area)
@@ -307,11 +314,11 @@ class PitiviViewer(gtk.VBox, Loggable):
 
     def _backCb(self, unused_button):
         # Seek backwards one second
-        self.seeker.seekRelative(0 - gst.SECOND)
+        self.seeker.seekRelative(0 - Gst.SECOND)
 
     def _forwardCb(self, unused_button):
         # Seek forward one second
-        self.seeker.seekRelative(gst.SECOND)
+        self.seeker.seekRelative(Gst.SECOND)
 
     def _goToEndCb(self, unused_button):
         try:
@@ -343,8 +350,8 @@ class PitiviViewer(gtk.VBox, Loggable):
         self.undock_action.set_label(_("Dock Viewer"))
 
         self.remove(self.buttons)
-        self.external_vbox.pack_end(self.buttons, False, False)
-        self.external_window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_UTILITY)
+        self.external_vbox.pack_end(self.buttons, False, False, 0)
+        self.external_window.set_type_hint(Gdk.WindowTypeHint.UTILITY)
         self.external_window.show()
         self.target = self.external
         # if we are playing, switch output immediately
@@ -366,7 +373,7 @@ class PitiviViewer(gtk.VBox, Loggable):
 
         self.target = self.internal
         self.external_vbox.remove(self.buttons)
-        self.pack_end(self.buttons, False, False)
+        self.pack_end(self.buttons, False, False, 0)
         self.show()
         # if we are playing, switch output immediately
         if self.sink:
@@ -392,7 +399,7 @@ class PitiviViewer(gtk.VBox, Loggable):
         """
         While a clip is being trimmed, show a live preview of it.
         """
-        if isinstance(tl_obj, ges.TimelineTitleSource) or tl_obj.props.is_image or not hasattr(tl_obj, "get_uri"):
+        if isinstance(tl_obj, GES.TimelineTitleSource) or tl_obj.props.is_image or not hasattr(tl_obj, "get_uri"):
             self.log("%s is an image or has no URI, so not previewing trim" % tl_obj)
             return False
 
@@ -400,16 +407,16 @@ class PitiviViewer(gtk.VBox, Loggable):
         cur_time = time()
         if not self._tmp_pipeline:
             self.debug("Creating temporary pipeline for clip %s, position %s",
-                clip_uri, gst.TIME_ARGS(position))
+                clip_uri, print_ns(position))
 
             self._oldTimelinePos = self.pipeline.getPosition()
-            self._tmp_pipeline = gst.element_factory_make("playbin")
+            self._tmp_pipeline = Gst.ElementFactory.make("playbin", None)
             self._tmp_pipeline.set_property("uri", clip_uri)
             self.setPipeline(SimplePipeline(self._tmp_pipeline))
             self._lastClipTrimTime = cur_time
         if (cur_time - self._lastClipTrimTime) > 0.2:
             # Do not seek more than once every 200 ms (for performance)
-            self._tmp_pipeline.seek_simple(gst.FORMAT_TIME, gst.SEEK_FLAG_FLUSH, position)
+            self._tmp_pipeline.seek_simple(Gst.Format.TIME, Gst.SeekFlags.FLUSH, position)
             self._lastClipTrimTime = cur_time
 
     def clipTrimPreviewFinished(self):
@@ -417,7 +424,7 @@ class PitiviViewer(gtk.VBox, Loggable):
         After trimming a clip, reset the project pipeline into the viewer.
         """
         if self._tmp_pipeline is not None:
-            self._tmp_pipeline.set_state(gst.STATE_NULL)
+            self._tmp_pipeline.set_state(Gst.State.NULL)
             self._tmp_pipeline = None  # Free the memory
             self.setPipeline(self.app.current.pipeline, self._oldTimelinePos)
             self.debug("Back to old pipeline")
@@ -430,10 +437,10 @@ class PitiviViewer(gtk.VBox, Loggable):
         This is meant to be called by mainwindow.
         """
         self.info("current state changed : %s", state)
-        if int(state) == int(gst.STATE_PLAYING):
+        if int(state) == int(Gst.State.PLAYING):
             self.playpause_button.setPause()
             self.system.inhibitScreensaver(self.INHIBIT_REASON)
-        elif int(state) == int(gst.STATE_PAUSED):
+        elif int(state) == int(Gst.State.PAUSED):
             self.playpause_button.setPlay()
             self.system.uninhibitScreensaver(self.INHIBIT_REASON)
         else:
@@ -450,10 +457,10 @@ class PitiviViewer(gtk.VBox, Loggable):
         self._switch_output_window()
 
     def _switch_output_window(self):
-        gtk.gdk.threads_enter()
+        Gdk.threads_enter()
         self.sink.set_window_handle(self.target.window_xid)
         self.sink.expose()
-        gtk.gdk.threads_leave()
+        Gdk.threads_leave()
 
 
 class Point():
@@ -769,7 +776,7 @@ class TransformationBox():
             self.transformation_properties.connectSpinButtonsToFlush()
 
 
-class ViewerWidget(gtk.DrawingArea, Loggable):
+class ViewerWidget(Gtk.DrawingArea, Loggable):
     """
     Widget for displaying properly GStreamer video sink
 
@@ -780,7 +787,7 @@ class ViewerWidget(gtk.DrawingArea, Loggable):
     __gsignals__ = {}
 
     def __init__(self, settings=None):
-        gtk.DrawingArea.__init__(self)
+        Gtk.DrawingArea.__init__(self)
         Loggable.__init__(self)
         self.seeker = Seeker()
         self.settings = settings
@@ -792,14 +799,15 @@ class ViewerWidget(gtk.DrawingArea, Loggable):
         self.pixbuf = None
         self.pipeline = None
         self.transformation_properties = None
-        for state in range(gtk.STATE_INSENSITIVE + 1):
-            self.modify_bg(state, self.style.black)
+        # FIXME PyGi Styling with Gtk3
+        #for state in range(Gtk.StateType.INSENSITIVE + 1):
+            #self.modify_bg(state, self.style.black)
 
     def init_transformation_events(self):
-        self.set_events(gtk.gdk.BUTTON_PRESS_MASK
-                        | gtk.gdk.BUTTON_RELEASE_MASK
-                        | gtk.gdk.POINTER_MOTION_MASK
-                        | gtk.gdk.POINTER_MOTION_HINT_MASK)
+        self.set_events(Gdk.EventMask.BUTTON_PRESS_MASK
+                        | Gdk.EventMask.BUTTON_RELEASE_MASK
+                        | Gdk.EventMask.POINTER_MOTION_MASK
+                        | Gdk.EventMask.POINTER_MOTION_HINT_MASK)
 
     def show_box(self):
         if not self.box:
@@ -842,11 +850,11 @@ class ViewerWidget(gtk.DrawingArea, Loggable):
             # The transformation box is active and dezoomed
             # crop away 1 pixel border to avoid artefacts on the pixbuf
 
-            self.pixbuf = gtk.gdk.pixbuf_get_from_window(self.get_window(),
+            self.pixbuf = Gdk.pixbuf_get_from_window(self.get_window(),
                 self.box.area.x + 1, self.box.area.y + 1,
                 self.box.area.width - 2, self.box.area.height - 2)
         else:
-            self.pixbuf = gtk.gdk.pixbuf_get_from_window(self.get_window(),
+            self.pixbuf = Gdk.pixbuf_get_from_window(self.get_window(),
                 0, 0,
                 self.get_window().get_width(),
                 self.get_window().get_height())
@@ -858,7 +866,7 @@ class ViewerWidget(gtk.DrawingArea, Loggable):
         Redefine gtk DrawingArea's do_realize method to handle multiple OSes.
         This is called when creating the widget to get the window ID.
         """
-        gtk.DrawingArea.do_realize(self)
+        Gtk.DrawingArea.do_realize(self)
         if platform.system() == 'Windows':
             self.window_xid = self.props.window.handle
         else:
@@ -879,12 +887,12 @@ class ViewerWidget(gtk.DrawingArea, Loggable):
 
     def _currentStateCb(self, pipeline, state):
         self.pipeline = pipeline
-        if state == gst.STATE_PAUSED:
+        if state == Gst.State.PAUSED:
             self._store_pixbuf()
         self.renderbox()
 
     def motion_notify_event(self, widget, event):
-        if event.get_state() & gtk.gdk.BUTTON1_MASK:
+        if event.get_state() & Gdk.ModifierType.BUTTON1_MASK:
             if self.box.transform(event):
                 if self.stored:
                     self.renderbox()
@@ -897,7 +905,7 @@ class ViewerWidget(gtk.DrawingArea, Loggable):
             if self.zoom != 1.0:
                 width = int(float(self.area.width) * self.zoom)
                 height = int(float(self.area.height) * self.zoom)
-                area = gtk.gdk.Rectangle((self.area.width - width) / 2,
+                area = ((self.area.width - width) / 2,
                                      (self.area.height - height) / 2,
                                      width, height)
                 self.sink.set_render_rectangle(*area)
@@ -938,31 +946,31 @@ class ViewerWidget(gtk.DrawingArea, Loggable):
                 if self.box.area.width != self.pixbuf.get_width():
                     cr.restore()
 
-            if self.pipeline and self.pipeline.get_state()[1] == gst.STATE_PAUSED:
+            if self.pipeline and self.pipeline.get_state()[1] == Gst.State.PAUSED:
                 self.box.draw(cr)
             cr.pop_group_to_source()
             cr.paint()
 
 
-class PlayPauseButton(gtk.Button, Loggable):
+class PlayPauseButton(Gtk.Button, Loggable):
     """
-    Double state gtk.Button which displays play/pause
+    Double state Gtk.Button which displays play/pause
     """
     __gsignals__ = {
-        "play": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_BOOLEAN,))
+        "play": (GObject.SignalFlags.RUN_LAST, None, (GObject.TYPE_BOOLEAN,))
         }
 
     def __init__(self):
-        gtk.Button.__init__(self)
+        GObject.GObject.__init__(self)
         Loggable.__init__(self)
-        self.image = gtk.Image()
+        self.image = Gtk.Image()
         self.add(self.image)
         self.playing = False
         self.setPlay()
         self.connect('clicked', self._clickedCb)
 
     def set_sensitive(self, value):
-        gtk.Button.set_sensitive(self, value)
+        Gtk.Button.set_sensitive(self, value)
 
     def _clickedCb(self, unused):
         self.playing = not self.playing
@@ -972,7 +980,7 @@ class PlayPauseButton(gtk.Button, Loggable):
         """ display the play image """
         self.log("setPlay")
         self.playing = True
-        self.set_image(gtk.image_new_from_stock(gtk.STOCK_MEDIA_PLAY, gtk.ICON_SIZE_BUTTON))
+        self.set_image(Gtk.Image.new_from_stock(Gtk.STOCK_MEDIA_PLAY, Gtk.IconSize.BUTTON))
         self.set_tooltip_text(_("Play"))
         self.playing = False
 
@@ -980,6 +988,6 @@ class PlayPauseButton(gtk.Button, Loggable):
         self.log("setPause")
         """ display the pause image """
         self.playing = False
-        self.set_image(gtk.image_new_from_stock(gtk.STOCK_MEDIA_PAUSE, gtk.ICON_SIZE_BUTTON))
+        self.set_image(Gtk.Image.new_from_stock(Gtk.STOCK_MEDIA_PAUSE, Gtk.IconSize.BUTTON))
         self.set_tooltip_text(_("Pause"))
         self.playing = True
diff --git a/tests/__init__.py b/tests/__init__.py
index 619126a..0442462 100644
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -1,6 +1,6 @@
-import gobject
-# This call has to be made before any "import gst" call!
-gobject.threads_init()
+from gi.repository import GObject
+# This call has to be made before any "import Gst" call!
+GObject.threads_init()
 
 from pitivi.check import initial_checks
 
diff --git a/tests/common.py b/tests/common.py
index e347b55..0c3274c 100644
--- a/tests/common.py
+++ b/tests/common.py
@@ -2,7 +2,7 @@
 A collection of objects to use for testing
 """
 
-import gst
+from gi.repository import Gst
 import os
 import gc
 import unittest
@@ -11,7 +11,7 @@ detect_leaks = os.environ.get("PITIVI_TEST_DETECT_LEAKS", "1") not in ("0", "")
 
 
 class TestCase(unittest.TestCase):
-    _tracked_types = (gst.MiniObject, gst.Element, gst.Pad, gst.Caps)
+    _tracked_types = (Gst.MiniObject, Gst.Element, Gst.Pad, Gst.Caps)
 
     def gctrack(self):
         self.gccollect()
diff --git a/tests/dogtail_scripts/helper_functions.py b/tests/dogtail_scripts/helper_functions.py
index d9687ce..4b262fb 100644
--- a/tests/dogtail_scripts/helper_functions.py
+++ b/tests/dogtail_scripts/helper_functions.py
@@ -19,11 +19,11 @@ class HelpFunc(BaseDogTail):
         if saveAs:
             self.assertIsNotNone(path)
             proj_menu.menuItem("Save As...").click()
-            save_dialog = self.pitivi.child(name="Save As...", roleName='dialog', recursive=False)
+            save_dialog = self.pitivi.get_child()(name="Save As...", roleName='dialog', recursive=False)
             # In GTK3's file chooser, you can enter /tmp/foo.xptv directly
             # In GTK2 however, you must do it in two steps:
             path_dir, filename = os.path.split(path)
-            text_field = save_dialog.child(roleName="text")
+            text_field = save_dialog.get_child()(roleName="text")
             text_field.text = path_dir
             dogtail.rawinput.pressKey("Enter")
             sleep(0.15)
@@ -39,15 +39,15 @@ class HelpFunc(BaseDogTail):
         proj_menu = self.menubar.menu("Project")
         proj_menu.click()
         proj_menu.menuItem("Open...").click()
-        load = self.pitivi.child(roleName='dialog', recursive=False)
-        load.child(name="Type a file name", roleName="toggle button").click()
-        load.child(roleName='text').text = url
+        load = self.pitivi.get_child()(roleName='dialog', recursive=False)
+        load.get_child()(name="Type a file name", roleName="toggle button").click()
+        load.get_child()(roleName='text').text = url
         load.button('Open').click()
         # If an unsaved changes confirmation dialog shows up, deal with it
         if expect_unsaved_changes:
             # Simply try searching for the existence of the dialog's widgets
             # If it fails, dogtail will fail with a SearchError, which is fine
-            self.pitivi.child(name="Close without saving", roleName="push button").click()
+            self.pitivi.get_child()(name="Close without saving", roleName="push button").click()
 
     def search_by_text(self, text, parent, name=None, roleName=None):
         """
@@ -71,7 +71,7 @@ class HelpFunc(BaseDogTail):
     def insert_clip(self, icon, n=1):
         icon.select()
         lib = self.menubar.menu("Library")
-        insert = lib.child("Insert at End of Timeline")
+        insert = lib.get_child()("Insert at End of Timeline")
         for i in range(n):
             sleep(0.3)
             lib.click()
@@ -84,12 +84,12 @@ class HelpFunc(BaseDogTail):
         # Use the menus, as the main toolbar might be hidden
         lib_menu = self.menubar.menu("Library")
         lib_menu.click()
-        import_menu_item = lib_menu.child("Import Files...")
+        import_menu_item = lib_menu.get_child()("Import Files...")
         import_menu_item.click()
 
         # Force dogtail to look only one level deep, which is much faster
         # as it doesn't have to analyze the whole mainwindow.
-        import_dialog = self.pitivi.child(name="Select One or More Files",
+        import_dialog = self.pitivi.get_child()(name="Select One or More Files",
                                           roleName="dialog", recursive=False)
         # Instead of checking for the presence of the path text field and then
         # searching for the toggle button to enable it, use the fact that GTK's
@@ -98,7 +98,7 @@ class HelpFunc(BaseDogTail):
 
         filepath = os.path.realpath(__file__).split("dogtail_scripts/")[0]
         filepath += "samples/" + filename
-        import_dialog.child(roleName='text').text = filepath
+        import_dialog.get_child()(roleName='text').text = filepath
         dogtail.rawinput.pressKey("Enter")  # Don't search for the Add button
         sleep(0.6)
 
@@ -113,7 +113,7 @@ class HelpFunc(BaseDogTail):
                     return icon
             sleep(0.5)
         # Failure to find an icon might be because it is hidden due to a search
-        current_search_text = libtab.child(roleName="text").text.lower()
+        current_search_text = libtab.get_child()(roleName="text").text.lower()
         self.assertNotEqual(current_search_text, "")
         self.assertNotIn(filename.lower(), current_search_text)
         return None
@@ -123,15 +123,15 @@ class HelpFunc(BaseDogTail):
         # Use the menus, as the main toolbar might be hidden
         lib_menu = self.menubar.menu("Library")
         lib_menu.click()
-        import_menu_item = lib_menu.child("Import Files...")
+        import_menu_item = lib_menu.get_child()("Import Files...")
         import_menu_item.click()
 
         # Same performance hack as in the import_media method
-        import_dialog = self.pitivi.child(name="Select One or More Files",
+        import_dialog = self.pitivi.get_child()(name="Select One or More Files",
                                           roleName="dialog", recursive=False)
         dogtail.rawinput.pressKey("/")
         dir_path = os.path.realpath(__file__).split("dogtail_scripts/")[0] + "samples/"
-        import_dialog.child(roleName='text').text = dir_path
+        import_dialog.get_child()(roleName='text').text = dir_path
         dogtail.rawinput.pressKey("Enter")
 
         # We are now in the samples directory, select various items.
@@ -139,11 +139,11 @@ class HelpFunc(BaseDogTail):
         # row of the filechooser is always selected by default, we must not use
         # ctrl when selecting the first item of our list, in order to deselect.
         ctrl_code = dogtail.rawinput.keyNameToKeyCode("Control_L")
-        file_list = import_dialog.child(name="Files", roleName="table")
+        file_list = import_dialog.get_child()(name="Files", roleName="table")
         first = True
         for f in files:
             sleep(0.5)
-            file_list.child(name=f).click()
+            file_list.get_child()(name=f).click()
             if first:
                 registry.generateKeyboardEvent(ctrl_code, None, KEY_PRESS)
                 first = False
@@ -151,7 +151,7 @@ class HelpFunc(BaseDogTail):
         import_dialog.button('Add').click()
 
         libtab = self.pitivi.tab("Media Library")
-        current_search_text = libtab.child(roleName="text").text.lower()
+        current_search_text = libtab.get_child()(roleName="text").text.lower()
         if current_search_text != "":
             # Failure to find some icons might be because of search filtering.
             # The following avoids searching for files that can't be found.
diff --git a/tests/dogtail_scripts/test_base.py b/tests/dogtail_scripts/test_base.py
index 305d33a..bc7bd3d 100644
--- a/tests/dogtail_scripts/test_base.py
+++ b/tests/dogtail_scripts/test_base.py
@@ -24,7 +24,7 @@ class BaseDogTail(unittest.TestCase):
         # making the tests take ages to start up.
         self.pid = run('bin/pitivi', dumb=False, appName="pitivi")
         self.pitivi = root.application('pitivi')
-        self.menubar = self.pitivi.child(roleName='menu bar')
+        self.menubar = self.pitivi.get_child()(roleName='menu bar')
         try:
             self.unlink
         except AttributeError:
@@ -36,7 +36,7 @@ class BaseDogTail(unittest.TestCase):
         else:
             proj_menu = self.menubar.menu("Project")
             proj_menu.click()
-            proj_menu.child("Quit").click()
+            proj_menu.get_child()("Quit").click()
         if clean:
             for filename in self.unlink:
                 try:
diff --git a/tests/dogtail_scripts/test_clipproperties.py b/tests/dogtail_scripts/test_clipproperties.py
index 53292ec..d29e2d3 100644
--- a/tests/dogtail_scripts/test_clipproperties.py
+++ b/tests/dogtail_scripts/test_clipproperties.py
@@ -19,29 +19,29 @@ class ClipTransforamtionTest(HelpFunc):
 
         conftab = self.pitivi.tab("Clip configuration")
         conftab.click()
-        conftab.child(name="Transformation", roleName="toggle button").click()
+        conftab.get_child()(name="Transformation", roleName="toggle button").click()
         #Just try changing values
         #Test slider
-        slider = conftab.child(roleName="slider")
+        slider = conftab.get_child()(roleName="slider")
         self.assertEqual(slider.value, 1.0)
         slider.click()
         # Clicking in the middle of the slider will set it backwards to 0.9
         self.assertNotEqual(slider.value, 1.0)
 
         #Test position
-        spinb = conftab.child(roleName="panel", name="Position").findChildren(GenericPredicate(roleName="spin button"))
+        spinb = conftab.get_child()(roleName="panel", name="Position").findChildren(GenericPredicate(roleName="spin button"))
         self.assertEqual(len(spinb), 2)
         spinb[0].text = "0.3"
         spinb[1].text = "0.2"
 
         #Test size
-        spinb = conftab.child(roleName="panel", name="Size").findChildren(GenericPredicate(roleName="spin button"))
+        spinb = conftab.get_child()(roleName="panel", name="Size").findChildren(GenericPredicate(roleName="spin button"))
         self.assertEqual(len(spinb), 2)
         spinb[0].text = "0.4"
         spinb[1].text = "0.1"
 
         #Test crop
-        spinb = conftab.child(roleName="panel", name="Crop").findChildren(GenericPredicate(roleName="spin button"))
+        spinb = conftab.get_child()(roleName="panel", name="Crop").findChildren(GenericPredicate(roleName="spin button"))
         self.assertEqual(len(spinb), 4)
         spinb[0].text = "0.05"
         spinb[1].text = "0.12"
@@ -50,36 +50,36 @@ class ClipTransforamtionTest(HelpFunc):
 
         #Click second clip, look that settings not changed(not linked)
         dogtail.rawinput.click(clippos[1][0], clippos[1][1])
-        self.assertEqual(conftab.child(roleName="slider").value, 1.0)
+        self.assertEqual(conftab.get_child()(roleName="slider").value, 1.0)
 
         #Click back, look if settings saved
         dogtail.rawinput.click(clippos[0][0], clippos[0][1])
-        self.assertNotEqual(conftab.child(roleName="slider").value, 1.0)
+        self.assertNotEqual(conftab.get_child()(roleName="slider").value, 1.0)
 
-        self.assertNotNone(self.search_by_text("0.3", conftab.child(roleName="panel", name="Position")))
-        self.assertNotNone(self.search_by_text("0.2", conftab.child(roleName="panel", name="Position")))
+        self.assertNotNone(self.search_by_text("0.3", conftab.get_child()(roleName="panel", name="Position")))
+        self.assertNotNone(self.search_by_text("0.2", conftab.get_child()(roleName="panel", name="Position")))
 
-        self.assertNotNone(self.search_by_text("0.4", conftab.child(roleName="panel", name="Size")))
-        self.assertNotNone(self.search_by_text("0.1", conftab.child(roleName="panel", name="Size")))
+        self.assertNotNone(self.search_by_text("0.4", conftab.get_child()(roleName="panel", name="Size")))
+        self.assertNotNone(self.search_by_text("0.1", conftab.get_child()(roleName="panel", name="Size")))
 
-        self.assertNotNone(self.search_by_text("0.05", conftab.child(roleName="panel", name="Crop")))
-        self.assertNotNone(self.search_by_text("0.12", conftab.child(roleName="panel", name="Crop")))
-        self.assertNotNone(self.search_by_text("0.14", conftab.child(roleName="panel", name="Crop")))
-        self.assertNotNone(self.search_by_text("0.07", conftab.child(roleName="panel", name="Crop")))
+        self.assertNotNone(self.search_by_text("0.05", conftab.get_child()(roleName="panel", name="Crop")))
+        self.assertNotNone(self.search_by_text("0.12", conftab.get_child()(roleName="panel", name="Crop")))
+        self.assertNotNone(self.search_by_text("0.14", conftab.get_child()(roleName="panel", name="Crop")))
+        self.assertNotNone(self.search_by_text("0.07", conftab.get_child()(roleName="panel", name="Crop")))
 
         #Push clear
-        conftab.child(roleName="scroll bar").value = 140
+        conftab.get_child()(roleName="scroll bar").value = 140
         conftab.button("Clear")
 
-        self.assertEqual(conftab.child(roleName="slider").value, 1.0)
+        self.assertEqual(conftab.get_child()(roleName="slider").value, 1.0)
 
-        self.assertNone(self.search_by_text("0.3", conftab.child(roleName="panel", name="Position")))
-        self.assertNone(self.search_by_text("0.2", conftab.child(roleName="panel", name="Position")))
+        self.assertNone(self.search_by_text("0.3", conftab.get_child()(roleName="panel", name="Position")))
+        self.assertNone(self.search_by_text("0.2", conftab.get_child()(roleName="panel", name="Position")))
 
-        self.assertNone(self.search_by_text("0.4", conftab.child(roleName="panel", name="Size")))
-        self.assertNone(self.search_by_text("0.1", conftab.child(roleName="panel", name="Size")))
+        self.assertNone(self.search_by_text("0.4", conftab.get_child()(roleName="panel", name="Size")))
+        self.assertNone(self.search_by_text("0.1", conftab.get_child()(roleName="panel", name="Size")))
 
-        self.assertNone(self.search_by_text("0.05", conftab.child(roleName="panel", name="Crop")))
-        self.assertNone(self.search_by_text("0.12", conftab.child(roleName="panel", name="Crop")))
-        self.assertNone(self.search_by_text("0.14", conftab.child(roleName="panel", name="Crop")))
-        self.assertNone(self.search_by_text("0.07", conftab.child(roleName="panel", name="Crop")))
+        self.assertNone(self.search_by_text("0.05", conftab.get_child()(roleName="panel", name="Crop")))
+        self.assertNone(self.search_by_text("0.12", conftab.get_child()(roleName="panel", name="Crop")))
+        self.assertNone(self.search_by_text("0.14", conftab.get_child()(roleName="panel", name="Crop")))
+        self.assertNone(self.search_by_text("0.07", conftab.get_child()(roleName="panel", name="Crop")))
diff --git a/tests/dogtail_scripts/test_dialogs_clipmediaprops.py b/tests/dogtail_scripts/test_dialogs_clipmediaprops.py
index 3d2c2ef..8421623 100644
--- a/tests/dogtail_scripts/test_dialogs_clipmediaprops.py
+++ b/tests/dogtail_scripts/test_dialogs_clipmediaprops.py
@@ -12,14 +12,14 @@ class DialogsClipMediaPropsTest(HelpFunc):
         buttons[1].click()
 
         #Check if we have real info, can't check if in correct place.
-        dialog = self.pitivi.child(name="Clip Properties", roleName="dialog", recursive=False)
+        dialog = self.pitivi.get_child()(name="Clip Properties", roleName="dialog", recursive=False)
         labels = {"640", "480"}
         real_labels = set([])
         for label in dialog.findChildren(GenericPredicate(roleName="label")):
             real_labels.add(label.text)
         self.assertEqual(len(labels.difference(real_labels)), 0, "Not all info is displayed")
-        self.assertFalse(dialog.child(name="Audio:", roleName="panel").showing)
-        dialog.child(name="Cancel").click()
+        self.assertFalse(dialog.get_child()(name="Audio:", roleName="panel").showing)
+        dialog.get_child()(name="Cancel").click()
         sample.deselect()
 
         sample = self.import_media()
@@ -28,7 +28,7 @@ class DialogsClipMediaPropsTest(HelpFunc):
         self.menubar.menuItem("Clip Properties...").click()
 
         #Check if we have real info, can't check if in correct place.
-        dialog = self.pitivi.child(name="Clip Properties", roleName="dialog", recursive=False)
+        dialog = self.pitivi.get_child()(name="Clip Properties", roleName="dialog", recursive=False)
         labels = {"1280", "544", "23.976 fps", "Square", "Stereo", "48 KHz", "16 bit"}
         real_labels = set([])
         for label in dialog.findChildren(GenericPredicate(roleName="label")):
@@ -36,13 +36,13 @@ class DialogsClipMediaPropsTest(HelpFunc):
         self.assertEqual(len(labels.difference(real_labels)), 0, "Not all info is displayed")
 
         #Uncheck frame rate
-        dialog.child(name="Frame rate:").click()
-        dialog.child(name="Apply to project").click()
+        dialog.get_child()(name="Frame rate:").click()
+        dialog.get_child()(name="Apply to project").click()
 
         #Check if correctly applied
         self.menubar.menu("Edit").click()
         self.menubar.menuItem("Project Settings").click()
-        dialog = self.pitivi.child(name="Project Settings", roleName="dialog", recursive=False)
+        dialog = self.pitivi.get_child()(name="Project Settings", roleName="dialog", recursive=False)
 
         children = dialog.findChildren(IsATextEntryNamed(""))
         childtext = {}
diff --git a/tests/dogtail_scripts/test_dialogs_prefs.py b/tests/dogtail_scripts/test_dialogs_prefs.py
index dd1db81..4316d46 100644
--- a/tests/dogtail_scripts/test_dialogs_prefs.py
+++ b/tests/dogtail_scripts/test_dialogs_prefs.py
@@ -10,17 +10,17 @@ class DialogsPreferencesTest(HelpFunc):
         dogtail.rawinput.pressKey("Esc")
         self.menubar.menu("Edit").click()
         self.menubar.menuItem("Preferences").click()
-        dialog = self.pitivi.child(name="Preferences", roleName="dialog")
-        dialog.child("Reset to Factory Settings", roleName="push button").click()
+        dialog = self.pitivi.get_child()(name="Preferences", roleName="dialog")
+        dialog.get_child()("Reset to Factory Settings", roleName="push button").click()
 
         # Set a different font
-        dialog.child(name="Sans", roleName="label").click()
-        fontchooser = self.pitivi.child(name="Pick a Font", roleName="fontchooser")
-        fontchooser.child(name="Serif").click()
-        fontchooser.child(name="OK", roleName="push button").click()
+        dialog.get_child()(name="Sans", roleName="label").click()
+        fontchooser = self.pitivi.get_child()(name="Pick a Font", roleName="fontchooser")
+        fontchooser.get_child()(name="Serif").click()
+        fontchooser.get_child()(name="OK", roleName="push button").click()
 
         # Set the thumbnail gap setting (or whatever the first spinbutton is)
-        foo = dialog.child(roleName="spin button")
+        foo = dialog.get_child()(roleName="spin button")
         # The following is quite silly. You *need* to focus the widget
         # before changing its text, otherwise GTK won't fire "changed" signals
         # when you click somewhere else (ex: the Close button) and it won't be
@@ -35,27 +35,27 @@ class DialogsPreferencesTest(HelpFunc):
         dogtail.rawinput.pressKey("Esc")
         self.menubar.menu("Edit").click()
         self.menubar.menuItem("Preferences").click()
-        dialog = self.pitivi.child(name="Preferences", roleName="dialog")
+        dialog = self.pitivi.get_child()(name="Preferences", roleName="dialog")
 
         # Check if the previous values were correctly saved
         # In the case of the font, just search if such an item exists:
         try:
-            dialog.child(name="Serif", roleName="label")
+            dialog.get_child()(name="Serif", roleName="label")
         except SearchError:
             self.fail("Font was not saved")
-        self.assertEqual(dialog.child(roleName="spin button").text, "12")
+        self.assertEqual(dialog.get_child()(roleName="spin button").text, "12")
 
         # Check the "revert to last user values" feature
-        foo = dialog.child(roleName="spin button")
+        foo = dialog.get_child()(roleName="spin button")
         foo.click()
         foo.text = ""  # Clear the text so we can type into it
         # Finish typeText with a \n so that the "changed" signals get fired
         # Otherwise the Revert button will not be made sensitive
         foo.typeText("888\n")
-        dialog.child("Revert", roleName="push button").click()
-        self.assertEqual(dialog.child(roleName="spin button").text, "12", "Spacing setting was not reverted")
+        dialog.get_child()("Revert", roleName="push button").click()
+        self.assertEqual(dialog.get_child()(roleName="spin button").text, "12", "Spacing setting was not reverted")
 
         # Check resetting to factory settings
-        dialog.child("Reset to Factory Settings", roleName="push button").click()
-        dialog.child(name="Sans", roleName="label")
-        self.assertEqual(dialog.child(roleName="spin button").text, "5", "Resetting to factory defaults failed")
+        dialog.get_child()("Reset to Factory Settings", roleName="push button").click()
+        dialog.get_child()(name="Sans", roleName="label")
+        self.assertEqual(dialog.get_child()(roleName="spin button").text, "5", "Resetting to factory defaults failed")
diff --git a/tests/dogtail_scripts/test_dialogs_startupwizard.py b/tests/dogtail_scripts/test_dialogs_startupwizard.py
index d96ba12..fbfdcde 100644
--- a/tests/dogtail_scripts/test_dialogs_startupwizard.py
+++ b/tests/dogtail_scripts/test_dialogs_startupwizard.py
@@ -7,13 +7,13 @@ class DialogsStartupWizardTest(HelpFunc):
     def test_welcome(self):
         filename = "test_project%i.xptv" % time()
         #Save project
-        self.pitivi.child(name="New", roleName='push button').click()
-        self.pitivi.child(name="OK", roleName="push button").click()
+        self.pitivi.get_child()(name="New", roleName='push button').click()
+        self.pitivi.get_child()(name="OK", roleName="push button").click()
         self.saveProject("/tmp/" + filename)
         sleep(1)
         #Hacky, but we need to open once more
         self.tearDown(clean=False)
         self.setUp()
-        welcome = self.pitivi.child(name="Welcome", roleName="frame")
+        welcome = self.pitivi.get_child()(name="Welcome", roleName="frame")
         #We expect that just saved project will be in welcome window
-        welcome.child(name=filename)
+        welcome.get_child()(name=filename)
diff --git a/tests/dogtail_scripts/test_effects.py b/tests/dogtail_scripts/test_effects.py
index 7a0adc3..954f660 100644
--- a/tests/dogtail_scripts/test_effects.py
+++ b/tests/dogtail_scripts/test_effects.py
@@ -10,8 +10,8 @@ class EffectLibraryTest(HelpFunc):
         tab = self.pitivi.tab("Effect Library")
         tab.click()
         search = tab.textentry("")
-        view = tab.child(roleName="table")
-        combotypes = tab.child(name="All effects", roleName="combo box")
+        view = tab.get_child()(roleName="table")
+        combotypes = tab.get_child()(name="All effects", roleName="combo box")
         # Some test of video effects and search. The two column headers are
         # also children and are always present, and each row has two children:
         search.text = "Crop"
@@ -24,11 +24,11 @@ class EffectLibraryTest(HelpFunc):
         self.assertEqual(len(view.children), 2 + 2 * 3)
 
         #Audio effects
-        tab.child(name="Video effects", roleName="combo box").click()
+        tab.get_child()(name="Video effects", roleName="combo box").click()
         tab.menuItem("Audio effects").click()
         search.text = "Equa"
         #Titles plus 3 plugins, two collumns = 8
-        self.assertEqual(len(tab.child(roleName="table").children), 8)
+        self.assertEqual(len(tab.get_child()(roleName="table").children), 8)
 
     def help_test_effect_drag(self):
         sample = self.import_media()
@@ -40,7 +40,7 @@ class EffectLibraryTest(HelpFunc):
         tab.click()
         conftab = self.pitivi.tab("Clip configuration")
         conftab.click()
-        table = conftab.child(roleName="table")
+        table = conftab.get_child()(roleName="table")
 
         dogtail.rawinput.click(clippos[0], clippos[1])
         self.assertTrue(table.sensitive)
@@ -59,7 +59,7 @@ class EffectLibraryTest(HelpFunc):
         self.assertEqual(len(table.children), 9)
 
         #Drag audio effect on the clip
-        tab.child(name="Video effects", roleName="combo box").click()
+        tab.get_child()(name="Video effects", roleName="combo box").click()
         tab.menuItem("Audio effects").click()
         effect = self.search_by_regex("^Amplifier", tab, roleName="table cell")
         self.improved_drag(center(effect), clippos)
@@ -73,7 +73,7 @@ class EffectLibraryTest(HelpFunc):
     def test_change_effect_settings(self):
         self.help_test_effect_drag()
         conftab = self.pitivi.tab("Clip configuration")
-        conftab.child(roleName="table").child(name="audioamplify").click()
-        eftab = conftab.child(name="Effects", roleName="toggle button")
-        eftab.child(name="Normal clipping (default)", roleName="combo box")
-        eftab.child(roleName="spin button").text = "2"
+        conftab.get_child()(roleName="table").get_child()(name="audioamplify").click()
+        eftab = conftab.get_child()(name="Effects", roleName="toggle button")
+        eftab.get_child()(name="Normal clipping (default)", roleName="combo box")
+        eftab.get_child()(roleName="spin button").text = "2"
diff --git a/tests/dogtail_scripts/test_medialibrary.py b/tests/dogtail_scripts/test_medialibrary.py
index e6afe4f..7266335 100644
--- a/tests/dogtail_scripts/test_medialibrary.py
+++ b/tests/dogtail_scripts/test_medialibrary.py
@@ -21,7 +21,7 @@ class MediaLibraryTest(HelpFunc):
         self.assertFalse(samples[2].isSelected)
 
         tab = self.pitivi.tab("Media Library")
-        iconview = tab.child(roleName="layered pane")
+        iconview = tab.get_child()(roleName="layered pane")
         self.assertEqual(len(iconview.children), 3)
         search = tab.textentry("")
         search.click()
diff --git a/tests/dogtail_scripts/test_project.py b/tests/dogtail_scripts/test_project.py
index 8968c8c..2360620 100644
--- a/tests/dogtail_scripts/test_project.py
+++ b/tests/dogtail_scripts/test_project.py
@@ -7,15 +7,15 @@ import os
 
 class ProjectPropertiesTest(HelpFunc):
     def test_settings_video(self):
-        welcome_dialog = self.pitivi.child(name="Welcome", roleName="frame", recursive=False)
+        welcome_dialog = self.pitivi.get_child()(name="Welcome", roleName="frame", recursive=False)
         welcome_dialog.button("New").click()
 
         #Play with project settings, look if they are correctly represented
-        dialog = self.pitivi.child(name="Project Settings", roleName="dialog", recursive=False)
+        dialog = self.pitivi.get_child()(name="Project Settings", roleName="dialog", recursive=False)
         video = dialog.tab("Video")
 
         #Test presets
-        video.child(name="720p24", roleName="table cell").click()
+        video.get_child()(name="720p24", roleName="table cell").click()
         children = video.findChildren(IsATextEntryNamed(""))
         childtext = {}
         for child in children:
@@ -33,23 +33,23 @@ class ProjectPropertiesTest(HelpFunc):
         self.assertIn("720", spintext)
 
         #Test frame rate combinations, link button
-        frameCombo = video.child(name="23.976 fps", roleName="combo box")
+        frameCombo = video.get_child()(name="23.976 fps", roleName="combo box")
         frameText = childtext["24M"]
         frameCombo.click()
-        video.child(name="120 fps", roleName="menu item").click()
+        video.get_child()(name="120 fps", roleName="menu item").click()
         self.assertEqual(frameText.text, "120:1")
         frameText.click()
         frameText.typeText("0")
-        video.child(name="12 fps", roleName="combo box")
+        video.get_child()(name="12 fps", roleName="combo box")
 
         #Test pixel and display ascpect ratio
-        pixelCombo = video.child(name="Square", roleName="combo box")
+        pixelCombo = video.get_child()(name="Square", roleName="combo box")
         pixelText = childtext["1:1"]
-        displayCombo = video.child(name="DV Widescreen (16:9)", roleName="combo box")
+        displayCombo = video.get_child()(name="DV Widescreen (16:9)", roleName="combo box")
         displayText = childtext["16:9"]
 
         pixelCombo.click()
-        video.child(name="576p", roleName="menu item").click()
+        video.get_child()(name="576p", roleName="menu item").click()
         self.assertEqual(pixelCombo.combovalue, "576p")
         self.assertEqual(pixelText.text, "12:11")
         #self.assertEqual(displayCombo.combovalue, "")
@@ -63,9 +63,9 @@ class ProjectPropertiesTest(HelpFunc):
         self.assertEqual(displayCombo.combovalue, "Standard (4:3)")
         self.assertEqual(displayText.text, "4:3")
 
-        video.child(name="Display aspect ratio", roleName="radio button").click()
+        video.get_child()(name="Display aspect ratio", roleName="radio button").click()
         displayCombo.click()
-        video.child(name="Cinema (1.37)", roleName="menu item").click()
+        video.get_child()(name="Cinema (1.37)", roleName="menu item").click()
         #self.assertEqual(pixelCombo.combovalue, "")
         self.assertEqual(pixelText.text, "99:128")
         self.assertEqual(displayCombo.combovalue, "Cinema (1.37)")
@@ -87,7 +87,7 @@ class ProjectPropertiesTest(HelpFunc):
         self.assertEqual(spin[1].text, oldtext)
         spin[1].doubleClick()
         spin[1].typeText("2000")
-        video.child(name="Link").click()
+        video.get_child()(name="Link").click()
         spin[1].doubleClick()
         spin[1].typeText("1000")
         spin[0].click()
@@ -108,7 +108,7 @@ class ProjectPropertiesTest(HelpFunc):
         self.pitivi.menu("Edit").click()
         self.pitivi.menuItem("Project Settings").click()
 
-        dialog = self.pitivi.child(name="Project Settings", roleName="dialog", recursive=False)
+        dialog = self.pitivi.get_child()(name="Project Settings", roleName="dialog", recursive=False)
         video = dialog.tab("Video")
         children = video.findChildren(IsATextEntryNamed(""))
         childtext = {}
@@ -158,7 +158,7 @@ class ProjectPropertiesTest(HelpFunc):
         seektime = self.search_by_text("0:00:00.000", self.pitivi, roleName="text")
         self.assertIsNotNone(seektime)
         self.insert_clip(sample)
-        self.nextb = self.pitivi.child(name="Next", roleName="push button")
+        self.nextb = self.pitivi.get_child()(name="Next", roleName="push button")
         self.nextb.click()
         self.assertEqual(seektime.text, "0:00:01.227")
 
@@ -173,7 +173,7 @@ class ProjectPropertiesTest(HelpFunc):
         self.menubar.menu("Project").menuItem("Quit").click()
 
         #If finds button, means it warned
-        self.pitivi.child(roleName="dialog", recursive=False).button("Cancel").click()
+        self.pitivi.get_child()(roleName="dialog", recursive=False).button("Cancel").click()
         self.saveProject(saveAs=False)
         #Backup should be deleted, and no warning displayed
         self.menubar.menu("Project").click()
@@ -181,16 +181,16 @@ class ProjectPropertiesTest(HelpFunc):
         self.assertFalse(os.path.exists(backup_path))
         #Test if backup is found
         self.setUp()
-        welcome_dialog = self.pitivi.child(name="Welcome", roleName="frame", recursive=False)
-        welcome_dialog.child(name=filename).doubleClick()
+        welcome_dialog = self.pitivi.get_child()(name="Welcome", roleName="frame", recursive=False)
+        welcome_dialog.get_child()(name=filename).doubleClick()
         sample = self.import_media("flat_colour1_640x480.png")
         self.assertTrue(self.wait_for_file(backup_path, 120), "Backup not created")
         self.tearDown(clean=False, kill=True)
         self.setUp()
-        welcome_dialog = self.pitivi.child(name="Welcome", roleName="frame", recursive=False)
-        welcome_dialog.child(name=filename).doubleClick()
+        welcome_dialog = self.pitivi.get_child()(name="Welcome", roleName="frame", recursive=False)
+        welcome_dialog.get_child()(name=filename).doubleClick()
         #Try restoring from backup
-        self.pitivi.child(roleName="dialog", recursive=False).button("Restore from backup").click()
+        self.pitivi.get_child()(roleName="dialog", recursive=False).button("Restore from backup").click()
         samples = self.pitivi.tab("Media Library").findChildren(GenericPredicate(roleName="icon"))
         self.assertEqual(len(samples), 2)
         self.menubar.menu("Project").click()
@@ -201,9 +201,9 @@ class ProjectPropertiesTest(HelpFunc):
         self.tearDown(clean=False, kill=True)
         timestamp = os.path.getmtime(backup_path)
         self.setUp()
-        welcome_dialog = self.pitivi.child(name="Welcome", roleName="frame", recursive=False)
-        welcome_dialog.child(name=filename).doubleClick()
-        self.pitivi.child(roleName="dialog", recursive=False).button("Ignore backup").click()
+        welcome_dialog = self.pitivi.get_child()(name="Welcome", roleName="frame", recursive=False)
+        welcome_dialog.get_child()(name=filename).doubleClick()
+        self.pitivi.get_child()(roleName="dialog", recursive=False).button("Ignore backup").click()
         #Backup is not deleted, not changed
         self.assertEqual(timestamp, os.path.getmtime(backup_path))
 
@@ -216,7 +216,7 @@ class ProjectPropertiesTest(HelpFunc):
         self.menubar.menu("Project").menuItem("Quit").click()
 
         # Dismiss the unsaved changes warning by cancelling it:
-        self.pitivi.child(roleName="dialog", recursive=False).button("Cancel").click()
+        self.pitivi.get_child()(roleName="dialog", recursive=False).button("Cancel").click()
         self.saveProject(saveAs=False)
 
         #Backup should be deleted, and no warning displayed
@@ -225,10 +225,10 @@ class ProjectPropertiesTest(HelpFunc):
         self.assertFalse(os.path.exists(backup_path))
 
     def test_load_save(self):
-        self.nextb = self.pitivi.child(name="Next", roleName="push button")
+        self.nextb = self.pitivi.get_child()(name="Next", roleName="push button")
         tab = self.pitivi.tab("Media Library")
         seektime = self.search_by_text("0:00:00.000", self.pitivi, roleName="text")
-        infobar_media = tab.child(name="Add media to your project by dragging files and folders here or by using the \"Import Files...\" button.")
+        infobar_media = tab.get_child()(name="Add media to your project by dragging files and folders here or by using the \"Import Files...\" button.")
         filename1 = "/tmp/test_project-%i.xptv" % time()
         filename2 = "/tmp/test_project-%i.xptv" % time()
 
@@ -243,7 +243,7 @@ class ProjectPropertiesTest(HelpFunc):
         sleep(0.5)
         self.menubar.menu("Project").click()
         self.menubar.menu("Project").menuItem("New").click()
-        self.pitivi.child(name="Project Settings", roleName="dialog", recursive=False).button("OK").click()
+        self.pitivi.get_child()(name="Project Settings", roleName="dialog", recursive=False).button("OK").click()
 
         icons = tab.findChildren(GenericPredicate(roleName="icon"))
         self.nextb.click()
diff --git a/tests/dogtail_scripts/test_timeline.py b/tests/dogtail_scripts/test_timeline.py
index 96151cf..52450a7 100644
--- a/tests/dogtail_scripts/test_timeline.py
+++ b/tests/dogtail_scripts/test_timeline.py
@@ -10,7 +10,7 @@ from pyatspi import (KEY_SYM, KEY_PRESS, KEY_PRESSRELEASE, KEY_RELEASE)
 class TimelineTest(HelpFunc):
     def setUp(self):
         super(TimelineTest, self).setUp()
-        self.nextb = self.pitivi.child(name="Next", roleName="push button")
+        self.nextb = self.pitivi.get_child()(name="Next", roleName="push button")
 
     def help_test_insertEnd(self):
         sample = self.import_media()
@@ -84,16 +84,16 @@ class TimelineTest(HelpFunc):
         adj = (float)(timeline.size[0]) / 883
 
         dogtail.rawinput.click(timeline.position[0] + 500 * adj, timeline.position[1] + 50)
-        self.pitivi.child(name="Split", roleName="push button").click()
+        self.pitivi.get_child()(name="Split", roleName="push button").click()
         dogtail.rawinput.click(timeline.position[0] + 450 * adj, timeline.position[1] + 50)
-        self.pitivi.child(name="Delete", roleName="push button").click()
+        self.pitivi.get_child()(name="Delete", roleName="push button").click()
 
         self.nextb.click()
         self.assertEqual(seektime.text, "0:00:02.455")
 
         dogtail.rawinput.click(timeline.position[0] + 550 * adj, timeline.position[1] + 50)
         dogtail.rawinput.pressKey("Del")
-        #self.pitivi.child(name="Delete", roleName="push button").click()
+        #self.pitivi.get_child()(name="Delete", roleName="push button").click()
 
         self.nextb.click()
         self.assertEqual(seektime.text, "0:00:01.227")
@@ -113,7 +113,7 @@ class TimelineTest(HelpFunc):
                 sleep(0.1)
                 dogtail.rawinput.pressKey("s")
                 #Just search some object to look if it still alive
-                self.pitivi.child(roleName="icon")
+                self.pitivi.get_child()(roleName="icon")
 
     def test_transition(self):
         self.help_test_insertEndFast()
@@ -136,12 +136,12 @@ class TimelineTest(HelpFunc):
         sleep(1)
         dogtail.rawinput.click(tpos[0] + 250 * adj, tpos[1] + 50)
         #Check if we selected transition
-        transitions = self.pitivi.child(name="Transitions", roleName="page tab")
-        iconlist = transitions.child(roleName="layered pane")
+        transitions = self.pitivi.get_child()(name="Transitions", roleName="page tab")
+        iconlist = transitions.get_child()(roleName="layered pane")
         self.assertTrue(iconlist.sensitive)
         iconlist.children[-2].select()
-        self.assertTrue(transitions.child(roleName="slider").sensitive)
-        transitions.child(roleName="slider").value = 50
+        self.assertTrue(transitions.get_child()(roleName="slider").sensitive)
+        transitions.get_child()(roleName="slider").value = 50
 
     def search_clip_end(self, y, seek, timeline):
         minx = timeline.position[0] + 10.
@@ -187,7 +187,7 @@ class TimelineTest(HelpFunc):
         conftab = self.pitivi.tab("Clip configuration")
         conftab.click()
         center = lambda obj: (obj.position[0] + obj.size[0] / 2, obj.position[1] + obj.size[1] / 2)
-        table = conftab.child(roleName="table")
+        table = conftab.get_child()(roleName="table")
         icon = self.search_by_text("Agingtv ", tab, roleName="icon")
         self.improved_drag(center(icon), center(table))
         self.nextb.click()
diff --git a/tests/runtests.py b/tests/runtests.py
index a94a794..8b22e85 100644
--- a/tests/runtests.py
+++ b/tests/runtests.py
@@ -2,11 +2,11 @@ import os
 import sys
 import unittest
 
-import gobject
-# This call has to be made before any "import gst" call!
+from gi.repository import GObject
+# This call has to be made before any "import Gst" call!
 # We have to do this call here, even though it already is in __init__.py,
 # because this tool is run directly, as an executable.
-gobject.threads_init()
+GObject.threads_init()
 
 
 def gettestnames(file_names):
diff --git a/tests/test_cache.py b/tests/test_cache.py
index ed75827..3ed37a0 100644
--- a/tests/test_cache.py
+++ b/tests/test_cache.py
@@ -1,7 +1,7 @@
 import unittest
 import cairo
 import tempfile
-import gst
+from gi.repository import Gst
 import os
 
 from urllib import unquote
@@ -18,7 +18,7 @@ class ThumbnailsCacheTest(TestCase):
     """
     def setUp(self):
         self.tmpfile = tempfile.NamedTemporaryFile()
-        self.uri = unquote(gst.uri_construct("file", self.tmpfile.name))
+        self.uri = unquote(Gst.uri_construct("file", self.tmpfile.name))
         self.hash = hash_file(self.tmpfile.name)
 
     def tearDown(self):
diff --git a/tests/test_integration.py b/tests/test_integration.py
index 0cbe029..8d4824e 100644
--- a/tests/test_integration.py
+++ b/tests/test_integration.py
@@ -30,9 +30,9 @@ from pitivi.utils.timeline import MoveContext, TrimStartContext,\
 from pitivi.utils.signal import Signallable
 from pitivi.stream import AudioStream, VideoStream
 import pitivi.instance
-import gobject
+from gi.repository import GObject
 import os.path
-import gst
+from gi.repository import Gst
 import random
 
 base_uri = "file:///" + os.getcwd() + "/media/"
@@ -57,7 +57,7 @@ class WatchDog(object):
     def start(self):
         self.will_quit = False
         self.keep_going = True
-        gobject.timeout_add(self.timeout, self._timeoutcb)
+        GObject.timeout_add(self.timeout, self._timeoutcb)
 
     def suspend(self):
         self.keepAlive()
@@ -78,33 +78,33 @@ class WatchDog(object):
 class TestWatchdog(TestCase):
 
     def testWatchdog(self):
-        self.ml = gobject.MainLoop()
+        self.ml = GObject.MainLoop()
         wd = WatchDog(self.ml, 100)
         self.timeout_called = False
         wd.start()
-        gobject.timeout_add(2000, self._timeoutCb)
+        GObject.timeout_add(2000, self._timeoutCb)
         self.ml.run()
         self.assertFalse(self.timeout_called)
         self.assertTrue(wd.activated)
 
     def testKeepAlive(self):
-        self.ml = gobject.MainLoop()
+        self.ml = GObject.MainLoop()
         wd = WatchDog(self.ml, 2000)
         self.timeout_called = False
         wd.start()
-        gobject.timeout_add(500, wd.keepAlive)
-        gobject.timeout_add(2500, self._timeoutCb)
+        GObject.timeout_add(500, wd.keepAlive)
+        GObject.timeout_add(2500, self._timeoutCb)
         self.ml.run()
         self.assertTrue(self.timeout_called)
         self.assertFalse(wd.activated)
 
     def testSuspend(self):
-        self.ml = gobject.MainLoop()
+        self.ml = GObject.MainLoop()
         wd = WatchDog(self.ml, 500)
         self.timeout_called = False
         wd.start()
         wd.suspend()
-        gobject.timeout_add(2000, self._timeoutCb)
+        GObject.timeout_add(2000, self._timeoutCb)
         self.ml.run()
         self.assertTrue(self.timeout_called)
         self.assertFalse(wd.activated)
@@ -314,7 +314,7 @@ class InstanceRunner(Signallable):
             self.instance.run([])
 
     def shutDown(self):
-        gobject.idle_add(self.instance.shutdown)
+        GObject.idle_add(self.instance.shutdown)
         self.project._dirty = False
 
 
@@ -344,7 +344,7 @@ class Brush(Signallable):
         self.priority = finalPriority
         self.count = 0
         self.steps = steps
-        gobject.timeout_add(self.delay, self._scrubTimeoutCb)
+        GObject.timeout_add(self.delay, self._scrubTimeoutCb)
 
     def _scrubTimeoutCb(self):
         self.watchdog.keepAlive()
@@ -451,15 +451,15 @@ class TestBasic(Base):
             test1,
             {
                 "start": 0,
-                "duration": gst.SECOND,
-                "media-start": gst.SECOND,
+                "duration": Gst.SECOND,
+                "media-start": Gst.SECOND,
             })
         config.addSource(
             "object2",
             test2,
             {
-                "start": gst.SECOND,
-                "duration": gst.SECOND,
+                "start": Gst.SECOND,
+                "duration": Gst.SECOND,
             })
 
         def timelineConfigured(runner):
@@ -482,16 +482,16 @@ class TestBasic(Base):
             test1,
             {
                 "start": 0,
-                "duration": gst.SECOND,
-                "media-start": gst.SECOND,
+                "duration": Gst.SECOND,
+                "media-start": Gst.SECOND,
                 "priority": 0
             })
         initial.addSource(
             "object2",
             test2,
             {
-                "start": gst.SECOND,
-                "duration": gst.SECOND,
+                "start": Gst.SECOND,
+                "duration": Gst.SECOND,
                 "priority": 1,
             })
         final = Configuration()
@@ -499,13 +499,13 @@ class TestBasic(Base):
             "object1",
             test1,
             {
-                "start": 10 * gst.SECOND,
+                "start": 10 * Gst.SECOND,
             })
         final.addSource(
             "object2",
             test2,
             {
-                "start": 11 * gst.SECOND,
+                "start": 11 * Gst.SECOND,
                 "priority": 2,
             })
 
@@ -513,7 +513,7 @@ class TestBasic(Base):
             context = MoveContext(self.runner.timeline,
                 self.runner.video1.object1,
                 set((self.runner.audio1.object2,)))
-            brush.scrub(context, 10 * gst.SECOND, 1, steps=10)
+            brush.scrub(context, 10 * Gst.SECOND, 1, steps=10)
 
         def scrubStep(brush, time, priority):
             pass
@@ -535,21 +535,21 @@ class TestBasic(Base):
 
         initial = Configuration()
         initial.addSource('clip1', test1, {
-            "duration": gst.SECOND,
-            "start": gst.SECOND,
+            "duration": Gst.SECOND,
+            "start": Gst.SECOND,
             "priority": 2})
         initial.addSource('clip2', test1, {
-            "duration": gst.SECOND,
-            "start": 2 * gst.SECOND,
+            "duration": Gst.SECOND,
+            "start": 2 * Gst.SECOND,
             "priority": 5})
         final = Configuration()
         final.addSource('clip1', test1, {
-            "duration": gst.SECOND,
-            "start": 11 * gst.SECOND,
+            "duration": Gst.SECOND,
+            "start": 11 * Gst.SECOND,
             "priority": 0})
         final.addSource('clip2', test1, {
-            "duration": gst.SECOND,
-            "start": 12 * gst.SECOND,
+            "duration": Gst.SECOND,
+            "start": 12 * Gst.SECOND,
             "priority": 3})
 
         def timelineConfigured(runner):
@@ -557,7 +557,7 @@ class TestBasic(Base):
             context = MoveContext(self.runner.timeline,
                 self.runner.video1.clip1, set())
             context.setMode(context.RIPPLE)
-            brush.scrub(context, 11 * gst.SECOND, 0, steps=0)
+            brush.scrub(context, 11 * Gst.SECOND, 0, steps=0)
 
         def scrubDone(brush):
             final.matches(self.runner)
@@ -574,35 +574,35 @@ class TestBasic(Base):
         initial = Configuration()
         initial.addSource('clip1', test1,
             {
-                "start": gst.SECOND,
-                "duration": gst.SECOND,
+                "start": Gst.SECOND,
+                "duration": Gst.SECOND,
             })
         initial.addSource('clip2', test1,
             {
-                "start": 2 * gst.SECOND,
-                "duration": gst.SECOND,
+                "start": 2 * Gst.SECOND,
+                "duration": Gst.SECOND,
             })
         initial.addSource('clip3', test1,
             {
-                "start": 5 * gst.SECOND,
-                "duration": 10 * gst.SECOND,
+                "start": 5 * Gst.SECOND,
+                "duration": 10 * Gst.SECOND,
             })
 
         final = Configuration()
         final.addSource('clip1', test1,
             {
-                "start": 6 * gst.SECOND,
-                "duration": gst.SECOND,
+                "start": 6 * Gst.SECOND,
+                "duration": Gst.SECOND,
             })
         final.addSource('clip2', test1,
             {
-                "start": 7 * gst.SECOND,
-                "duration": gst.SECOND,
+                "start": 7 * Gst.SECOND,
+                "duration": Gst.SECOND,
             })
         final.addSource('clip3', test1,
             {
-                "start": 10 * gst.SECOND,
-                "duration": 5 * gst.SECOND,
+                "start": 10 * Gst.SECOND,
+                "duration": 5 * Gst.SECOND,
             })
 
         self.runner.loadConfiguration(initial)
@@ -611,7 +611,7 @@ class TestBasic(Base):
             context = TrimStartContext(self.runner.timeline,
                 self.runner.video1.clip3, set())
             context.setMode(context.RIPPLE)
-            brush.scrub(context, 10 * gst.SECOND, 0)
+            brush.scrub(context, 10 * Gst.SECOND, 0)
         self.runner.connect("timeline-configured", timelineConfigured)
 
         def scrubDone(brush):
@@ -634,8 +634,8 @@ class TestSeeking(Base):
     config = Configuration()
     for i in xrange(0, 10):
         config.addSource("clip%d" % i, test1, {
-            "start": i * gst.SECOND,
-            "duration": gst.SECOND,
+            "start": i * Gst.SECOND,
+            "duration": Gst.SECOND,
             "priority": i % 2,
         })
 
@@ -644,7 +644,7 @@ class TestSeeking(Base):
         self.steps = steps
         self.positions = 0
         self.runner.project.pipeline.connect("position", self._positionCb)
-        gobject.timeout_add(interval, self._seekTimeoutCb)
+        GObject.timeout_add(interval, self._seekTimeoutCb)
 
     def _seekTimeoutCb(self):
         if self.count < self.steps:
@@ -699,7 +699,7 @@ class TestRippleExtensive(Base):
         self.finals = []
         for i in xrange(0, 10):
             self.initial.addSource('clip%d' % i, test1,
-                {'start': gst.SECOND * i, 'duration': gst.SECOND,
+                {'start': Gst.SECOND * i, 'duration': Gst.SECOND,
                     'priority': i % 2})
             # we're going to repeat the same operation using each clip as the
             # focus of the editing context. We create one final
@@ -708,13 +708,13 @@ class TestRippleExtensive(Base):
             for j in xrange(0, 10):
                 if j < i:
                     final.addSource('clip%d' % j, test1,
-                        {'start': gst.SECOND * j,
-                          'duration': gst.SECOND,
+                        {'start': Gst.SECOND * j,
+                          'duration': Gst.SECOND,
                           'priority': j % 2})
                 else:
                     final.addSource('clip%d' % j, test1,
-                        {'start': gst.SECOND * (j + 10),
-                          'duration': gst.SECOND,
+                        {'start': Gst.SECOND * (j + 10),
+                          'duration': Gst.SECOND,
                           'priority': (j % 2) + 1})
             self.finals.append(final)
         Base.__init__(self, unknown)
@@ -745,7 +745,7 @@ class TestRippleExtensive(Base):
         self.context = context
         # this isn't a method, but an attribute that will be set by specific
         # test cases
-        self.scrub_func(context, (cur + 10) * gst.SECOND, (cur % 2) + 1)
+        self.scrub_func(context, (cur + 10) * Gst.SECOND, (cur % 2) + 1)
 
     # when each scrub has finished, verify the current configuration is
     # correct, reset the timeline, and kick off the next scenario. Shut down
@@ -758,7 +758,7 @@ class TestRippleExtensive(Base):
         config.matches(self.runner)
         restore = MoveContext(self.runner.timeline, context.focus, set())
         restore.setMode(restore.RIPPLE)
-        restore.editTo(cur * gst.SECOND, (cur % 2))
+        restore.editTo(cur * Gst.SECOND, (cur % 2))
         restore.finish()
         self.initial.matches(self.runner)
         self.cur += 1
@@ -792,34 +792,34 @@ class TestTransitions(Base):
             test1,
             {
                 "start": 0,
-                "duration": 5 * gst.SECOND,
+                "duration": 5 * Gst.SECOND,
                 "priority": 0,
             })
         initial.addSource(
             "object2",
             test1,
             {
-                "start": 5 * gst.SECOND,
-                "duration": 5 * gst.SECOND,
+                "start": 5 * Gst.SECOND,
+                "duration": 5 * Gst.SECOND,
                 "priority": 0,
             })
         initial.addSource(
             "object3",
             test1,
             {
-                "start": 10 * gst.SECOND,
-                "duration": 5 * gst.SECOND,
+                "start": 10 * Gst.SECOND,
+                "duration": 5 * Gst.SECOND,
                 "priority": 0,
             })
 
         moves = [
-            (9 * gst.SECOND, 0),
-            (1 * gst.SECOND, 0),
+            (9 * Gst.SECOND, 0),
+            (1 * Gst.SECOND, 0),
         ]
 
         expected = [
-            ("object2", "object3", 10 * gst.SECOND, 4 * gst.SECOND, 0),
-            ("object1", "object2", 1 * gst.SECOND, 4 * gst.SECOND, 0),
+            ("object2", "object3", 10 * Gst.SECOND, 4 * Gst.SECOND, 0),
+            ("object1", "object2", 1 * Gst.SECOND, 4 * Gst.SECOND, 0),
         ]
 
         def timelineConfigured(runner):
@@ -867,29 +867,29 @@ class TestTransitions(Base):
             test1,
             {
                 "start": 0,
-                "duration": 5 * gst.SECOND,
+                "duration": 5 * Gst.SECOND,
                 "priority": 0,
             })
         initial.addSource(
             "object2",
             test1,
             {
-                "start": 5 * gst.SECOND,
-                "duration": 5 * gst.SECOND,
+                "start": 5 * Gst.SECOND,
+                "duration": 5 * Gst.SECOND,
                 "priority": 0,
             })
         initial.addSource(
             "object3",
             test1,
             {
-                "start": 10 * gst.SECOND,
-                "duration": 5 * gst.SECOND,
+                "start": 10 * Gst.SECOND,
+                "duration": 5 * Gst.SECOND,
                 "priority": 0,
             })
 
         moves = [
-            ("object1", 9 * gst.SECOND, 0),
-            ("object3", 1 * gst.SECOND, 0),
+            ("object1", 9 * Gst.SECOND, 0),
+            ("object3", 1 * Gst.SECOND, 0),
         ]
 
         def timelineConfigured(runner):
@@ -927,23 +927,23 @@ class TestTransitions(Base):
             test1,
             {
                 "start": 0,
-                "duration": 5 * gst.SECOND,
+                "duration": 5 * Gst.SECOND,
                 "priority": 0,
             })
         initial.addSource(
             "object2",
             test1,
             {
-                "start": 5 * gst.SECOND,
-                "duration": 3 * gst.SECOND,
+                "start": 5 * Gst.SECOND,
+                "duration": 3 * Gst.SECOND,
                 "priority": 0,
             })
         initial.addSource(
             "object3",
             test1,
             {
-                "start": 8 * gst.SECOND,
-                "duration": 5 * gst.SECOND,
+                "start": 8 * Gst.SECOND,
+                "duration": 5 * Gst.SECOND,
                 "priority": 0,
             })
 
@@ -951,39 +951,39 @@ class TestTransitions(Base):
         phase2.updateSource(
             "object2",
             props={
-                "start": 4 * gst.SECOND,
+                "start": 4 * Gst.SECOND,
             })
 
         phase3 = phase2.clone()
         phase3.updateSource(
             "object3",
             props={
-                "duration": 1 * gst.SECOND
+                "duration": 1 * Gst.SECOND
             })
 
         phase4 = initial.clone()
         phase4.updateSource(
             "object2",
             props={
-                "start": 3 * gst.SECOND,
+                "start": 3 * Gst.SECOND,
             })
         phase4.updateSource(
             "object3",
             props={
-                "start": 5 * gst.SECOND,
-                "duration": 5 * gst.SECOND,
+                "start": 5 * Gst.SECOND,
+                "duration": 5 * Gst.SECOND,
             })
 
         moves = [
             # [1------]    [3--[2==]]
-            (MoveContext, "object2", 9 * gst.SECOND, 0, initial, []),
+            (MoveContext, "object2", 9 * Gst.SECOND, 0, initial, []),
 
             # [1--[2=]]    [3-------]
-            (MoveContext, "object2", 1 * gst.SECOND, 0, initial, []),
+            (MoveContext, "object2", 1 * Gst.SECOND, 0, initial, []),
 
             # [1------]    [3-------]
             #        [2--]
-            (MoveContext, "object2", 4 * gst.SECOND, 0, phase2,
+            (MoveContext, "object2", 4 * Gst.SECOND, 0, phase2,
                 [("object1", "object2")]),
 
             # Activates overlap prevention
@@ -991,33 +991,33 @@ class TestTransitions(Base):
             #      [3-------]
             #        [2--]
 
-            (MoveContext, "object3", 3 * gst.SECOND, 0, phase2,
+            (MoveContext, "object3", 3 * Gst.SECOND, 0, phase2,
                 [("object1", "object2")]),
 
             # [1------]  [3-]
             #        [2--]
-            (TrimEndContext, "object3", 9 * gst.SECOND, 0, phase3,
+            (TrimEndContext, "object3", 9 * Gst.SECOND, 0, phase3,
                 [("object1", "object2")]),
 
             # Activates overlap prevention
             # [1------]
             #        [3-]
             #        [2--]
-            (MoveContext, "object3", 4 * gst.SECOND, 0, phase3,
+            (MoveContext, "object3", 4 * Gst.SECOND, 0, phase3,
                 [("object1", "object2")]),
 
             # Activates overlap prevention
             # [1------]
             #       [3]
             #        [2--]
-            (MoveContext, "object3", long(3.5 * gst.SECOND), 0, phase3,
+            (MoveContext, "object3", long(3.5 * Gst.SECOND), 0, phase3,
                 [("object1", "object2")]),
 
             # Activates overlap prevention
             # [1      ]
             #         [3]
             #        [2  ]
-            (MoveContext, "object3", long(4.5 * gst.SECOND), 0,
+            (MoveContext, "object3", long(4.5 * Gst.SECOND), 0,
                 phase3, [("object1", "object2")]),
 
             # Next few commands build this arrangement
@@ -1025,11 +1025,11 @@ class TestTransitions(Base):
             #     [2    ]
             #          [3   ]
 
-            (MoveContext, "object2", 3 * gst.SECOND, 0,
+            (MoveContext, "object2", 3 * Gst.SECOND, 0,
                 None, None),
-            (MoveContext, "object3", 5 * gst.SECOND, 0,
+            (MoveContext, "object3", 5 * Gst.SECOND, 0,
                 None, None),
-            (TrimEndContext, "object3", 10 * gst.SECOND, 0,
+            (TrimEndContext, "object3", 10 * Gst.SECOND, 0,
                 phase4, [("object1", "object2"), ("object2",
                     "object3")]),
 
@@ -1038,7 +1038,7 @@ class TestTransitions(Base):
             #     [2    ]
             #       [3   ]
 
-            (MoveContext, "object3", 4 * gst.SECOND, 0,
+            (MoveContext, "object3", 4 * Gst.SECOND, 0,
                 phase4, [("object1", "object2"),
                     ("object2", "object3")]),
 
diff --git a/tests/test_projectmanager.py b/tests/test_projectmanager.py
index b7f2ed4..28aed64 100644
--- a/tests/test_projectmanager.py
+++ b/tests/test_projectmanager.py
@@ -32,7 +32,7 @@
 #from pitivi.formatters.base import Formatter, \
         #FormatterError, FormatterLoadError
 #import os
-#import gst
+#from gi.repository import Gst
 #from pitivi.utils.misc import uri_is_reachable
 #import time
 
@@ -304,8 +304,8 @@
     #def testSaveProject(self):
         #uri = "file://" + os.path.abspath("testproject.xptv")
         #uri2 = "file://" + os.path.abspath("testproject2.xptv")
-        #path = gst.uri_get_location(uri)
-        #path2 = gst.uri_get_location(uri2)
+        #path = Gst.uri_get_location(uri)
+        #path2 = Gst.uri_get_location(uri2)
 
         ## unlink any existing project files
         #try:
diff --git a/tests/test_still_image.py b/tests/test_still_image.py
index dc095af..30f5550 100644
--- a/tests/test_still_image.py
+++ b/tests/test_still_image.py
@@ -22,8 +22,8 @@
 import os.path
 from unittest import TestCase
 
-import gobject
-import gst
+from gi.repository import GObject
+from gi.repository import Gst
 
 import common
 
@@ -40,18 +40,18 @@ from pitivi.pipeline import Pipeline
 
 
 class TestStillImage(TestCase):
-    clip_duration = 3 * gst.SECOND
+    clip_duration = 3 * Gst.SECOND
 
     def setUp(self):
-        self.mainloop = gobject.MainLoop()
+        self.mainloop = GObject.MainLoop()
 
         samples = os.path.join(os.path.dirname(__file__), "samples")
         self.facs = []
-        self.facs.append([PictureFileSourceFactory('file://' + os.path.join(samples, "flat_colour1_640x480.png")), VideoStream(gst.Caps("video/x-raw-rgb,bpp=(int)24,depth=(int)24,endianness=(int)4321,red_mask=(int)16711680,green_mask=(int)65280,blue_mask=(int)255"))])
-        self.facs.append([PictureFileSourceFactory('file://' + os.path.join(samples, "flat_colour2_640x480.png")), VideoStream(gst.Caps("video/x-raw-rgb,bpp=(int)24,depth=(int)24,endianness=(int)4321,red_mask=(int)16711680,green_mask=(int)65280,blue_mask=(int)255"))])
-        self.facs.append([PictureFileSourceFactory('file://' + os.path.join(samples, "flat_colour3_320x180.png")), VideoStream(gst.Caps("video/x-raw-rgb,bpp=(int)24,depth=(int)24,endianness=(int)4321,red_mask=(int)16711680,green_mask=(int)65280,blue_mask=(int)255"))])
+        self.facs.append([PictureFileSourceFactory('file://' + os.path.join(samples, "flat_colour1_640x480.png")), VideoStream(Gst.Caps("video/x-raw-rgb,bpp=(int)24,depth=(int)24,endianness=(int)4321,red_mask=(int)16711680,green_mask=(int)65280,blue_mask=(int)255"))])
+        self.facs.append([PictureFileSourceFactory('file://' + os.path.join(samples, "flat_colour2_640x480.png")), VideoStream(Gst.Caps("video/x-raw-rgb,bpp=(int)24,depth=(int)24,endianness=(int)4321,red_mask=(int)16711680,green_mask=(int)65280,blue_mask=(int)255"))])
+        self.facs.append([PictureFileSourceFactory('file://' + os.path.join(samples, "flat_colour3_320x180.png")), VideoStream(Gst.Caps("video/x-raw-rgb,bpp=(int)24,depth=(int)24,endianness=(int)4321,red_mask=(int)16711680,green_mask=(int)65280,blue_mask=(int)255"))])
         # one video with a different resolution
-        self.facs.append([VideoTestSourceFactory(), VideoStream(gst.Caps('video/x-raw-yuv,width=(int)640,height=(int)480,format=(fourcc)I420'))])
+        self.facs.append([VideoTestSourceFactory(), VideoStream(Gst.Caps('video/x-raw-yuv,width=(int)640,height=(int)480,format=(fourcc)I420'))])
 
         # configure durations and add output streams to factories
         for fac in self.facs:
diff --git a/tests/test_timeline_undo.py b/tests/test_timeline_undo.py
index b523150..42499ea 100644
--- a/tests/test_timeline_undo.py
+++ b/tests/test_timeline_undo.py
@@ -28,7 +28,7 @@
 
 #from unittest import TestCase
 
-#import gst
+#from gi.repository import Gst
 
 #from pitivi.pipeline import Pipeline
 #from pitivi.utils.timeline import Timeline, TimelineObject, SELECT_ADD
@@ -59,7 +59,7 @@
 
 
 #def new_stream():
-    #return VideoStream(gst.Caps("video/x-raw-rgb"))
+    #return VideoStream(Gst.Caps("video/x-raw-rgb"))
 
 
 #def new_source_factory():
@@ -232,11 +232,11 @@
             #stacks.append(stack)
         #self.action_log.connect("commit", commitCb)
 
-        #self.timeline_object1.start = 5 * gst.SECOND
-        #self.timeline_object1.duration = 20 * gst.SECOND
+        #self.timeline_object1.start = 5 * Gst.SECOND
+        #self.timeline_object1.duration = 20 * Gst.SECOND
         #self.timeline.addTimelineObject(self.timeline_object1)
         #self.action_log.begin("modify clip")
-        #self.timeline_object1.start = 10 * gst.SECOND
+        #self.timeline_object1.start = 10 * Gst.SECOND
         #self.action_log.commit()
 
         #self.failUnlessEqual(len(stacks), 1)
@@ -245,11 +245,11 @@
         #action = stack.done_actions[0]
         #self.failUnless(isinstance(action, TimelineObjectPropertyChanged))
 
-        #self.failUnlessEqual(self.timeline_object1.start, 10 * gst.SECOND)
+        #self.failUnlessEqual(self.timeline_object1.start, 10 * Gst.SECOND)
         #self.action_log.undo()
-        #self.failUnlessEqual(self.timeline_object1.start, 5 * gst.SECOND)
+        #self.failUnlessEqual(self.timeline_object1.start, 5 * Gst.SECOND)
         #self.action_log.redo()
-        #self.failUnlessEqual(self.timeline_object1.start, 10 * gst.SECOND)
+        #self.failUnlessEqual(self.timeline_object1.start, 10 * Gst.SECOND)
 
         #self.timeline_object1.priority = 10
         #self.action_log.begin("priority change")
@@ -263,17 +263,17 @@
         #self.failUnlessEqual(self.timeline_object1.priority, 20)
 
     #def testUngroup(self):
-        #self.timeline_object1.start = 5 * gst.SECOND
-        #self.timeline_object1.duration = 20 * gst.SECOND
+        #self.timeline_object1.start = 5 * Gst.SECOND
+        #self.timeline_object1.duration = 20 * Gst.SECOND
 
         #self.timeline.addTimelineObject(self.timeline_object1)
         #self.timeline.setSelectionToObj(self.track_object1, SELECT_ADD)
 
         #self.failUnlessEqual(len(self.timeline.timeline_objects), 1)
         #self.failUnlessEqual(self.timeline.timeline_objects[0].start,
-                #5 * gst.SECOND)
+                #5 * Gst.SECOND)
         #self.failUnlessEqual(self.timeline.timeline_objects[0].duration,
-                #20 * gst.SECOND)
+                #20 * Gst.SECOND)
 
         #self.action_log.begin("ungroup")
         #self.timeline.ungroupSelection()
@@ -281,18 +281,18 @@
 
         #self.failUnlessEqual(len(self.timeline.timeline_objects), 2)
         #self.failUnlessEqual(self.timeline.timeline_objects[0].start,
-                #5 * gst.SECOND)
+                #5 * Gst.SECOND)
         #self.failUnlessEqual(self.timeline.timeline_objects[0].duration,
-                #20 * gst.SECOND)
+                #20 * Gst.SECOND)
         #self.failUnlessEqual(self.timeline.timeline_objects[1].start,
-                #5 * gst.SECOND)
+                #5 * Gst.SECOND)
         #self.failUnlessEqual(self.timeline.timeline_objects[1].duration,
-                #20 * gst.SECOND)
+                #20 * Gst.SECOND)
 
         #self.action_log.undo()
 
         #self.failUnlessEqual(len(self.timeline.timeline_objects), 1)
         #self.failUnlessEqual(self.timeline.timeline_objects[0].start,
-                #5 * gst.SECOND)
+                #5 * Gst.SECOND)
         #self.failUnlessEqual(self.timeline.timeline_objects[0].duration,
-                #20 * gst.SECOND)
+                #20 * Gst.SECOND)
diff --git a/tests/test_utils.py b/tests/test_utils.py
index 3076f91..52608cf 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -22,10 +22,10 @@
 
 from unittest import TestCase
 
-import gst
+from gi.repository import Gst
 from pitivi.utils.ui import beautify_length
 
-second = gst.SECOND
+second = Gst.SECOND
 minute = second * 60
 hour = minute * 60
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]