[pitivi] Add support to undo/redo deletion of clips.



commit 9748117d4ee5ae2a547b77981b27ae0849312031
Author: Alessandro Decina <alessandro d gmail com>
Date:   Wed Jun 10 16:48:22 2009 +0200

    Add support to undo/redo deletion of clips.

 pitivi/timeline/timeline.py      |    4 +-
 pitivi/timeline/timeline_undo.py |   44 ++++++++++++++++++++++++++++++++++++++
 pitivi/ui/mainwindow.py          |   42 ++++++++++++++++++++++++++---------
 pitivi/ui/timeline.py            |    4 +++
 pitivi/undo.py                   |   12 ++-------
 5 files changed, 84 insertions(+), 22 deletions(-)
---
diff --git a/pitivi/timeline/timeline.py b/pitivi/timeline/timeline.py
index 34b89d4..d6e7c08 100644
--- a/pitivi/timeline/timeline.py
+++ b/pitivi/timeline/timeline.py
@@ -882,13 +882,13 @@ class Timeline(Signallable, Loggable):
         self.rebuildEdges()
         #self.edges.removeTimelineObject(obj)
 
+        self.emit("object-removed", obj)
+
         if deep:
             for track_object in obj.track_objects:
                 track = track_object.track
                 track.removeTrackObject(track_object)
 
