[pitivi] Use GObject.Object instead of Signallable
- From: Thibault Saunier <tsaunier src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pitivi] Use GObject.Object instead of Signallable
- Date: Wed, 24 Sep 2014 17:05:11 +0000 (UTC)
commit 0de1e04eff4c2a6077467bc14b537fd616844278
Author: Alexandru Băluț <alexandru balut gmail com>
Date: Tue Apr 22 09:31:56 2014 +0200
Use GObject.Object instead of Signallable
pitivi/application.py | 5 +-
pitivi/dialogs/filelisterrordialog.py | 17 +-
pitivi/dialogs/prefs.py | 2 +-
pitivi/dialogs/startupwizard.py | 6 +-
pitivi/medialibrary.py | 24 +--
pitivi/project.py | 37 ++--
pitivi/render.py | 20 ++-
pitivi/settings.py | 32 +++-
pitivi/timeline/previewers.py | 68 +++++---
pitivi/titleeditor.py | 2 -
pitivi/transitions.py | 11 +-
pitivi/undo/effect.py | 3 +
pitivi/undo/medialibrary.py | 2 +
pitivi/undo/timeline.py | 43 ++++--
pitivi/undo/undo.py | 76 +++++----
pitivi/utils/pipeline.py | 100 +++++------
pitivi/utils/signal.py | 258 ---------------------------
pitivi/utils/system.py | 14 +-
pitivi/utils/threads.py | 17 +-
pitivi/utils/timeline.py | 34 ++--
tests/Makefile.am | 1 -
tests/test_application.py | 21 +--
tests/test_project.py | 70 ++++----
tests/test_signallable.py | 311 ---------------------------------
tests/test_undo.py | 4 +
25 files changed, 330 insertions(+), 848 deletions(-)
---
diff --git a/pitivi/application.py b/pitivi/application.py
index cd49a16..a2d9863 100644
--- a/pitivi/application.py
+++ b/pitivi/application.py
@@ -57,7 +57,7 @@ class Pitivi(Gtk.Application, Loggable):
"""
__gsignals__ = {
- 'version-info-received': (GObject.SIGNAL_RUN_LAST, None, (object,))
+ "version-info-received": (GObject.SIGNAL_RUN_LAST, None, (object,))
}
def __init__(self):
@@ -72,7 +72,7 @@ class Pitivi(Gtk.Application, Loggable):
self.system = None
self.project_manager = ProjectManager(self)
- self.action_log = None
+ self.action_log = UndoableActionLog()
self.timeline_log_observer = None
self.project_log_observer = None
@@ -99,7 +99,6 @@ class Pitivi(Gtk.Application, Loggable):
self.effects = EffectsHandler()
self.system = getSystem()
- self.action_log = UndoableActionLog()
self.action_log.connect("commit", self._actionLogCommit)
self.action_log.connect("undo", self._actionLogUndo)
self.action_log.connect("redo", self._actionLogRedo)
diff --git a/pitivi/dialogs/filelisterrordialog.py b/pitivi/dialogs/filelisterrordialog.py
index 26f2585..fb08d94 100644
--- a/pitivi/dialogs/filelisterrordialog.py
+++ b/pitivi/dialogs/filelisterrordialog.py
@@ -23,25 +23,28 @@
Dialog box listing files which had errors, and the reasons.
"""
-from gi.repository import Gtk
import os
+from urllib.parse import unquote
+
+from gi.repository import GObject
+from gi.repository import Gtk
from gi.repository import Pango
from gettext import gettext as _
-from urllib.parse import unquote
from pitivi.configure import get_ui_dir
-from pitivi.utils.signal import Signallable
from pitivi.utils.loggable import Loggable
-class FileListErrorDialog(Signallable, Loggable):
+class FileListErrorDialog(GObject.Object, Loggable):
""" Dialog box for showing errors in a list of files """
- __signals__ = {
- 'close': None,
- 'response': ["something"]}
+
+ __gsignals__ = {
+ 'close': (GObject.SIGNAL_RUN_LAST, None, ()),
+ 'response': (GObject.SIGNAL_RUN_LAST, None, (object,))}
def __init__(self, title, headline):
+ GObject.Object.__init__(self)
Loggable.__init__(self)
self.builder = Gtk.Builder()
self.builder.add_from_file(os.path.join(get_ui_dir(),
diff --git a/pitivi/dialogs/prefs.py b/pitivi/dialogs/prefs.py
index 3435a22..acc515b 100644
--- a/pitivi/dialogs/prefs.py
+++ b/pitivi/dialogs/prefs.py
@@ -369,7 +369,7 @@ class PreferencesDialog(object):
value = getattr(self.settings, attrname)
if attrname not in self.original_values:
self.original_values[attrname] = value
- if attrname + "Changed" not in GlobalSettings.get_signals():
+ if not GlobalSettings.notifiesConfigOption(attrname):
self.restart_warning.show()
self.revert_button.set_sensitive(True)
diff --git a/pitivi/dialogs/startupwizard.py b/pitivi/dialogs/startupwizard.py
index 8ed3828..ba1d7c6 100644
--- a/pitivi/dialogs/startupwizard.py
+++ b/pitivi/dialogs/startupwizard.py
@@ -147,9 +147,9 @@ class StartUpWizard(object):
@type project_manager: L{ProjectManager}
"""
if fully_loaded:
- project_manager.disconnect_by_function(self._projectFailedCb)
- project_manager.disconnect_by_function(self._projectLoadedCb)
- project_manager.disconnect_by_function(self._projectLoadingCb)
+ project_manager.disconnect_by_func(self._projectFailedCb)
+ project_manager.disconnect_by_func(self._projectLoadedCb)
+ project_manager.disconnect_by_func(self._projectLoadingCb)
def _projectLoadingCb(self, unused_project_manager, unused_project):
"""Handle the start of a project load operation."""
diff --git a/pitivi/medialibrary.py b/pitivi/medialibrary.py
index 4472674..622aada 100644
--- a/pitivi/medialibrary.py
+++ b/pitivi/medialibrary.py
@@ -50,7 +50,6 @@ from pitivi.dialogs.filelisterrordialog import FileListErrorDialog
from pitivi.dialogs.clipmediaprops import ClipMediaPropsDialog
from pitivi.utils.ui import beautify_length
from pitivi.utils.misc import PathWalker, quote_uri, path_from_uri
-from pitivi.utils.signal import SignalGroup
from pitivi.utils.loggable import Loggable
import pitivi.utils.ui as dnd
from pitivi.utils.ui import beautify_info, info_name, SPACING
@@ -251,7 +250,6 @@ class MediaLibraryWidget(Gtk.VBox, Loggable):
# Connect to project. We must remove and reset the callbacks when
# changing project.
- self.project_signals = SignalGroup()
project_manager = self.app.project_manager
project_manager.connect("new-project-created", self._newProjectCreatedCb)
project_manager.connect("new-project-loaded", self._newProjectLoadedCb)
@@ -396,21 +394,14 @@ class MediaLibraryWidget(Gtk.VBox, Loggable):
return icon
def _connectToProject(self, project):
- """Connect signal handlers to a project.
-
- This first disconnects any handlers connected to an old project.
- If project is None, this just disconnects any connected handlers.
"""
- self.project_signals.connect(project, "asset-added", None,
- self._assetAddedCb)
- self.project_signals.connect(project, "asset-removed", None,
- self._assetRemovedCb)
- self.project_signals.connect(project, "error-loading-asset",
- None, self._errorCreatingAssetCb)
- self.project_signals.connect(project, "done-importing", None,
- self._sourcesStoppedImportingCb)
- self.project_signals.connect(project, "start-importing", None,
- self._sourcesStartedImportingCb)
+ Connect signal handlers to a project.
+ """
+ project.connect("asset-added", self._assetAddedCb)
+ project.connect("asset-removed", self._assetRemovedCb)
+ project.connect("error-loading-asset", self._errorCreatingAssetCb)
+ project.connect("done-importing", self._sourcesStoppedImportingCb)
+ project.connect("start-importing", self._sourcesStartedImportingCb)
# The start-importing signal would have already been emited at that
# time, make sure to catch if it is the case
@@ -1008,7 +999,6 @@ class MediaLibraryWidget(Gtk.VBox, Loggable):
def _newProjectFailedCb(self, unused_pitivi, unused_reason, unused_uri):
self.storemodel.clear()
- self.project_signals.disconnectAll()
self._project = None
def _addUris(self, uris):
diff --git a/pitivi/project.py b/pitivi/project.py
index c554927..e3a8f5b 100644
--- a/pitivi/project.py
+++ b/pitivi/project.py
@@ -43,7 +43,6 @@ from pitivi.configure import get_ui_dir
from pitivi.utils.misc import quote_uri, path_from_uri, isWritable
from pitivi.utils.pipeline import PipelineError, Seeker
from pitivi.utils.loggable import Loggable
-from pitivi.utils.signal import Signallable
from pitivi.utils.pipeline import Pipeline
from pitivi.utils.widgets import FractionWidget
from pitivi.utils.ripple_update_group import RippleUpdateGroup
@@ -64,6 +63,7 @@ DEFAULT_AUDIO_ENCODER = "vorbisenc"
class AssetRemovedAction(UndoableAction):
def __init__(self, project, asset):
+ UndoableAction.__init__(self)
self.project = project
self.asset = asset
@@ -76,6 +76,7 @@ class AssetRemovedAction(UndoableAction):
class AssetAddedAction(UndoableAction):
def __init__(self, project, asset):
+ UndoableAction.__init__(self)
self.project = project
self.asset = asset
@@ -89,6 +90,7 @@ class AssetAddedAction(UndoableAction):
class ProjectSettingsChanged(UndoableAction):
def __init__(self, project, old, new):
+ UndoableAction.__init__(self)
self.project = project
self.oldsettings = old
self.newsettings = new
@@ -105,6 +107,7 @@ class ProjectSettingsChanged(UndoableAction):
class ProjectLogObserver(UndoableAction):
def __init__(self, log):
+ UndoableAction.__init__(self)
self.log = log
def startObserving(self, project):
@@ -141,30 +144,28 @@ class ProjectLogObserver(UndoableAction):
self.log.push(action)
-class ProjectManager(Signallable, Loggable):
+class ProjectManager(GObject.Object, Loggable):
"""
@type app: L{Pitivi}
@type current_project: L{Project}
@param disable_save: Whether saving is disabled to enforce using save-as.
"""
- __signals__ = {
- "new-project-loading": ["uri"],
- "new-project-created": ["project"],
- "new-project-failed": ["uri", "exception"],
- "new-project-loaded": ["project", "fully_ready"],
- "save-project-failed": ["uri", "exception"],
- "project-saved": ["project", "uri"],
- "closing-project": ["project"],
- "project-closed": ["project"],
- "missing-uri": ["formatter", "uri", "factory"],
- "reverting-to-saved": ["project"],
+ __gsignals__ = {
+ "new-project-loading": (GObject.SIGNAL_RUN_LAST, None, (str,)),
+ "new-project-created": (GObject.SIGNAL_RUN_LAST, None, (object,)),
+ "new-project-failed": (GObject.SIGNAL_RUN_LAST, None, (str, object)),
+ "new-project-loaded": (GObject.SIGNAL_RUN_LAST, None, (object, bool)),
+ "save-project-failed": (GObject.SIGNAL_RUN_LAST, None, (str, object)),
+ "project-saved": (GObject.SIGNAL_RUN_LAST, None, (object, str)),
+ "closing-project": (GObject.SIGNAL_RUN_LAST, bool, (object,)),
+ "project-closed": (GObject.SIGNAL_RUN_LAST, None, (object,)),
+ "missing-uri": (GObject.SIGNAL_RUN_LAST, str, (object, str, object)),
+ "reverting-to-saved": (GObject.SIGNAL_RUN_LAST, bool, (object,)),
}
- _instance = None
-
def __init__(self, app):
- Signallable.__init__(self)
+ GObject.Object.__init__(self)
Loggable.__init__(self)
self.app = app
self.current_project = None
@@ -533,7 +534,7 @@ class ProjectManager(Signallable, Loggable):
name, ext = os.path.splitext(uri)
return name + ext + "~"
- def _missingURICb(self, project, error, asset, unused_what=None):
+ def _missingURICb(self, project, error, asset):
return self.emit("missing-uri", project, error, asset)
def _projectLoadedCb(self, unused_project, unused_timeline):
@@ -848,7 +849,7 @@ class Project(Loggable, GES.Project):
@render_scale.setter
def render_scale(self, value):
if value:
- return self.set_meta("render-scale", value)
+ self.set_meta("render-scale", value)
# ------------------------------------------ #
# GES.Project virtual methods implementation #
diff --git a/pitivi/render.py b/pitivi/render.py
index bbd02a7..ecf642f 100644
--- a/pitivi/render.py
+++ b/pitivi/render.py
@@ -28,10 +28,11 @@ import os
import subprocess
import time
+from gi.repository import GES
from gi.repository import GLib
-from gi.repository import Gtk
+from gi.repository import GObject
from gi.repository import Gst
-from gi.repository import GES
+from gi.repository import Gtk
from gettext import gettext as _
@@ -41,7 +42,6 @@ from pitivi.check import PYCANBERRA_SOFT_DEPENDENCY
from pitivi.utils.loggable import Loggable
from pitivi.utils.misc import show_user_manual, path_from_uri
from pitivi.utils.ripple_update_group import RippleUpdateGroup
-from pitivi.utils.signal import Signallable
from pitivi.utils.ui import model, frame_rates, audio_rates,\
audio_channels, get_combo_value, set_combo_value, beautify_ETA
from pitivi.utils.widgets import GstElementSettingsDialog
@@ -220,14 +220,18 @@ def factorylist(factories):
return model(columns, data)
-#--------------------------------- Public classes -----------------------------#
-class RenderingProgressDialog(Signallable):
- __signals__ = {
- "pause": [],
- "cancel": [],
+# --------------------------------- Public classes -----------------------------#
+
+class RenderingProgressDialog(GObject.Object):
+
+ __gsignals__ = {
+ "pause": (GObject.SIGNAL_RUN_LAST, None, ()),
+ "cancel": (GObject.SIGNAL_RUN_LAST, None, ()),
}
def __init__(self, app, parent):
+ GObject.Object.__init__(self)
+
self.app = app
self.main_render_dialog = parent
self.builder = Gtk.Builder()
diff --git a/pitivi/settings.py b/pitivi/settings.py
index b324f8a..90739a3 100644
--- a/pitivi/settings.py
+++ b/pitivi/settings.py
@@ -23,8 +23,7 @@ import os
from configparser import SafeConfigParser, ParsingError
from gi.repository import GLib
-
-from pitivi.utils.signal import Signallable
+from gi.repository import GObject
def get_bool_env(var):
@@ -102,7 +101,11 @@ class Notification(object):
def __init__(self, attrname):
self.attrname = "_" + attrname
- self.signame = attrname + "Changed"
+ self.signame = self.signalName(attrname)
+
+ @staticmethod
+ def signalName(attrname):
+ return attrname + "Changed"
def __get__(self, instance, unused):
return getattr(instance, self.attrname)
@@ -112,7 +115,7 @@ class Notification(object):
instance.emit(self.signame)
-class GlobalSettings(Signallable):
+class GlobalSettings(GObject.Object):
"""
Pitivi app settings.
@@ -130,10 +133,11 @@ class GlobalSettings(Signallable):
options = {}
environment = set()
defaults = {}
- __signals__ = {}
+
+ __gsignals__ = {}
def __init__(self, **unused_kwargs):
- Signallable.__init__(self)
+ GObject.Object.__init__(self)
self._config = SafeConfigParser()
self._readSettingsFromConfigurationFile()
self._readSettingsFromEnvironmentVariables()
@@ -278,7 +282,7 @@ class GlobalSettings(Signallable):
signals when modified (default is False).
@type notify: C{boolean}
"""
- if section and not section in cls.options:
+ if section and section not in cls.options:
raise ConfigError("You must add the section \"%s\" first." % section)
if key and not section:
raise ConfigError("You must specify a section for key \"%s\"" % key)
@@ -295,9 +299,14 @@ class GlobalSettings(Signallable):
if not type_:
type_ = type(default)
if notify:
- setattr(cls, attrname, Notification(attrname))
+ notification = Notification(attrname)
+ setattr(cls, attrname, notification)
setattr(cls, "_" + attrname, default)
- cls.__signals__[attrname + 'Changed'] = []
+ GObject.signal_new(notification.signame,
+ cls,
+ GObject.SIGNAL_RUN_LAST,
+ None,
+ ())
else:
setattr(cls, attrname, default)
if section and key:
@@ -316,3 +325,8 @@ class GlobalSettings(Signallable):
if section in cls.options:
raise ConfigError("Duplicate Section \"%s\"." % section)
cls.options[section] = {}
+
+ @classmethod
+ def notifiesConfigOption(cls, attrname):
+ signal_name = Notification.signalName(attrname)
+ GObject.signal_lookup(signal_name, cls)
diff --git a/pitivi/timeline/previewers.py b/pitivi/timeline/previewers.py
index b65bd83..302faf6 100644
--- a/pitivi/timeline/previewers.py
+++ b/pitivi/timeline/previewers.py
@@ -21,7 +21,6 @@
# Boston, MA 02110-1301, USA.
from datetime import datetime, timedelta
-from gi.repository import Clutter, Gst, GLib, GdkPixbuf, Cogl, GES
from random import randrange
import cairo
import numpy
@@ -29,6 +28,14 @@ import os
import pickle
import sqlite3
+from gi.repository import Clutter
+from gi.repository import Cogl
+from gi.repository import GES
+from gi.repository import GObject
+from gi.repository import GLib
+from gi.repository import GdkPixbuf
+from gi.repository import Gst
+
# Our C module optimizing waveforms rendering
try:
from . import renderer
@@ -37,7 +44,6 @@ except ImportError:
import renderer
from pitivi.settings import get_dir, xdg_cache_home
-from pitivi.utils.signal import Signallable
from pitivi.utils.loggable import Loggable
from pitivi.utils.misc import binary_search, filename_from_uri, quantize, quote_uri, hash_file, format_ns
from pitivi.utils.system import CPUUsageTracker
@@ -55,6 +61,12 @@ THUMB_MARGIN_PX = 3
WAVEFORM_UPDATE_INTERVAL = timedelta(microseconds=500000)
MARGIN = 500 # For the waveforms, ensures we always have a little extra surface when scrolling while
playing.
+PREVIEW_GENERATOR_SIGNALS = {
+ "done": (GObject.SIGNAL_RUN_LAST, None, ()),
+ "error": (GObject.SIGNAL_RUN_LAST, None, ()),
+}
+
+
"""
Convention throughout this file:
Every GES element which name could be mistaken with a UI element
@@ -67,10 +79,9 @@ class PreviewGeneratorManager():
Manage the execution of PreviewGenerators
"""
def __init__(self):
- self._cpipeline = {
- GES.TrackType.AUDIO: None,
- GES.TrackType.VIDEO: None
- }
+ # The current PreviewGenerator per GES.TrackType.
+ self._cpipeline = {}
+ # The queue of PreviewGenerators.
self._pipelines = {
GES.TrackType.AUDIO: [],
GES.TrackType.VIDEO: []
@@ -79,32 +90,33 @@ class PreviewGeneratorManager():
def addPipeline(self, pipeline):
track_type = pipeline.track_type
+ current_pipeline = self._cpipeline.get(track_type)
if pipeline in self._pipelines[track_type] or \
- pipeline is self._cpipeline[track_type]:
+ pipeline is current_pipeline:
+ # Already in the queue or already processing.
return
- if not self._pipelines[track_type] and self._cpipeline[track_type] is None:
+ if not self._pipelines[track_type] and current_pipeline is None:
self._setPipeline(pipeline)
else:
self._pipelines[track_type].insert(0, pipeline)
def _setPipeline(self, pipeline):
self._cpipeline[pipeline.track_type] = pipeline
- PreviewGenerator.connect(pipeline, "done", self._nextPipeline)
+ pipeline.connect("done", self._nextPipeline)
pipeline.startGeneration()
def _nextPipeline(self, controlled):
track_type = controlled.track_type
- if self._cpipeline[track_type]:
- PreviewGenerator.disconnect_by_function(self._cpipeline[track_type],
- self._nextPipeline)
- self._cpipeline[track_type] = None
+ pipeline = self._cpipeline.pop(track_type, None)
+ if pipeline:
+ pipeline.disconnect_by_func(self._nextPipeline)
if self._pipelines[track_type]:
self._setPipeline(self._pipelines[track_type].pop())
-class PreviewGenerator(Signallable):
+class PreviewGenerator(object):
"""
Interface to be implemented by classes that generate previews
It is need to implement it so PreviewGeneratorManager can manage
@@ -115,16 +127,10 @@ class PreviewGenerator(Signallable):
# all the generators.
__manager = PreviewGeneratorManager()
- __signals__ = {
- "done": [],
- "error": [],
- }
-
def __init__(self, track_type):
"""
@param track_type : GES.TrackType.*
"""
- Signallable.__init__(self)
self.track_type = track_type
def startGeneration(self):
@@ -141,16 +147,21 @@ class PreviewGenerator(Signallable):
class VideoPreviewer(Clutter.ScrollActor, PreviewGenerator, Zoomable, Loggable):
+
+ # We could define them in PreviewGenerator, but then for some reason they
+ # are ignored.
+ __gsignals__ = PREVIEW_GENERATOR_SIGNALS
+
def __init__(self, bElement, timeline):
"""
@param bElement : the backend GES.TrackElement
@param track : the track to which the bElement belongs
@param timeline : the containing graphic timeline.
"""
- Zoomable.__init__(self)
Clutter.ScrollActor.__init__(self)
- Loggable.__init__(self)
PreviewGenerator.__init__(self, GES.TrackType.VIDEO)
+ Zoomable.__init__(self)
+ Loggable.__init__(self)
# Variables related to the timeline objects
self.timeline = timeline
@@ -523,7 +534,7 @@ class VideoPreviewer(Clutter.ScrollActor, PreviewGenerator, Zoomable, Loggable):
self.pipeline.set_state(Gst.State.NULL)
self.pipeline.get_state(Gst.CLOCK_TIME_NONE)
self.pipeline = None
- PreviewGenerator.emit(self, "done")
+ self.emit("done")
def cleanup(self):
self.stopGeneration()
@@ -537,7 +548,6 @@ class Thumbnail(Clutter.Actor):
self.props.content = image
self.width = width
self.height = height
- #self.set_background_color(Clutter.Color.new(0, 100, 150, 100))
self.set_opacity(0)
self.set_size(self.width, self.height)
self.has_pixel_data = False
@@ -619,7 +629,7 @@ class ThumbnailCache(Loggable):
self.warning("JPEG compression failed")
return
blob = sqlite3.Binary(jpeg)
- #Replace if the key already existed
+ # Replace if a row with the same time already exists.
self._cur.execute("DELETE FROM Thumbs WHERE time=?", (key,))
self._cur.execute("INSERT INTO Thumbs VALUES (?,?)", (key, blob,))
@@ -725,11 +735,15 @@ class AudioPreviewer(Clutter.Actor, PreviewGenerator, Zoomable, Loggable):
"""
Audio previewer based on the results from the "level" gstreamer element.
"""
+
+ __gsignals__ = PREVIEW_GENERATOR_SIGNALS
+
def __init__(self, bElement, timeline):
Clutter.Actor.__init__(self)
+ PreviewGenerator.__init__(self, GES.TrackType.AUDIO)
Zoomable.__init__(self)
Loggable.__init__(self)
- PreviewGenerator.__init__(self, GES.TrackType.AUDIO)
+
self.pipeline = None
self.discovered = False
self.bElement = bElement
@@ -967,7 +981,7 @@ class AudioPreviewer(Clutter.Actor, PreviewGenerator, Zoomable, Loggable):
self.pipeline.set_state(Gst.State.NULL)
self.pipeline.get_state(Gst.CLOCK_TIME_NONE)
- PreviewGenerator.emit(self, "done")
+ self.emit("done")
def cleanup(self):
self.stopGeneration()
diff --git a/pitivi/titleeditor.py b/pitivi/titleeditor.py
index a95ecf3..34097b1 100644
--- a/pitivi/titleeditor.py
+++ b/pitivi/titleeditor.py
@@ -33,7 +33,6 @@ from gettext import gettext as _
from pitivi.configure import get_ui_dir
from pitivi.utils.loggable import Loggable
from pitivi.utils.pipeline import Seeker
-from pitivi.utils.signal import Signallable
from pitivi.utils.timeline import SELECT
from pitivi.utils.ui import argb_to_gdk_rgba, gdk_rgba_to_argb
@@ -51,7 +50,6 @@ class TitleEditor(Loggable):
def __init__(self, app):
Loggable.__init__(self)
- Signallable.__init__(self)
self.app = app
self.settings = {}
self.source = None
diff --git a/pitivi/transitions.py b/pitivi/transitions.py
index 7e8afea..f58fbb9 100644
--- a/pitivi/transitions.py
+++ b/pitivi/transitions.py
@@ -22,8 +22,9 @@
import os
-from gi.repository import GLib
from gi.repository import GES
+from gi.repository import GLib
+from gi.repository import GObject
from gi.repository import Gtk
from gi.repository import GdkPixbuf
@@ -31,8 +32,8 @@ from gettext import gettext as _
from pitivi.configure import get_pixmap_dir
from pitivi.utils.loggable import Loggable
-from pitivi.utils.signal import Signallable
-from pitivi.utils.ui import SPACING, PADDING
+from pitivi.utils.ui import SPACING
+
(COL_TRANSITION_ASSET,
COL_NAME_TEXT,
@@ -40,7 +41,7 @@ from pitivi.utils.ui import SPACING, PADDING
COL_ICON) = list(range(4))
-class TransitionsListWidget(Signallable, Gtk.VBox, Loggable):
+class TransitionsListWidget(Gtk.VBox, Loggable):
"""
Widget for configuring the selected transition.
@@ -50,7 +51,6 @@ class TransitionsListWidget(Signallable, Gtk.VBox, Loggable):
def __init__(self, app):
Gtk.VBox.__init__(self)
Loggable.__init__(self)
- Signallable.__init__(self)
self.app = app
self.element = None
@@ -358,4 +358,3 @@ class TransitionsListWidget(Signallable, Gtk.VBox, Loggable):
text = self.searchEntry.get_text().lower()
return text in model.get_value(iter, COL_DESC_TEXT).lower() or\
text in model.get_value(iter, COL_NAME_TEXT).lower()
- return False
diff --git a/pitivi/undo/effect.py b/pitivi/undo/effect.py
index f854009..efe5663 100644
--- a/pitivi/undo/effect.py
+++ b/pitivi/undo/effect.py
@@ -29,6 +29,7 @@ from pitivi.effects import PROPS_TO_IGNORE
class EffectPropertyChanged(UndoableAction):
def __init__(self, effect, property_name, old_value, new_value):
+ UndoableAction.__init__(self)
self.effect = effect
self.property_name = property_name
self.old_value = old_value
@@ -89,6 +90,7 @@ class EffectAdded(UndoableAction):
# to the Effect when undoing so we reset theirs effect when
# doing it again. The way of doing it is the same with EffectRemoved
def __init__(self, clip, effect, properties_watcher):
+ UndoableAction.__init__(self)
self.clip = clip
self.effect = effect
self.asset = effect.get_asset()
@@ -121,6 +123,7 @@ class EffectAdded(UndoableAction):
class EffectRemoved(UndoableAction):
def __init__(self, clip, effect, properties_watcher):
+ UndoableAction.__init__(self)
self.effect = effect
self.clip = clip
self.asset = effect.get_asset()
diff --git a/pitivi/undo/medialibrary.py b/pitivi/undo/medialibrary.py
index 8bd6623..1b27941 100644
--- a/pitivi/undo/medialibrary.py
+++ b/pitivi/undo/medialibrary.py
@@ -24,6 +24,7 @@ from pitivi.undo.undo import UndoableAction
class MediaLibrarySourceAddedAction(UndoableAction):
def __init__(self, medialibrary, source):
+ UndoableAction.__init__(self)
self.medialibrary = medialibrary
self.source = source
@@ -38,6 +39,7 @@ class MediaLibrarySourceAddedAction(UndoableAction):
class MediaLibrarySourceRemovedAction(UndoableAction):
def __init__(self, medialibrary, uri, source):
+ UndoableAction.__init__(self)
self.medialibrary = medialibrary
self.uri = uri
self.source = source
diff --git a/pitivi/undo/timeline.py b/pitivi/undo/timeline.py
index ca9e231..9bb4ffc 100644
--- a/pitivi/undo/timeline.py
+++ b/pitivi/undo/timeline.py
@@ -20,7 +20,8 @@
# Boston, MA 02110-1301, USA.
from gi.repository import GES
-from pitivi.utils.signal import Signallable
+from gi.repository import GObject
+
from pitivi.undo.undo import PropertyChangeTracker, UndoableAction
from pitivi.undo.effect import EffectAdded, EffectRemoved
from pitivi.undo.effect import EffectGstElementPropertyChangeTracker
@@ -30,6 +31,9 @@ class ClipPropertyChangeTracker(PropertyChangeTracker):
# no out-point
property_names = ["start", "duration", "in-point", "priority"]
+ def __init__(self):
+ PropertyChangeTracker.__init__(self)
+
def connectToObject(self, obj):
PropertyChangeTracker.connectToObject(self, obj)
self.timeline = obj.timeline
@@ -47,9 +51,10 @@ class ClipPropertyChangeTracker(PropertyChangeTracker):
self._propertyChangedCb(self.obj, property_value, property_name)
-class KeyframeChangeTracker(Signallable):
- __signals__ = {
- "keyframe-moved": ["keyframe"]
+class KeyframeChangeTracker(GObject.Object):
+
+ __gsignals__ = {
+ "keyframe-moved": (GObject.SIGNAL_RUN_LAST, None, (object, object, object, object)),
}
def __init__(self):
@@ -91,7 +96,9 @@ class KeyframeChangeTracker(Signallable):
class ClipPropertyChanged(UndoableAction):
+
def __init__(self, clip, property_name, old_value, new_value):
+ UndoableAction.__init__(self)
self.clip = clip
self.property_name = property_name
self.old_value = old_value
@@ -107,7 +114,9 @@ class ClipPropertyChanged(UndoableAction):
class ClipAdded(UndoableAction):
+
def __init__(self, layer, clip):
+ UndoableAction.__init__(self)
self.layer = layer
self.clip = clip
@@ -122,7 +131,9 @@ class ClipAdded(UndoableAction):
class ClipRemoved(UndoableAction):
+
def __init__(self, layer, clip):
+ UndoableAction.__init__(self)
self.layer = layer
self.clip = clip
@@ -137,7 +148,9 @@ class ClipRemoved(UndoableAction):
class InterpolatorKeyframeAdded(UndoableAction):
+
def __init__(self, track_element, keyframe):
+ UndoableAction.__init__(self)
self.track_element = track_element
self.keyframe = keyframe
@@ -151,7 +164,9 @@ class InterpolatorKeyframeAdded(UndoableAction):
class InterpolatorKeyframeRemoved(UndoableAction):
+
def __init__(self, track_element, keyframe):
+ UndoableAction.__init__(self)
self.track_element = track_element
self.keyframe = keyframe
@@ -166,7 +181,9 @@ class InterpolatorKeyframeRemoved(UndoableAction):
class InterpolatorKeyframeChanged(UndoableAction):
+
def __init__(self, track_element, keyframe, old_snapshot, new_snapshot):
+ UndoableAction.__init__(self)
self.track_element = track_element
self.keyframe = keyframe
self.old_snapshot = old_snapshot
@@ -188,7 +205,9 @@ class InterpolatorKeyframeChanged(UndoableAction):
class ActivePropertyChanged(UndoableAction):
+
def __init__(self, effect_action, active):
+ UndoableAction.__init__(self)
self.effect_action = effect_action
self.active = not active
@@ -264,10 +283,10 @@ class TimelineLogObserver(object):
tracker = ClipPropertyChangeTracker()
tracker.connectToObject(clip)
for property_name in tracker.property_names:
- setattr(tracker, "last-%s" % property_name,
- clip.get_property(property_name))
- tracker.connect("notify::" + property_name,
- self._clipPropertyChangedCb, property_name)
+ attr_name = "last-%s" % property_name
+ last_value = clip.get_property(property_name)
+ setattr(tracker, attr_name, last_value)
+ tracker.connect("monitored-property-changed", self._clipPropertyChangedCb)
self.clip_property_trackers[clip] = tracker
clip.connect("child-added", self._clipTrackElementAddedCb)
@@ -316,11 +335,13 @@ class TimelineLogObserver(object):
self.log.push(action)
def _clipPropertyChangedCb(self, tracker, clip,
- old_value, new_value, property_name):
+ property_name, old_value, new_value):
+ attr_name = "last-%s" % property_name
new_value = clip.get_property(property_name)
+ old_value = getattr(tracker, attr_name)
action = self.timelinePropertyChangedAction(clip, property_name,
- getattr(tracker, "last-%s" % property_name), new_value)
- setattr(tracker, "last-%s" % property_name, new_value)
+ old_value, new_value)
+ setattr(tracker, attr_name, new_value)
self.log.push(action)
def _clipTrackElementAddedCb(self, clip, track_element):
diff --git a/pitivi/undo/undo.py b/pitivi/undo/undo.py
index 94f6a38..1c35d76 100644
--- a/pitivi/undo/undo.py
+++ b/pitivi/undo/undo.py
@@ -20,10 +20,11 @@
# Boston, MA 02110-1301, USA.
"""
-Base classes for the undo/redo feature implementation
+Base classes for undo/redo.
"""
-from pitivi.utils.signal import Signallable
+from gi.repository import GObject
+
from pitivi.utils.loggable import Loggable
@@ -37,17 +38,21 @@ class UndoWrongStateError(UndoError):
pass
-class UndoableAction(Signallable):
+class UndoableAction(GObject.Object):
"""
- This class represents an action that can be undone.
+ An action that can be undone.
In other words, when your object's state changes, create an UndoableAction
to allow reverting the change if needed later on.
"""
- __signals__ = {
- "done": [],
- "undone": [],
+
+ __gsignals__ = {
+ "done": (GObject.SIGNAL_RUN_LAST, None, ()),
+ "undone": (GObject.SIGNAL_RUN_LAST, None, ()),
}
+ def __init__(self):
+ GObject.Object.__init__(self)
+
def do(self):
raise NotImplementedError()
@@ -69,13 +74,13 @@ class UndoableActionStack(UndoableAction):
"""
Simply a stack of UndoableAction objects.
"""
- __signals__ = {
- "done": [],
- "undone": [],
- "cleaned": [],
+
+ __gsignals__ = {
+ "cleaned": (GObject.SIGNAL_RUN_LAST, None, ()),
}
def __init__(self, action_group_name):
+ UndoableAction.__init__(self)
self.action_group_name = action_group_name
self.done_actions = []
self.undone_actions = []
@@ -107,22 +112,23 @@ class UndoableActionStack(UndoableAction):
self.emit("cleaned")
-class UndoableActionLog(Signallable, Loggable):
+class UndoableActionLog(GObject.Object, Loggable):
"""
This is the "master" class that handles all the undo/redo system. There is
only one instance of it in Pitivi: application.py's "action_log" property.
"""
- __signals__ = {
- "begin": ["stack", "nested"],
- "push": ["stack", "action"],
- "rollback": ["stack", "nested"],
- "commit": ["stack", "nested"],
- "undo": ["stack"],
- "redo": ["stack"],
- "cleaned": [],
+ __gsignals__ = {
+ "begin": (GObject.SIGNAL_RUN_LAST, None, (object, bool)),
+ "push": (GObject.SIGNAL_RUN_LAST, None, (object, object)),
+ "rollback": (GObject.SIGNAL_RUN_LAST, None, (object, bool)),
+ "commit": (GObject.SIGNAL_RUN_LAST, None, (object, bool)),
+ "undo": (GObject.SIGNAL_RUN_LAST, None, (object,)),
+ "redo": (GObject.SIGNAL_RUN_LAST, None, (object,)),
+ "cleaned": (GObject.SIGNAL_RUN_LAST, None, ()),
}
def __init__(self):
+ GObject.Object.__init__(self)
Loggable.__init__(self)
self.undo_stacks = []
@@ -256,28 +262,36 @@ class UndoableActionLog(Signallable, Loggable):
return bool(len(self.stacks))
-class PropertyChangeTracker(Signallable):
+class PropertyChangeTracker(GObject.Object):
"""
BaseClass to track a class property, Used for undo/redo
"""
- __signals__ = {}
+
+ __gsignals__ = {
+ "monitored-property-changed": (GObject.SIGNAL_RUN_LAST, None, (object, str, object, object)),
+ }
+
+ # The properties monitored by this class
+ property_names = []
def __init__(self):
+ GObject.Object.__init__(self)
self.properties = {}
self.obj = None
def connectToObject(self, obj):
self.obj = obj
self.properties = self._takeCurrentSnapshot(obj)
+ # Connect to obj to keep track when the monitored properties
+ # are changed.
for property_name in self.property_names:
- signal_name = "notify::" + property_name
- self.__signals__[signal_name] = []
- obj.connect(signal_name,
- self._propertyChangedCb, property_name)
+ signal_name = "notify::%s" % property_name
+ obj.connect(signal_name, self._propertyChangedCb, property_name)
- def _takeCurrentSnapshot(self, obj):
+ @classmethod
+ def _takeCurrentSnapshot(cls, obj):
properties = {}
- for property_name in self.property_names:
+ for property_name in cls.property_names:
properties[property_name] = obj.get_property(property_name.replace("-", "_"))
return properties
@@ -286,7 +300,7 @@ class PropertyChangeTracker(Signallable):
self.obj = None
obj.disconnect_by_func(self._propertyChangedCb)
- def _propertyChangedCb(self, object, value, property_name):
+ def _propertyChangedCb(self, object, property_value, property_name):
old_value = self.properties[property_name]
- self.properties[property_name] = value
- self.emit("notify::" + property_name, object, old_value, value)
+ self.properties[property_name] = property_value
+ self.emit("monitored-property-changed", object, property_name, old_value, property_value)
diff --git a/pitivi/utils/pipeline.py b/pitivi/utils/pipeline.py
index 77c625c..3200743 100644
--- a/pitivi/utils/pipeline.py
+++ b/pitivi/utils/pipeline.py
@@ -24,34 +24,44 @@
"""
High-level pipelines
"""
-
import platform
-from pitivi.utils.loggable import Loggable
-from pitivi.utils.signal import Signallable
-from pitivi.utils.misc import format_ns
from gi.repository import GLib
from gi.repository import GObject
from gi.repository import Gst
from gi.repository import GES
+from pitivi.utils.loggable import Loggable
+from pitivi.utils.misc import format_ns
+
+
MAX_RECOVERIES = 5
+PIPELINE_SIGNALS = {
+ "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.SignalFlags.RUN_LAST, None, (GObject.TYPE_STRING, GObject.TYPE_STRING)),
+}
+
class PipelineError(Exception):
pass
-class Seeker(Signallable, Loggable):
+class Seeker(GObject.Object, Loggable):
"""
The Seeker is a singleton helper class to do various seeking
operations in the pipeline.
"""
+
_instance = None
- __signals__ = {
- 'seek': ['position', 'format'],
- 'seek-relative': ['time'],
+
+ __gsignals__ = {
+ "seek": (GObject.SIGNAL_RUN_LAST, None, (GObject.TYPE_UINT64, object)),
+ "seek-relative": (GObject.SIGNAL_RUN_LAST, None, (GObject.TYPE_INT64,)),
}
def __new__(cls, *args, **kwargs):
@@ -67,7 +77,7 @@ class Seeker(Signallable, Loggable):
"""
@param timeout (optional): the amount of miliseconds for a seek attempt
"""
- Signallable.__init__(self)
+ GObject.Object.__init__(self)
Loggable.__init__(self)
self.timeout = timeout
@@ -117,8 +127,10 @@ class Seeker(Signallable, Loggable):
self._time = None
elif self.position is not None and self.format is not None:
- position, self.position = self.position, None
- format, self.format = self.format, None
+ position = max(0, self.position)
+ self.position = None
+ format = self.format
+ self.format = None
try:
self.emit('seek', position, format)
except PipelineError as e:
@@ -135,7 +147,7 @@ class Seeker(Signallable, Loggable):
return False
-class SimplePipeline(Signallable, Loggable):
+class SimplePipeline(GObject.Object, Loggable):
"""
The Pipeline is only responsible for:
- State changes
@@ -150,17 +162,11 @@ class SimplePipeline(Signallable, Loggable):
- C{error} : An error happened.
"""
- __signals__ = {
- "state-change": ["state"],
- "position": ["position"],
- "duration-changed": ["duration"],
- "eos": [],
- "error": ["message", "details"]
- }
+ __gsignals__ = PIPELINE_SIGNALS
def __init__(self, pipeline):
+ GObject.Object.__init__(self)
Loggable.__init__(self)
- Signallable.__init__(self)
self._pipeline = pipeline
self._bus = self._pipeline.get_bus()
@@ -206,7 +212,8 @@ class SimplePipeline(Signallable, Loggable):
self.pause()
try:
self.seekRelative(0)
- except PipelineError:
+ except PipelineError as e:
+ self.warning("Could not flush because: %s", e)
pass
def setState(self, state):
@@ -255,8 +262,8 @@ class SimplePipeline(Signallable, Loggable):
# during the playback.
try:
position = self.getPosition()
- except PipelineError:
- # Getting the position failed
+ except PipelineError as e:
+ self.warning("Getting the position failed: %s", e)
return
if position != Gst.CLOCK_TIME_NONE and position >= 0:
self.emit("position", position)
@@ -344,12 +351,14 @@ class SimplePipeline(Signallable, Loggable):
def _positionListenerCb(self):
try:
- cur = self.getPosition()
- if cur != Gst.CLOCK_TIME_NONE:
- self.emit('position', cur)
- self.lastPosition = cur
- except PipelineError:
- pass
+ try:
+ position = self.getPosition()
+ except PipelineError as e:
+ self.warning("Could not get position because: %s", e)
+ else:
+ if position != Gst.CLOCK_TIME_NONE:
+ self.emit('position', position)
+ self.lastPosition = position
finally:
return True
@@ -435,7 +444,8 @@ class SimplePipeline(Signallable, Loggable):
# trigger duration-changed
try:
self.getDuration()
- except PipelineError:
+ except PipelineError as e:
+ self.warning("Could not get duration because: %s", e)
# no sinks??
pass
if self.pendingRecovery:
@@ -484,8 +494,8 @@ class SimplePipeline(Signallable, Loggable):
def _queryDurationAsync(self, *unused_args, **unused_kwargs):
try:
self.getDuration()
- except:
- self.log("Duration failed... but we don't care")
+ except Exception as e:
+ self.warning("Could not get duration because: %s", e)
return False
def _handleErrorMessage(self, error, detail, source):
@@ -533,25 +543,9 @@ class Pipeline(GES.Pipeline, SimplePipeline):
"""
Helper to handle GES.Pipeline through the SimplePipeline API
and handle the Seeker properly
-
- Signals:
- - C{state-changed} : The state of the pipeline changed.
- - C{position} : The current position of the pipeline changed.
- - C{eos} : The Pipeline has finished playing.
- - C{error} : An error happened.
"""
- __gsignals__ = {
- "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.SignalFlags.RUN_LAST, None,
- (GObject.TYPE_STRING, GObject.TYPE_STRING))
- }
+ __gsignals__ = PIPELINE_SIGNALS
def __init__(self, pipeline=None):
GES.Pipeline.__init__(self)
@@ -608,11 +602,5 @@ class Pipeline(GES.Pipeline, SimplePipeline):
new_pos / float(Gst.SECOND))
self.simple_seek(new_pos)
- def _seekCb(self, unused_ruler, position, unused_format):
- """
- The app's main seek method used when the user seeks manually.
-
- We clamp the seeker position so that it cannot go past 0 or the
- end of the timeline.
- """
+ def _seekCb(self, unused_seeker, position, unused_format):
self.simple_seek(position)
diff --git a/pitivi/utils/system.py b/pitivi/utils/system.py
index 4cd5651..e9af1bb 100644
--- a/pitivi/utils/system.py
+++ b/pitivi/utils/system.py
@@ -23,22 +23,24 @@ import multiprocessing
import os
import resource
+from gi.repository import GObject
+
from pitivi.check import NOTIFY_SOFT_DEPENDENCY
from pitivi.configure import APPNAME
from pitivi.utils.loggable import Loggable
-from pitivi.utils.signal import Signallable
-class System(Signallable, Loggable):
- """A base class for all *Systems
- implementing methods available in other parts of Pitivi
+class System(GObject.Object, Loggable):
+ """
+ A base class for systems in which Pitivi runs.
"""
- __signals__ = {
- 'update-power-inhibition': []
+ __gsignals__ = {
+ 'update-power-inhibition': (GObject.SIGNAL_RUN_LAST, None, ()),
}
def __init__(self):
+ GObject.Object.__init__(self)
Loggable.__init__(self)
self.log("new object " + str(self))
self._reset()
diff --git a/pitivi/utils/threads.py b/pitivi/utils/threads.py
index 9bd45a1..7e9912f 100644
--- a/pitivi/utils/threads.py
+++ b/pitivi/utils/threads.py
@@ -18,12 +18,11 @@
# License along with this program; if not, write to the
# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
# Boston, MA 02110-1301, USA.
-"""
-Threading support
-"""
import threading
-from pitivi.utils.signal import Signallable
+
+from gi.repository import GObject
+
from pitivi.utils.loggable import Loggable
#
@@ -32,15 +31,17 @@ from pitivi.utils.loggable import Loggable
#
-class Thread(threading.Thread, Signallable, Loggable):
+class Thread(threading.Thread, GObject.Object, Loggable):
"""
Event-powered thread
"""
- __signals__ = {
- "done": None}
+ __gsignals__ = {
+ "done": (GObject.SIGNAL_RUN_LAST, None, ()),
+ }
def __init__(self):
+ GObject.Object.__init__(self)
threading.Thread.__init__(self)
Loggable.__init__(self)
@@ -91,7 +92,7 @@ class ThreadMaster(Loggable):
""" Stop all running Thread(s) controlled by this master """
self.log("stopping all threads")
joinedthreads = 0
- while(joinedthreads < len(self.threads)):
+ while joinedthreads < len(self.threads):
for thread in self.threads:
self.log("Trying to stop thread %r", thread)
try:
diff --git a/pitivi/utils/timeline.py b/pitivi/utils/timeline.py
index ddd3a8d..c21ba06 100644
--- a/pitivi/utils/timeline.py
+++ b/pitivi/utils/timeline.py
@@ -21,12 +21,9 @@
# Boston, MA 02110-1301, USA.
from gi.repository import GES
-from gi.repository import Gdk
+from gi.repository import GObject
from gi.repository import Gst
-from pitivi.undo.undo import UndoableAction
-from pitivi.utils.signal import Signallable
-
# Selection modes
# Set the selection to the given set.
@@ -39,12 +36,13 @@ SELECT_ADD = 2
#------------------------------------------------------------------------------#
# Timeline Object management helper #
+
class TimelineError(Exception):
"""Base Exception for errors happening in L{Timeline}s or L{Clip}s"""
pass
-class Selected(Signallable):
+class Selected(GObject.Object):
"""
A simple class that let us emit a selected-changed signal
when needed, and that can be check directly to know if the
@@ -54,10 +52,12 @@ class Selected(Signallable):
utils.timeline's "Selection" class.
"""
- __signals__ = {
- "selected-changed": []}
+ __gsignals__ = {
+ "selected-changed": (GObject.SIGNAL_RUN_LAST, None, (bool,)),
+ }
def __init__(self):
+ GObject.Object.__init__(self)
self._selected = False
def __bool__(self):
@@ -77,7 +77,7 @@ class Selected(Signallable):
selected = property(getSelected, setSelected)
-class Selection(Signallable):
+class Selection(GObject.Object):
"""
A collection of L{GES.Clip}.
@@ -88,10 +88,12 @@ class Selection(Signallable):
@type selected: C{list}
"""
- __signals__ = {
- "selection-changed": []}
+ __gsignals__ = {
+ "selection-changed": (GObject.SIGNAL_RUN_LAST, None, ()),
+ }
def __init__(self):
+ GObject.Object.__init__(self)
self.selected = set()
def setToObj(self, obj, mode):
@@ -187,16 +189,17 @@ class Selection(Signallable):
#-----------------------------------------------------------------------------#
# Timeline edition modes helper #
-class EditingContext(Signallable):
+
+class EditingContext(GObject.Object):
"""
Encapsulates interactive editing.
This is the main class for interactive edition.
"""
- __signals__ = {
- "clip-trim": ["uri", "position"],
- "clip-trim-finished": [],
+ __gsignals__ = {
+ "clip-trim": (GObject.SIGNAL_RUN_LAST, None, (GES.Clip, int)),
+ "clip-trim-finished": (GObject.SIGNAL_RUN_LAST, None, ()),
}
def __init__(self, focus, timeline, mode, edge, unused_settings, action_log):
@@ -222,8 +225,7 @@ class EditingContext(Signallable):
@returns: An instance of L{pitivi.utils.timeline.EditingContext}
"""
- Signallable.__init__(self)
-
+ GObject.Object.__init__(self)
if isinstance(focus, GES.TrackElement):
self.focus = focus.get_parent()
else:
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 22265c6..63478af 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -13,7 +13,6 @@ tests = \
test_preset.py \
test_project.py \
test_projectsettings.py \
- test_signallable.py \
test_system.py \
test_undo.py \
test_undo_timeline.py \
diff --git a/tests/test_application.py b/tests/test_application.py
index 5c0fe26..62d8d56 100644
--- a/tests/test_application.py
+++ b/tests/test_application.py
@@ -33,53 +33,48 @@ class MockGioFile(object):
class TestPitivi(common.TestCase):
- def testBasic(self):
- app = application.Pitivi()
- app.emit("startup")
- self.assertTrue(app.shutdown())
-
def testVersionInfo(self):
app = application.Pitivi()
- app.emit("startup")
+ app._checkVersion()
self.assertTrue(app.isLatest())
app = application.Pitivi()
- app.emit("startup")
+ app._checkVersion()
app._versionInfoReceivedCb(MockGioFile(), "invalid", None)
self.assertTrue(app.isLatest())
app = application.Pitivi()
- app.emit("startup")
+ app._checkVersion()
app._versionInfoReceivedCb(MockGioFile(), "%s=CURRENT" % configure.VERSION, None)
self.assertTrue(app.isLatest())
self.assertEqual(configure.VERSION, app.getLatest())
app = application.Pitivi()
- app.emit("startup")
+ app._checkVersion()
app._versionInfoReceivedCb(MockGioFile(), "%s=current\n0=supported" % configure.VERSION, None)
self.assertTrue(app.isLatest())
self.assertEqual(configure.VERSION, app.getLatest())
app = application.Pitivi()
- app.emit("startup")
+ app._checkVersion()
app._versionInfoReceivedCb(MockGioFile(), "999.0=CURRENT", None)
self.assertFalse(app.isLatest())
self.assertEqual("999.0", app.getLatest())
app = application.Pitivi()
- app.emit("startup")
+ app._checkVersion()
app._versionInfoReceivedCb(MockGioFile(), "999.0=CURRENT\n%s=SUPPORTED" % configure.VERSION, None)
self.assertFalse(app.isLatest())
self.assertEqual("999.0", app.getLatest())
app = application.Pitivi()
- app.emit("startup")
+ app._checkVersion()
app._versionInfoReceivedCb(MockGioFile(), "0.91=current", None)
self.assertTrue(app.isLatest())
self.assertEqual("0.91", app.getLatest())
app = application.Pitivi()
- app.emit("startup")
+ app._checkVersion()
app._versionInfoReceivedCb(MockGioFile(), "0.100000000=current", None)
self.assertFalse(app.isLatest())
self.assertEqual("0.100000000", app.getLatest())
diff --git a/tests/test_project.py b/tests/test_project.py
index 8547e6f..a5ad911 100644
--- a/tests/test_project.py
+++ b/tests/test_project.py
@@ -28,18 +28,17 @@ from gi.repository import GES
from gi.repository import GLib
from pitivi.application import Pitivi
-from pitivi.project import Project, ProjectManager
+from pitivi.project import ProjectManager
from pitivi.utils.misc import uri_is_reachable
def _createRealProject(name=None):
app = Pitivi()
- app.emit("startup")
- app.project_manager.newBlankProject()
+ project_manager = ProjectManager(app)
+ project_manager.newBlankProject()
if name:
- app.project_manager.current_project.name = name
-
- return app.project_manager.current_project
+ project_manager.current_project.name = name
+ return project_manager.current_project
class MockProject(object):
@@ -385,9 +384,6 @@ class TestProjectLoading(TestCase):
class TestExportSettings(TestCase):
"""Test the project.MultimediaSettings class."""
- def setUp(self):
- self.project = _createRealProject()
-
def testMasterAttributes(self):
self._testMasterAttribute('muxer', dependant_attr='containersettings')
self._testMasterAttribute('vencoder', dependant_attr='vcodecsettings')
@@ -395,33 +391,35 @@ class TestExportSettings(TestCase):
def _testMasterAttribute(self, attr, dependant_attr):
"""Test changing the specified attr has effect on its dependant attr."""
+ project = _createRealProject()
+
attr_value1 = "%s_value1" % attr
attr_value2 = "%s_value2" % attr
- setattr(self.project, attr, attr_value1)
- setattr(self.project, dependant_attr, {})
- getattr(self.project, dependant_attr)["key1"] = "v1"
-
- setattr(self.project, attr, attr_value2)
- setattr(self.project, dependant_attr, {})
- getattr(self.project, dependant_attr)["key2"] = "v2"
-
- setattr(self.project, attr, attr_value1)
- self.assertTrue("key1" in getattr(self.project, dependant_attr))
- self.assertFalse("key2" in getattr(self.project, dependant_attr))
- self.assertEqual("v1", getattr(self.project, dependant_attr)["key1"])
- setattr(self.project, dependant_attr, {})
-
- setattr(self.project, attr, attr_value2)
- self.assertFalse("key1" in getattr(self.project, dependant_attr))
- self.assertTrue("key2" in getattr(self.project, dependant_attr))
- self.assertEqual("v2", getattr(self.project, dependant_attr)["key2"])
- setattr(self.project, dependant_attr, {})
-
- setattr(self.project, attr, attr_value1)
- self.assertFalse("key1" in getattr(self.project, dependant_attr))
- self.assertFalse("key2" in getattr(self.project, dependant_attr))
-
- setattr(self.project, attr, attr_value2)
- self.assertFalse("key1" in getattr(self.project, dependant_attr))
- self.assertFalse("key2" in getattr(self.project, dependant_attr))
+ setattr(project, attr, attr_value1)
+ setattr(project, dependant_attr, {})
+ getattr(project, dependant_attr)["key1"] = "v1"
+
+ setattr(project, attr, attr_value2)
+ setattr(project, dependant_attr, {})
+ getattr(project, dependant_attr)["key2"] = "v2"
+
+ setattr(project, attr, attr_value1)
+ self.assertTrue("key1" in getattr(project, dependant_attr))
+ self.assertFalse("key2" in getattr(project, dependant_attr))
+ self.assertEqual("v1", getattr(project, dependant_attr)["key1"])
+ setattr(project, dependant_attr, {})
+
+ setattr(project, attr, attr_value2)
+ self.assertFalse("key1" in getattr(project, dependant_attr))
+ self.assertTrue("key2" in getattr(project, dependant_attr))
+ self.assertEqual("v2", getattr(project, dependant_attr)["key2"])
+ setattr(project, dependant_attr, {})
+
+ setattr(project, attr, attr_value1)
+ self.assertFalse("key1" in getattr(project, dependant_attr))
+ self.assertFalse("key2" in getattr(project, dependant_attr))
+
+ setattr(project, attr, attr_value2)
+ self.assertFalse("key1" in getattr(project, dependant_attr))
+ self.assertFalse("key2" in getattr(project, dependant_attr))
diff --git a/tests/test_undo.py b/tests/test_undo.py
index cec82db..6199a5a 100644
--- a/tests/test_undo.py
+++ b/tests/test_undo.py
@@ -28,6 +28,9 @@ from pitivi.undo.undo import UndoError, UndoWrongStateError, UndoableAction, \
class DummyUndoableAction(UndoableAction):
done_ = True
+ def __init__(self):
+ UndoableAction.__init__(self)
+
def do(self):
self.done_ = True
self._done()
@@ -392,6 +395,7 @@ class TestUndoableActionLog(TestCase):
class Action(UndoableAction):
def __init__(self, n):
+ UndoableAction.__init__(self)
self.n = n
def do(self):
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]