[pitivi] Make effect property changes undoable



commit a1379d69f3eb9d6afc86d1cf187c4e18036b094e
Author: Thibault Saunier <tsaunier gnome org>
Date:   Fri Jul 30 13:48:33 2010 +0200

    Make effect property changes undoable

 pitivi/effects.py                 |   45 +++++++++++++++++++++++++++++++++++-
 pitivi/timeline/timeline.py       |    2 +-
 pitivi/timeline/timeline_undo.py  |    3 ++
 pitivi/ui/clipproperties.py       |    2 +-
 pitivi/ui/effectsconfiguration.py |    6 ++++-
 pitivi/ui/gstwidget.py            |    7 +++++-
 6 files changed, 59 insertions(+), 6 deletions(-)
---
diff --git a/pitivi/effects.py b/pitivi/effects.py
index 1c67584..8c949bc 100644
--- a/pitivi/effects.py
+++ b/pitivi/effects.py
@@ -26,6 +26,7 @@ Effects global handling
 """
 import gst
 import gtk
+import gobject
 import re
 import os
 
@@ -35,8 +36,7 @@ from gettext import gettext as _
 from pitivi.factories.operation import EffectFactory
 from pitivi.stream import get_stream_for_pad
 from pitivi.configure import get_pixmap_dir
-
-from xdg import IconTheme
+from pitivi.undo import UndoableAction
 
 # Note: Some effects are available through the frei0r library and the libavfilter0 library
 
@@ -296,3 +296,44 @@ class EffectsHandler(object):
                 except:
                     return None
         return icon
+
+
+class EffectPropertyChanged(UndoableAction):
+    def __init__(self, gst_element, property_name, old_value, new_value):
+        self.gst_element = gst_element
+        self.property_name = property_name
+        self.old_value = old_value
+        self.new_value = new_value
+
+    def do(self):
+        self.gst_element.set_property(self.property_name, self.new_value)
+        self._done()
+
+    def undo(self):
+        self.gst_element.set_property(self.property_name, self.old_value)
+        self._undone()
+
+class EffectGstElementPropertyChangeTracker:
+    """
+    Track effect configuration changes in its list of control effects
+    """
+    def __init__(self, action_log):
+        self._tracked_effects = {}
+        self.action_log = action_log
+
+    def addEffectElement(self, gst_element):
+        properties = {}
+        for prop in gobject.list_properties(gst_element):
+            gst_element.connect('notify::' + prop.name,
+                                self._propertyChangedCb,
+                                gst_element)
+            properties[prop.name] = gst_element.get_property(prop.name)
+        self._tracked_effects[gst_element] = properties
+
+    def _propertyChangedCb(self, gst_element, pspec, unused):
+        old_value = self._tracked_effects[gst_element][pspec.name]
+        new_value = gst_element.get_property(pspec.name)
+        action = EffectPropertyChanged(gst_element, pspec.name, old_value,
+                                       new_value)
+        self._tracked_effects[gst_element][pspec.name] = new_value
+        self.action_log.push(action)
diff --git a/pitivi/timeline/timeline.py b/pitivi/timeline/timeline.py
index 47ea1c5..98b7c44 100644
--- a/pitivi/timeline/timeline.py
+++ b/pitivi/timeline/timeline.py
@@ -533,7 +533,7 @@ class Selection(Signallable):
 
     def getSelectedTrackEffects(self):
         """
-        Returns the list of L{TrackObject} contained in this selection.
+        Returns the list of L{TrackEffect} contained in this selection.
         """
         track_effects = []
         for timeline_object in self.selected:
diff --git a/pitivi/timeline/timeline_undo.py b/pitivi/timeline/timeline_undo.py
index b4f26c0..274b9d4 100644
--- a/pitivi/timeline/timeline_undo.py
+++ b/pitivi/timeline/timeline_undo.py
@@ -27,6 +27,7 @@ from pitivi.undo import UndoableAction
 from pitivi.timeline.track import TrackEffect
 
 from pitivi.ui.effectsconfiguration import PROPS_TO_IGNORE
+from pitivi.effects import EffectGstElementPropertyChangeTracker
 
 class TimelineObjectPropertyChangeTracker(PropertyChangeTracker):
     # no out-point
@@ -306,6 +307,7 @@ class TimelineLogObserver(object):
         self.log = log
         self.timeline_object_property_trackers = {}
         self.interpolator_keyframe_trackers = {}
+        self.effect_properties_tracker = EffectGstElementPropertyChangeTracker(log)
 
     def startObserving(self, timeline):
         self._connectToTimeline(timeline)
@@ -390,6 +392,7 @@ class TimelineLogObserver(object):
         if isinstance(track_object, TrackEffect):
             action = self.trackEffectAddAction(timeline_object, track_object)
             self.log.push(action)
+            self.effect_properties_tracker.addEffectElement(track_object.getElement())
         else:
             self._connectToTrackObject(track_object)
 
diff --git a/pitivi/ui/clipproperties.py b/pitivi/ui/clipproperties.py
index 5c69167..7a1ac87 100644
--- a/pitivi/ui/clipproperties.py
+++ b/pitivi/ui/clipproperties.py
@@ -59,7 +59,7 @@ class ClipProperties(gtk.VBox, Loggable):
         self.settings = instance.settings
         self.project = None
 
-        self.effect_properties_handling = EffectsPropertiesHandling()
+        self.effect_properties_handling = EffectsPropertiesHandling(instance.action_log)
         self.effect_expander = EffectProperties(instance,
                                                 self.effect_properties_handling)
         self.pack_start(self.effect_expander, expand=True, fill=True)
diff --git a/pitivi/ui/effectsconfiguration.py b/pitivi/ui/effectsconfiguration.py
index b95288d..a7e864d 100644
--- a/pitivi/ui/effectsconfiguration.py
+++ b/pitivi/ui/effectsconfiguration.py
@@ -30,10 +30,11 @@ from pitivi.pipeline import PipelineError
 PROPS_TO_IGNORE = ['name', 'qos']
 
 class EffectsPropertiesHandling:
-    def __init__(self):
+    def __init__(self, action_log):
         self.cache_dict = {}
         self.pipeline = None
         self._current_effect_setting_ui = None
+        self.action_log = action_log
 
     def getEffectConfigurationUI(self, effect):
         """
@@ -89,5 +90,8 @@ class EffectsPropertiesHandling:
 
     def _onValueChangedCb(self, widget, with_default=False):
         for prop, value in self._current_effect_setting_ui.getSettings(with_default).iteritems():
+            self.action_log.begin("Effect property change")
             self._current_effect_setting_ui.element.set_property(prop, value)
+            self.action_log.commit()
+
         self._flushSeekVideo()
diff --git a/pitivi/ui/gstwidget.py b/pitivi/ui/gstwidget.py
index dfd6673..6c6f69b 100644
--- a/pitivi/ui/gstwidget.py
+++ b/pitivi/ui/gstwidget.py
@@ -119,7 +119,6 @@ def make_property_widget(unused_element, prop, value=None):
         widget.pack_start(widget1)
         widget.pack_start(gtk.Label("/"))
         widget.pack_start(widget2)
-        print "%s, %s" %(value, type(value))
     else:
         widget = gtk.Label(type_name)
         widget.set_alignment(1.0, 0.5)
@@ -187,11 +186,17 @@ class GstElementSettingsWidget(gtk.VBox, Loggable):
                 button = self._getResetToDefaultValueButton(prop, widget)
                 table.attach(button, 2, 3, y, y+1, xoptions=gtk.FILL, yoptions=gtk.FILL)
                 self.buttons.append(button)
+            self.element.connect('notify::' + prop.name,
+                                self._propertyChangedCb,
+                                widget)
             y += 1
 
         self.pack_start(table)
         self.show_all()
 
+    def _propertyChangedCb(self, element, pspec, widget):
+        self._set_prop(widget, self.element.get_property(pspec.name))
+
     def _getResetToDefaultValueButton(self, prop, widget):
         icon = gtk.Image()
         icon.set_from_stock('gtk-clear', gtk.ICON_SIZE_MENU)



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