-        self.emit("object-removed", obj)
-
     # FIXME : shouldn't this be made more generic (i.e. not specific to source facotires) ?
     def addSourceFactory(self, factory, stream_map=None, strict=False):
         """
diff --git a/pitivi/timeline/timeline_undo.py b/pitivi/timeline/timeline_undo.py
index aeeb243..3060267 100644
--- a/pitivi/timeline/timeline_undo.py
+++ b/pitivi/timeline/timeline_undo.py
@@ -43,6 +43,46 @@ class TimelineObjectPropertyChanged(UndoableAction):
                 self.property_name.replace("-", "_"), self.old_value)
         self._undone()
 
+class TimelineObjectAdded(UndoableAction):
+    def __init__(self, timeline, timeline_object):
+        self.timeline = timeline
+        self.timeline_object = timeline_object
+
+    def do(self):
+        self.timeline.addTimelineObject(self.timeline_object)
+        self._done()
+
+    def undo(self):
+        self.timeline.removeTimelineObject(self.timeline_object)
+        self._undone()
+
+class TimelineObjectRemoved(UndoableAction):
+    def __init__(self, timeline, timeline_object):
+        self.timeline = timeline
+        self.timeline_object_copy = self._copyTimelineObject(timeline_object)
+        self.timeline_object = timeline_object
+
+    def do(self):
+        self.timeline.removeTimelineObject(self.timeline_object, deep=True)
+        self._done()
+
+    def undo(self):
+        self.timeline_object = self.timeline_object_copy
+        for track_object in self.timeline_object.track_objects:
+            track, track_object.track = track_object.track, None
+            track.addTrackObject(track_object)
+        self.timeline_object_copy = self._copyTimelineObject(self.timeline_object)
+        self.timeline.addTimelineObject(self.timeline_object)
+        self._undone()
+
+    def _copyTimelineObject(self, timeline_object):
+        copy = timeline_object.copy()
+        for (track_object_copy, track_object) in \
+                    zip(copy.track_objects, timeline_object.track_objects):
+            track_object_copy.track = track_object.track
+
+        return copy
+
 class TimelineLogObserver(object):
     def __init__(self, log):
         self.log = log
@@ -81,9 +121,13 @@ class TimelineLogObserver(object):
 
     def _timelineObjectAddedCb(self, timeline, timeline_object):
         self._connectToTimelineObject(timeline_object)
+        action = TimelineObjectAdded(timeline, timeline_object)
+        self.log.push(action)
 
     def _timelineObjectRemovedCb(self, timeline, timeline_object):
         self._disconnectFromTimelineObject(timeline_object)
+        action = TimelineObjectRemoved(timeline, timeline_object)
+        self.log.push(action)
 
     def _timelineObjectPropertyChangedCb(self, tracker, timeline_object,
             old_value, new_value, property_name):
diff --git a/pitivi/ui/mainwindow.py b/pitivi/ui/mainwindow.py
index 5d621ef..75086b2 100644
--- a/pitivi/ui/mainwindow.py
+++ b/pitivi/ui/mainwindow.py
@@ -180,8 +180,9 @@ class PitiviMainWindow(gtk.Window, Loggable):
         self.app.projectManager.connect("missing-uri",
                 self._projectManagerMissingUriCb)
 
-        self.app.action_log.connect("can-undo", self._actionLogCanUndo)
-        self.app.action_log.connect("can-redo", self._actionLogCanRedo)
+        self.app.action_log.connect("commit", self._actionLogCommit)
+        self.app.action_log.connect("undo", self._actionLogUndo)
+        self.app.action_log.connect("redo", self._actionLogRedo)
 
         # if no webcams available, hide the webcam action
         self.app.deviceprobe.connect("device-added", self._deviceChangeCb)
@@ -656,7 +657,7 @@ class PitiviMainWindow(gtk.Window, Loggable):
     def loop(self, unused_action):
         pass
 
-    
+
     def _projectManagerNewProjectLoadedCb(self, projectManager, project):
         self.log("A NEW project is loaded, update the UI!")
         self.project = project
@@ -735,17 +736,36 @@ class PitiviMainWindow(gtk.Window, Loggable):
 
         dialog.destroy()
 
-    def _actionLogCanUndo(self, action_log, can_undo, action_group_name):
-        action = self.actiongroup.get_action("Undo")
-        action.set_sensitive(can_undo)
+    def _actionLogCommit(self, action_log, stack, nested):
+        if nested:
+            return
+
+        self._syncDoUndo(action_log)
+
+    def _actionLogUndo(self, action_log, stack):
+        self._syncDoUndo(action_log)
+
+    def _actionLogRedo(self, action_log, stack):
+        self._syncDoUndo(action_log)
+
+    def _syncDoUndo(self, action_log):
+        undo_action = self.actiongroup.get_action("Undo")
+        can_undo = bool(action_log.undo_stacks)
+        undo_action.set_sensitive(can_undo)
         if can_undo:
-            action.props.label = _("Undo %s") % action_group_name
+            stack = action_log.undo_stacks[-1]
+            undo_action.props.label = _("Undo %s") % stack.action_group_name
+        else:
+            undo_action.props.label = _("Undo")
 
-    def _actionLogCanRedo(self, action_log, can_redo, action_group_name):
-        action = self.actiongroup.get_action("Redo")
-        action.set_sensitive(can_redo)
+        redo_action = self.actiongroup.get_action("Redo")
+        can_redo = bool(action_log.redo_stacks)
+        redo_action.set_sensitive(can_redo)
         if can_redo:
-            action.props.label = _("Redo %s") % action_group_name
+            stack = action_log.redo_stacks[-1]
+            redo_action.props.label = _("Redo %s") % stack.action_group_name
+        else:
+            redo_action.props.label = _("Redo")
 
 ## PiTiVi current project callbacks
 
diff --git a/pitivi/ui/timeline.py b/pitivi/ui/timeline.py
index 5dd6855..48ed73f 100644
--- a/pitivi/ui/timeline.py
+++ b/pitivi/ui/timeline.py
@@ -299,8 +299,10 @@ class Timeline(gtk.Table, Loggable, Zoomable):
         self.timeline.enableUpdates()
 
     def _dragDropCb(self, widget, context, x, y, timestamp):
+        self.app.action_log.begin("add clip")
         self._add_temp_source()
         self._move_temp_source(x, y)
+        self.app.action_log.commit()
         context.drop_finish(True, timestamp)
         self._factories = None
         self._temp_objects = None
@@ -469,7 +471,9 @@ class Timeline(gtk.Table, Loggable, Zoomable):
 
     def deleteSelected(self, unused_action):
         if self.timeline:
+            self.app.action_log.begin("delete clip")
             self.timeline.deleteSelection()
+            self.app.action_log.commit()
 
     def unlinkSelected(self, unused_action):
         if self.timeline:
diff --git a/pitivi/undo.py b/pitivi/undo.py
index f258602..b72435c 100644
--- a/pitivi/undo.py
+++ b/pitivi/undo.py
@@ -139,8 +139,6 @@ class UndoableActionLog(Signallable):
         "commit": ["stack", "nested"],
         "undo": ["stack"],
         "redo": ["stack"],
-        "can-undo": ["bool"],
-        "can-redo": ["bool"],
         "error": ["exception"]
     }
     def __init__(self):
@@ -189,10 +187,12 @@ class UndoableActionLog(Signallable):
         nested = self._stackIsNested(stack)
         if not self.stacks:
             self.undo_stacks.append(stack)
-            self.emit("can-undo", True, stack.action_group_name)
         else:
             self.stacks[-1].push(stack)
 
+        if self.redo_stacks:
+            self.redo_stacks = []
+
         self.emit("commit", stack, nested)
 
     def undo(self):
@@ -201,27 +201,21 @@ class UndoableActionLog(Signallable):
             return
 
         stack = self.undo_stacks.pop(-1)
-        if not self.undo_stacks:
-            self.emit("can-undo", False, None)
 
         self._runStack(stack, stack.undo)
 
         self.redo_stacks.append(stack)
         self.emit("undo", stack)
-        self.emit("can-redo", True, stack.action_group_name)
 
     def redo(self):
         if self.stacks or not self.redo_stacks:
             return self._error(UndoWrongStateError())
 
         stack = self.redo_stacks.pop(-1)
-        if not self.redo_stacks:
-            self.emit("can-redo", False, None)
 
         self._runStack(stack, stack.do)
         self.undo_stacks.append(stack)
         self.emit("redo", stack)
-        self.emit("can-undo", True, stack.action_group_name)
 
     def _runStack(self, stack, run):
         self._connectToRunningStack(stack)



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