[pitivi/1.0] timeline: Fix pasting copied clips multiple times



commit d3e95880fd29e4d71468992b9e15ea17816c4e7e
Author: Harish Fulara <harish14143 iiitd ac in>
Date:   Thu Feb 22 01:40:11 2018 +0530

    timeline: Fix pasting copied clips multiple times
    
    How copy-paste works? The object (o_copy) returned by the copy function
    stores reference to the object (o_orig) whose copy is made. While
    pasting o_copy onto the timeline, this reference is used to set the
    timeline for o_copy, i.e., timeline(o_copy) = timeline(o_orig), which
    makes o_copy get pasted on the timeline.
    
    Issue with previous logic? We were saving a copy of 'self.__copiedGroup'
    before pasting it onto the timeline and then restoring
    'self.__copiedGroup' from previously saved copy after the paste
    operation is done (for the first time). This saving and restoring
    'self.__copiedGroup' would make it store a reference to itself. When we
    paste again (for the second time) on the timeline, no timeline would be
    associated with the pasted object because 'self.__copiedGroup' refers to
    itself and there is no timeline associated with 'self.__copiedGroup'.
    Hence, nothing would get pasted onto the timeline.
    
    Fixes https://phabricator.freedesktop.org/T7639

 pitivi/timeline/timeline.py     |   17 ++++++++---------
 tests/test_timeline_timeline.py |   21 ++++++++++++++++-----
 2 files changed, 24 insertions(+), 14 deletions(-)
---
diff --git a/pitivi/timeline/timeline.py b/pitivi/timeline/timeline.py
index b70dce2..f71444c 100644
--- a/pitivi/timeline/timeline.py
+++ b/pitivi/timeline/timeline.py
@@ -1274,7 +1274,7 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
 
         self._project = None
         self.ges_timeline = None
-        self.__copiedGroup = None
+        self.__copied_group = None
 
         self._createUi()
         self._createActions()
@@ -1407,7 +1407,7 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
         self.group_action.set_enabled(selection_non_empty)
         self.ungroup_action.set_enabled(selection_non_empty)
         self.copy_action.set_enabled(selection_non_empty)
-        can_paste = bool(self.__copiedGroup)
+        can_paste = bool(self.__copied_group)
         self.paste_action.set_enabled(can_paste)
         self.keyframe_action.set_enabled(selection_non_empty)
         project_loaded = bool(self._project)
@@ -1669,21 +1669,20 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
 
     def __copyClipsCb(self, unused_action, unused_parameter):
         if self.timeline.current_group:
-            self.__copiedGroup = self.timeline.current_group.copy(True)
+            self.__copied_group = self.timeline.current_group.copy(True)
             self.updateActions()
 
     def __pasteClipsCb(self, unused_action, unused_parameter):
-        if not self.__copiedGroup:
+        if not self.__copied_group:
             self.info("Nothing to paste.")
             return
 
         with self.app.action_log.started("paste",
-                                         
finalizing_action=CommitTimelineFinalizingAction(self._project.pipeline),
-                                         toplevel=True):
-            save = self.__copiedGroup.copy(True)
+                    finalizing_action=CommitTimelineFinalizingAction(self._project.pipeline),
+                    toplevel=True):
             position = self._project.pipeline.getPosition()
-            self.__copiedGroup.paste(position)
-            self.__copiedGroup = save
+            copied_group_shallow_copy = self.__copied_group.paste(position)
+            self.__copied_group = copied_group_shallow_copy.copy(True)
 
     def _alignSelectedCb(self, unused_action, unused_parameter):
         if not self.ges_timeline:
diff --git a/tests/test_timeline_timeline.py b/tests/test_timeline_timeline.py
index a83a5f2..f49eaed 100644
--- a/tests/test_timeline_timeline.py
+++ b/tests/test_timeline_timeline.py
@@ -462,19 +462,17 @@ class TestCopyPaste(BaseTestTimeline):
         return timeline_container
 
     def testCopyPaste(self):
-        position = 20
-
         timeline_container = self.copyClips(2)
         timeline = timeline_container.timeline
-
         layer = timeline.ges_timeline.get_layers()[0]
-        # Monkey patching the pipeline.getPosition method
         project = timeline.ges_timeline.get_asset()
-        project.pipeline.getPosition = mock.Mock(return_value=position)
 
         clips = layer.get_clips()
         self.assertEqual(len(clips), 2)
 
+        # Pasting clips for the first time.
+        position = 20
+        project.pipeline.getPosition = mock.Mock(return_value=position)
         timeline_container.paste_action.emit("activate", None)
 
         n_clips = layer.get_clips()
@@ -485,6 +483,19 @@ class TestCopyPaste(BaseTestTimeline):
         self.assertEqual(copied_clips[0].props.start, position)
         self.assertEqual(copied_clips[1].props.start, position + 10)
 
+        # Pasting same clips second time.
+        position = 40
+        project.pipeline.getPosition = mock.Mock(return_value=position)
+        timeline_container.paste_action.emit("activate", None)
+
+        n_clips = layer.get_clips()
+        self.assertEqual(len(n_clips), 6)
+
+        copied_clips = [clip for clip in n_clips if clip not in clips]
+        self.assertEqual(len(copied_clips), 4)
+        self.assertEqual(copied_clips[2].props.start, position)
+        self.assertEqual(copied_clips[3].props.start, position + 10)
+
 
 class TestEditing(BaseTestTimeline):
 


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