[pitivi] undo: Fix DND of clips in the timeline



commit 2ef4a098495662ebe96b24213d9cf40fda56c8c6
Author: Thibault Saunier <tsaunier gnome org>
Date:   Wed Apr 27 16:06:26 2016 -0300

    undo: Fix DND of clips in the timeline
    
    Drag and dropping works like that:
    
    - We receive some dragged clips in the timeline
        - We add those to the timeline
        - The user eventually drags a bit more the clips
        - we create a EditingContext to move the clips
    
    Then we have 3 options:
    
    1- The user drops the clips when he is happy
        - We get a "leave" event on the timeline
            - We create a list of set of (layer, clip) in
              self.__last_clips_on_leave to remember the clips
              the were added to the timeline
        - The user releases the mouse button
            - We get a "drop" event
                - We re add all the previously cached clips to
                  the timeline
    
    2- The user changes his mind and goes outside the timeline
        - We get a "leave" event on the timeline
            - We create a list of set of (layer, clip) in
              self.__last_clips_on_leave to remember the clips
              the were added to the timeline
        - the user releases the mouse button (nothing else happens)
    
    3- The user gets out of the timeline (maybe not on purpose)
        - We get a "leave" event on the timeline
            - We create a list of set of (layer, clip) in
              self.__last_clips_on_leave to remember the clips
              the were added to the timeline
        - The user comes back to the timeline
            - We re add all the previously cached clips to
              the timeline
        - The user releases the mouse button
            - We get a "drop" event
                - We re add all the previously cached clips to
                  the timeline
    
    In the do/undo system what we care is only where the clips were added
    when they were definitely added, so in that patch we stop tracking
    any action happening when it is not the final decision.
    
    This means that the only thing we take into account now is the last
    " - We re add all the previously cached clips to the timeline" action
    and ignore anything else.
    
    Reviewed-by: Alex Băluț <alexandru balut gmail com>
    Differential Revision: https://phabricator.freedesktop.org/D976

 pitivi/timeline/timeline.py |   48 ++++++++++++++++++++++--------------------
 pitivi/undo/timeline.py     |    6 +++++
 pitivi/utils/timeline.py    |   11 +++++++--
 3 files changed, 39 insertions(+), 26 deletions(-)
---
diff --git a/pitivi/timeline/timeline.py b/pitivi/timeline/timeline.py
index fb28a1d..f3b0311 100644
--- a/pitivi/timeline/timeline.py
+++ b/pitivi/timeline/timeline.py
@@ -299,7 +299,7 @@ class Timeline(Gtk.EventBox, Zoomable, Loggable):
         # What's being dropped, for example asset URIs.
         self.dropData = None
         # Whether clips have been created in the current drag & drop.
-        self._createdClips = False
+        self.dropping_clips = False
         # The list of (Layer, Clip) tuples dragged into the timeline.
         self.__last_clips_on_leave = None
 
@@ -742,7 +742,7 @@ class Timeline(Gtk.EventBox, Zoomable, Loggable):
         self.queue_draw()
 
     def __createClips(self, x, y):
-        if self._createdClips:
+        if self.dropping_clips:
             return False
 
         x = self.adjustCoords(x=x)
@@ -769,22 +769,22 @@ class Timeline(Gtk.EventBox, Zoomable, Loggable):
 
             self.debug("Creating %s at %s", asset.props.id, Gst.TIME_ARGS(placement))
 
-            with self.app.action_log.started("add clip"):
-                ges_clip = ges_layer.add_asset(asset,
-                                               placement,
-                                               0,
-                                               clip_duration,
-                                               asset.get_supported_formats())
-                placement += clip_duration
-                self.current_group.add(ges_clip.get_toplevel_parent())
-                self.selection.setSelection([], SELECT_ADD)
+            ges_clip = ges_layer.add_asset(asset,
+                                           placement,
+                                           0,
+                                           clip_duration,
+                                           asset.get_supported_formats())
+            placement += clip_duration
+            self.current_group.add(ges_clip.get_toplevel_parent())
+            self.selection.setSelection([], SELECT_ADD)
+            ges_clip.first_placement = True
             self._project.pipeline.commit_timeline()
 
             if not self.draggingElement:
                 self.draggingElement = ges_clip.ui
                 self._on_layer = ges_layer
 
-            self._createdClips = True
+            self.dropping_clips = True
 
         return True
 
@@ -816,25 +816,24 @@ class Timeline(Gtk.EventBox, Zoomable, Loggable):
             self.__last_clips_on_leave = [(clip.get_layer(), clip)
                                           for clip in self.current_group.get_children(False)]
             self.dropDataReady = False
-            if self._createdClips:
+            if self.dropping_clips:
                 clips = self.current_group.get_children(False)
                 self.resetSelectionGroup()
                 self.selection.setSelection([], SELECT)
                 for clip in clips:
                     clip.get_layer().remove_clip(clip)
                 self._project.pipeline.commit_timeline()
-                self.app.action_log.commit("add dragged clip")
 
             self.draggingElement = None
             self.__got_dragged = False
-            self._createdClips = False
+            self.dropping_clips = False
         elif target == URI_TARGET_ENTRY.target:
             self.cleanDropData()
 
     def cleanDropData(self):
         self.dropDataReady = False
         self.dropData = None
-        self._createdClips = False
+        self.dropping_clips = False
 
     def __dragDropCb(self, unused_widget, context, x, y, timestamp):
         # Same as in insertEnd: this value changes during insertion, snapshot
@@ -846,16 +845,18 @@ class Timeline(Gtk.EventBox, Zoomable, Loggable):
         self.cleanDropData()
         if target == URI_TARGET_ENTRY.target:
             if self.__last_clips_on_leave:
-                self.app.action_log.begin("add dragged clip")
-
                 if self.__on_separators:
                     created_layer = self.__getDroppedLayer()
                 else:
                     created_layer = None
-                for layer, clip in self.__last_clips_on_leave:
-                    if created_layer:
-                        layer = created_layer
-                    layer.add_clip(clip)
+                pipeline = self._project.pipeline
+                with self.app.action_log.started("add clip",
+                                                 CommitTimelineFinalizingAction(pipeline)):
+                    for layer, clip in self.__last_clips_on_leave:
+                        if created_layer:
+                            layer = created_layer
+                        clip.first_placement = False
+                        layer.add_clip(clip)
 
                 if zoom_was_fitted:
                     self.parent._setBestZoomRatio()
@@ -1050,7 +1051,8 @@ class Timeline(Gtk.EventBox, Zoomable, Loggable):
                                                   self.ges_timeline,
                                                   edit_mode,
                                                   dragging_edge,
-                                                  self.app)
+                                                  self.app,
+                                                  not self.dropping_clips)
 
         x, y = event_widget.translate_coordinates(self, x, y)
         x -= CONTROL_WIDTH
diff --git a/pitivi/undo/timeline.py b/pitivi/undo/timeline.py
index 3ae2ace..18e93ec 100644
--- a/pitivi/undo/timeline.py
+++ b/pitivi/undo/timeline.py
@@ -691,6 +691,12 @@ class TimelineObserver(Loggable):
 
     def _clipPropertyChangedCb(self, tracker, clip,
                                property_name, old_value, new_value):
+
+        # Do not track clips when we are just moving clips around
+        # while drag and dropping them.
+        if self.app.gui.timeline_ui.timeline.dropping_clips:
+            return
+
         attr_name = "last-%s" % property_name
         new_value = clip.get_property(property_name)
         old_value = getattr(tracker, attr_name)
diff --git a/pitivi/utils/timeline.py b/pitivi/utils/timeline.py
index 8ba13fa..316166d 100644
--- a/pitivi/utils/timeline.py
+++ b/pitivi/utils/timeline.py
@@ -217,7 +217,7 @@ class EditingContext(GObject.Object, Loggable):
         This is the main class for interactive edition.
     """
 
-    def __init__(self, focus, timeline, mode, edge, app):
+    def __init__(self, focus, timeline, mode, edge, app, log_actions):
         """
         @param focus: the Clip or TrackElement which is to be the
         main target of interactive editing, such as the object directly under the
@@ -260,10 +260,15 @@ class EditingContext(GObject.Object, Loggable):
         self.edge = edge
         self.mode = mode
 
-        self.app.action_log.begin("move-clip")
+        from pitivi.undo.timeline import CommitTimelineFinalizingAction
+        self.__log_actions = log_actions
+        if log_actions:
+            self.app.action_log.begin("move-clip", CommitTimelineFinalizingAction(
+                self.timeline.get_asset().pipeline))
 
     def finish(self):
-        self.app.action_log.commit("move-clip")
+        if self.__log_actions:
+            self.app.action_log.commit("move-clip")
         self.timeline.get_asset().pipeline.commit_timeline()
         self.timeline.ui.app.gui.viewer.clipTrimPreviewFinished()
 


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