Commit f3db09ab authored by Alexandru Băluț's avatar Alexandru Băluț

timeline: Simplified the can-group/ungroup logic

parent d572d811
......@@ -840,7 +840,7 @@ class Timeline(Gtk.EventBox, Zoomable, Loggable):
toplevel = clip.get_toplevel_parent()
if isinstance(toplevel, GES.Group) and toplevel != self.current_group:
grouped_clips.update([c for c in toplevel.get_children(True)
if isinstance(c, GES.Clip)])
if isinstance(c, GES.Clip)])
return clips.union(grouped_clips)
......@@ -1538,7 +1538,7 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
self.delete_action.set_enabled(selection_non_empty)
self.delete_and_shift_action.set_enabled(selection_non_empty)
self.group_action.set_enabled(selection.can_group)
self.ungroup_action.set_enabled(selection.can_ungroup and not selection.can_group)
self.ungroup_action.set_enabled(selection.can_ungroup)
self.copy_action.set_enabled(selection_non_empty)
can_paste = bool(self.__copied_group)
self.paste_action.set_enabled(can_paste)
......@@ -1767,9 +1767,9 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
finalizing_action=CommitTimelineFinalizingAction(self._project.pipeline),
toplevel=True):
for clip in self.timeline.selection:
layer = clip.get_layer()
if isinstance(clip, GES.TransitionClip):
continue
layer = clip.get_layer()
layer.remove_clip(clip)
self.timeline.selection.setSelection([], SELECT)
......
......@@ -141,18 +141,14 @@ class Selection(GObject.Object, Loggable):
self.emit("selection-changed")
def set_can_group_ungroup(self):
containers = set()
for obj in self.selected:
toplevel = obj.get_toplevel_parent()
if not toplevel.props.serialize:
for child in toplevel.get_children(False):
containers.add(child)
else:
containers.add(toplevel)
if len(containers) > 1:
can_ungroup = False
toplevels = self.toplevels
for toplevel in toplevels:
if isinstance(toplevel, GES.Group) or len(toplevel.get_children(False)) > 1:
can_ungroup = True
break
self.can_group = len(containers) > 1
self.can_ungroup = len(self.getSelectedTrackElements()) > 1
self.can_group = len(toplevels) > 1
self.can_ungroup = can_ungroup and not self.can_group
def __get_selection_changes(self, old_selection):
for obj in old_selection - self.selected:
......@@ -182,17 +178,6 @@ class Selection(GObject.Object, Loggable):
return set(objects)
def getSelectedTrackElementsAtPosition(self, position, element_type=GObject.Object,
track_type=GES.TrackType.UNKNOWN):
selected = []
for clip in self.selected:
if clip.props.start <= position and position <= clip.props.start + clip.props.duration:
elements = clip.find_track_elements(None, track_type, element_type)
if elements:
selected.extend(elements)
return selected
def getSingleClip(self, clip_type=GES.SourceClip):
"""Returns the single-selected clip, if any.
......@@ -205,6 +190,28 @@ class Selection(GObject.Object, Loggable):
return clip
return None
@property
def toplevels(self):
"""Returns the toplevel elements of the selection."""
toplevels = set()
for obj in self.selected:
if not obj.timeline:
# The element has been removed from the timeline. Ignore it.
continue
toplevel = obj.get_toplevel_parent()
toplevels.update(self.__serializable_toplevels(toplevel))
return toplevels
def __serializable_toplevels(self, toplevel):
"""Generates the specified element if serializable, or its children."""
if toplevel.props.serialize:
yield toplevel
else:
for element in toplevel.get_children(False):
for child in self.__serializable_toplevels(element):
yield child
def __len__(self):
return len(self.selected)
......
......@@ -27,7 +27,6 @@ from pitivi.utils.timeline import UNSELECT
from pitivi.utils.ui import LAYER_HEIGHT
from pitivi.utils.ui import SEPARATOR_HEIGHT
from tests import common
from tests.common import create_timeline_container
THIN = LAYER_HEIGHT / 2
THICK = LAYER_HEIGHT
......@@ -87,7 +86,7 @@ class TestLayers(BaseTestTimeline):
[0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2])
def checkGetLayerAt(self, heights, preferred, past_middle_when_adjacent, expectations):
timeline_container = create_timeline_container()
timeline_container = common.create_timeline_container()
timeline = timeline_container.timeline
# Allocate layers
......@@ -146,7 +145,7 @@ class TestLayers(BaseTestTimeline):
assertLayerAt(ges_layers[expectations[15]], h[0] + s + h[1] + s + h[2] - 1)
def testSetSeparatorsPrelight(self):
timeline_container = create_timeline_container()
timeline_container = common.create_timeline_container()
timeline = timeline_container.timeline
timeline.__on_separators = [mock.Mock()]
timeline._setSeparatorsPrelight(False)
......@@ -154,7 +153,7 @@ class TestLayers(BaseTestTimeline):
"The separators must be forgotten only in dragEnd()")
def test_media_types(self):
timeline_container = create_timeline_container()
timeline_container = common.create_timeline_container()
timeline = timeline_container.timeline
ges_layer_1 = timeline.ges_timeline.append_layer()
......@@ -194,7 +193,7 @@ class TestLayers(BaseTestTimeline):
self.check_create_layer([0, 1, 2, 3], [0, 1, 2, 3])
def check_create_layer(self, start_priorities, expected_priorities):
timeline = create_timeline_container().timeline
timeline = common.create_timeline_container().timeline
ges_layers = []
for priority in start_priorities:
ges_layer = timeline.create_layer(priority)
......@@ -249,7 +248,7 @@ class TestLayers(BaseTestTimeline):
self.check_remove_layer([3, 2, 1])
def check_remove_layer(self, removal_order):
timeline = create_timeline_container().timeline
timeline = common.create_timeline_container().timeline
# Add layers to remove them later.
ges_layers = []
......@@ -276,7 +275,7 @@ class TestLayers(BaseTestTimeline):
self.check_move_layer(4, 3, [0, 1, 2, 4, 3])
def check_move_layer(self, from_priority, to_priority, expected_priorities):
timeline = create_timeline_container().timeline
timeline = common.create_timeline_container().timeline
# Add layers to move them later.
ges_layers = []
......@@ -291,11 +290,11 @@ class TestLayers(BaseTestTimeline):
class TestGrouping(BaseTestTimeline):
def __check_can_group_ungroup(self, timeline_container, can_group, can_ungroup):
self.assertEqual(can_group, timeline_container.group_action.props.enabled)
self.assertEqual(can_ungroup, timeline_container.ungroup_action.props.enabled)
self.assertEqual(timeline_container.group_action.props.enabled, can_group)
self.assertEqual(timeline_container.ungroup_action.props.enabled, can_ungroup)
def test_can_group_ungroup(self):
timeline_container = create_timeline_container()
timeline_container = common.create_timeline_container()
timeline = timeline_container.timeline
self.__check_can_group_ungroup(timeline_container, False, False)
ges_clip, = self.addClipsSimple(timeline, 1)
......@@ -361,14 +360,14 @@ class TestGrouping(BaseTestTimeline):
self.assertEqual(len(group.get_children(False)), len(clips))
def testGroup(self):
timeline_container = create_timeline_container()
timeline_container = common.create_timeline_container()
timeline = timeline_container.timeline
clips = self.addClipsSimple(timeline, 2)
self.group_clips(timeline_container, clips)
def testGroupSelection(self):
num_clips = 2
timeline_container = create_timeline_container()
timeline_container = common.create_timeline_container()
timeline = timeline_container.timeline
clips = self.addClipsSimple(timeline, num_clips)
self.group_clips(timeline_container, clips)
......@@ -386,7 +385,7 @@ class TestGrouping(BaseTestTimeline):
def testGroupUngroup(self):
num_clips = 2
timeline_container = create_timeline_container()
timeline_container = common.create_timeline_container()
timeline = timeline_container.timeline
clips = self.addClipsSimple(timeline, num_clips)
self.group_clips(timeline_container, clips)
......@@ -404,7 +403,7 @@ class TestGrouping(BaseTestTimeline):
def testGroupSplittedClipAndSelectGroup(self):
position = 5
timeline_container = create_timeline_container()
timeline_container = common.create_timeline_container()
timeline = timeline_container.timeline
clips = self.addClipsSimple(timeline, 1)
self.toggle_clip_selection(clips[0], expect_selected=True)
......@@ -439,7 +438,7 @@ class TestGrouping(BaseTestTimeline):
self.toggle_clip_selection(clips[1], expect_selected=True)
def testUngroupClip(self):
timeline_container = create_timeline_container()
timeline_container = common.create_timeline_container()
timeline = timeline_container.timeline
ges_clip, = self.addClipsSimple(timeline, 1)
......@@ -472,7 +471,7 @@ class TestGrouping(BaseTestTimeline):
def test_dragging_group_on_separator(self):
# Create two clips on different layers and group them.
timeline_container = create_timeline_container()
timeline_container = common.create_timeline_container()
timeline = timeline_container.timeline
clip1, = self.addClipsSimple(timeline, 1)
layer1 = clip1.get_layer()
......@@ -513,7 +512,7 @@ class TestGrouping(BaseTestTimeline):
class TestCopyPaste(BaseTestTimeline):
def copyClips(self, num_clips):
timeline_container = create_timeline_container()
timeline_container = common.create_timeline_container()
timeline = timeline_container.timeline
clips = self.addClipsSimple(timeline, num_clips)
......@@ -576,7 +575,7 @@ class TestEditing(BaseTestTimeline):
def test_trimming_on_layer_separator(self):
# Create a clip
timeline_container = create_timeline_container()
timeline_container = common.create_timeline_container()
timeline = timeline_container.timeline
clip, = self.addClipsSimple(timeline, 1)
layer = clip.get_layer()
......@@ -624,7 +623,7 @@ class TestShiftSelection(BaseTestTimeline):
self.assertEqual(clip.selected._selected, False)
def __check_simple(self, left_click_also_seeks):
timeline_container = create_timeline_container()
timeline_container = common.create_timeline_container()
timeline = timeline_container.timeline
timeline.app.settings.leftClickAlsoSeeks = left_click_also_seeks
ges_layer = timeline.ges_timeline.append_layer()
......@@ -658,7 +657,7 @@ class TestShiftSelection(BaseTestTimeline):
def __check_shift_selection_single_layer(self, left_click_also_seeks):
"""Checks group clips selection across a single layer."""
timeline_container = create_timeline_container()
timeline_container = common.create_timeline_container()
timeline = timeline_container.timeline
timeline.app.settings.leftClickAlsoSeeks = left_click_also_seeks
ges_layer = timeline.ges_timeline.append_layer()
......@@ -719,7 +718,7 @@ class TestShiftSelection(BaseTestTimeline):
def __check_shift_selection_multiple_layers(self, left_click_also_seeks):
"""Checks group clips selection across multiple layers."""
timeline_container = create_timeline_container()
timeline_container = common.create_timeline_container()
timeline = timeline_container.timeline
timeline.app.settings.leftClickAlsoSeeks = left_click_also_seeks
ges_layer1 = timeline.ges_timeline.append_layer()
......
......@@ -27,6 +27,7 @@ from pitivi.utils.timeline import Selected
from pitivi.utils.timeline import Selection
from pitivi.utils.timeline import UNSELECT
from tests import common
from tests.test_timeline_timeline import BaseTestTimeline
class TestSelected(common.TestCase):
......@@ -42,7 +43,7 @@ class TestSelected(common.TestCase):
self.assertFalse(selected)
class TestSelection(common.TestCase):
class TestSelection(BaseTestTimeline):
def testBoolEvaluation(self):
clip1 = mock.MagicMock()
......@@ -81,14 +82,17 @@ class TestSelection(common.TestCase):
self.assertIsNone(selection.getSingleClip(GES.TitleClip))
def test_can_group_ungroup(self):
clip1 = common.create_test_clip(GES.UriClip)
clip2 = common.create_test_clip(GES.UriClip)
timeline_container = common.create_timeline_container()
timeline = timeline_container.timeline
clip1, clip2 = self.addClipsSimple(timeline, 2)
selection = Selection()
self.assertFalse(selection)
self.assertFalse(selection.can_group)
self.assertFalse(selection.can_ungroup)
selection.setSelection([clip1], SELECT)
self.assertFalse(selection.can_ungroup)
self.assertFalse(selection.can_group)
self.assertTrue(selection.can_ungroup)
selection.setSelection([clip2], SELECT_ADD)
self.assertTrue(selection.can_group)
......@@ -98,6 +102,36 @@ class TestSelection(common.TestCase):
self.assertFalse(selection.can_group)
self.assertFalse(selection.can_ungroup)
def test_toplevels(self):
timeline_container = common.create_timeline_container()
timeline = timeline_container.timeline
clip1, clip2, clip3, clip4 = self.addClipsSimple(timeline, 4)
selection = Selection()
selection.setSelection([clip1, clip2, clip3, clip4], SELECT)
self.assertSetEqual(selection.toplevels, {clip1, clip2, clip3, clip4})
group1 = GES.Container.group([clip1, clip2])
group1.props.serialize = True
self.assertSetEqual(selection.toplevels, {group1, clip3, clip4})
group2 = GES.Container.group([group1, clip3])
group2.props.serialize = True
self.assertSetEqual(selection.toplevels, {group2, clip4})
group1.props.serialize = True
group1.props.serialize = False
self.assertSetEqual(selection.toplevels, {group2, clip4})
group1.props.serialize = False
group2.props.serialize = False
self.assertSetEqual(selection.toplevels, {clip1, clip2, clip3, clip4})
group1.props.serialize = True
group2.props.serialize = False
self.assertSetEqual(selection.toplevels, {group1, clip3, clip4})
class TestEditingContext(common.TestCase):
"""Tests for the EditingContext class."""
......
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