Commit d092f674 authored by Harish Fulara's avatar Harish Fulara Committed by Alexandru Băluț

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
parent 29a060cf
......@@ -1286,7 +1286,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()
......@@ -1420,7 +1420,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)
......@@ -1730,21 +1730,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:
......
......@@ -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):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment