Commit 850446a7 authored by Thibault Saunier's avatar Thibault Saunier

Fix ungrouping and add grouping unit tests

Ungrouping selected clips now deselects all clips so that
user can notice clips are actually not selected

After grouping, add the new group to timeline.current_group
as it keeps being selected.

In the case were we group/ungroup right away,
make sure ungrouping does not recurse and ungroups
more than supposed to.
Reviewed-by: Alexandru Băluț's avatarAlex Băluț <alexandru.balut@gmail.com>
Differential Revision: https://phabricator.freedesktop.org/D624
parent fa8808fe
......@@ -1562,21 +1562,21 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
if toplevel == self.timeline.current_group:
for child in toplevel.get_children(False):
child.ungroup(False)
else:
toplevel.ungroup(False)
self.timeline.resetSelectionGroup()
self.timeline.selection.setSelection([], SELECT)
self.app.action_log.commit()
self._project.pipeline.commit_timeline()
def _groupSelected(self, unused_action, unused_parameter):
if not self.bTimeline:
self.error("No timeline set yet?")
self.info("No timeline set yet?")
return
self.app.action_log.begin("group")
containers = set({})
containers = set()
new_group = None
for obj in self.timeline.selection:
toplevel = obj.get_toplevel_parent()
if toplevel == self.timeline.current_group:
......@@ -1587,10 +1587,13 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
containers.add(toplevel)
if containers:
GES.Container.group(list(containers))
new_group = GES.Container.group(list(containers))
self.timeline.resetSelectionGroup()
if new_group:
self.timeline.current_group.add(new_group)
self._project.pipeline.commit_timeline()
self.app.action_log.commit()
......
......@@ -7,14 +7,17 @@ import gc
import unittest
import tempfile
from gi.repository import Gdk
from gi.repository import Gst
from gi.repository import Gtk
from unittest import mock
from pitivi import check
from pitivi.application import Pitivi
from pitivi.utils.timeline import Selected
from pitivi.utils.loggable import Loggable
from pitivi.utils.timeline import Selected
from pitivi.utils.validate import Event
detect_leaks = os.environ.get("PITIVI_TEST_DETECT_LEAKS", "0") not in ("0", "")
os.environ["PITIVI_USER_CACHE_DIR"] = tempfile.mkdtemp("pitiviTestsuite")
......@@ -107,6 +110,22 @@ class TestCase(unittest.TestCase, Loggable):
self._result = result
unittest.TestCase.run(self, result)
def toggleClipSelection(self, bClip):
'''
Toggle selection state of @bClip.
'''
selected = bool(bClip.ui.get_state_flags() & Gtk.StateFlags.SELECTED)
self.assertEqual(bClip.selected.selected, selected)
bClip.ui.sendFakeEvent(
Event(Gdk.EventType.BUTTON_PRESS, button=1), bClip.ui)
bClip.ui.sendFakeEvent(
Event(Gdk.EventType.BUTTON_RELEASE, button=1), bClip.ui)
self.assertEqual(bool(bClip.ui.get_state_flags() & Gtk.StateFlags.SELECTED),
not selected)
self.assertEqual(bClip.selected.selected, not selected)
def getSampleUri(sample):
assets_dir = os.path.dirname(os.path.abspath(__file__))
......
......@@ -17,12 +17,17 @@
# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
# Boston, MA 02110-1301, USA.
from unittest import TestCase, mock
from tests.common import getPitiviMock
from unittest import mock
from gi.repository import Gdk
from gi.repository import GES
from gi.repository import Gtk
from tests import common
from pitivi.project import Project, ProjectManager
from pitivi.timeline.timeline import Timeline
from pitivi.project import ProjectManager
from pitivi.timeline.timeline import TimelineContainer
from pitivi.utils.validate import Event
from pitivi.utils import ui
......@@ -31,26 +36,23 @@ THIN = ui.LAYER_HEIGHT / 2
THICK = ui.LAYER_HEIGHT
class TestLayers(TestCase):
def createTimeline(self, layers_heights):
app = getPitiviMock()
class BaseTestTimeline(common.TestCase):
def createTimeline(self):
app = common.getPitiviMock()
project_manager = ProjectManager(app)
project_manager.newBlankProject()
project = project_manager.current_project
timeline = Timeline(container=mock.MagicMock(), app=app)
timeline_container = TimelineContainer(app)
timeline_container.setProject(project)
timeline = timeline_container.timeline
timeline.get_parent = mock.MagicMock()
timeline.setProject(project)
y = 0
for priority, height in enumerate(layers_heights):
bLayer = timeline.createLayer(priority=priority)
rect = Gdk.Rectangle()
rect.y = y
rect.height = height
bLayer.ui.set_allocation(rect)
y += height + SEPARATOR_HEIGHT
return timeline
class TestLayers(BaseTestTimeline):
def testDraggingLayer(self):
self.checkGetLayerAt([THIN, THIN, THIN], 1, True,
[0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2])
......@@ -82,7 +84,17 @@ class TestLayers(TestCase):
[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 = self.createTimeline(heights)
timeline = self.createTimeline()
y = 0
for priority, height in enumerate(heights):
bLayer = timeline.createLayer(priority=priority)
rect = Gdk.Rectangle()
rect.y = y
rect.height = height
bLayer.ui.set_allocation(rect)
y += height + SEPARATOR_HEIGHT
bLayers = [layer.bLayer for layer in timeline._layers]
if preferred is None:
preferred_bLayer = None
......@@ -126,3 +138,82 @@ class TestLayers(TestCase):
assertLayerAt(bLayers[expectations[13]], h[0] + s + h[1] + s + h[2] / 2 - 1)
assertLayerAt(bLayers[expectations[14]], h[0] + s + h[1] + s + h[2] / 2)
assertLayerAt(bLayers[expectations[15]], h[0] + s + h[1] + s + h[2] - 1)
class TestGrouping(BaseTestTimeline):
def groupClips(self, num_clips):
timeline = self.createTimeline()
timeline.app.settings.leftClickAlsoSeeks = False
layer = timeline.bTimeline.append_layer()
asset = GES.UriClipAsset.request_sync(
common.getSampleUri("tears_of_steel.webm"))
clips = [layer.add_asset(asset, i * 10, 0, 10, GES.TrackType.UNKNOWN)
for i in range(num_clips)]
# Press <ctrl> so selecting in ADD mode
timeline.sendFakeEvent(Event(event_type=Gdk.EventType.KEY_PRESS,
keyval=Gdk.KEY_Control_L))
# Select the 2 clips
for clip in clips:
self.toggleClipSelection(clip)
before_grouping_timeline_group = timeline.current_group
for clip in clips:
self.assertEqual(clip.get_parent(), timeline.current_group)
timeline.parent.group_action.emit("activate", None)
self.assertNotEqual(timeline.current_group, before_grouping_timeline_group)
for clip in clips:
# Check that we created a new group and that this group is not
# the timeline current_group
self.assertTrue(isinstance(clip.get_parent(), GES.Group))
self.assertNotEqual(clip.get_parent(), timeline.current_group)
# The newly created group has been selected
self.assertEqual(clip.get_toplevel_parent(), timeline.current_group)
for clip in clips:
self.assertEqual(clips[0].get_parent(), clip.get_parent())
self.assertTrue(bool(clip.ui.get_state_flags() & Gtk.StateFlags.SELECTED))
self.assertTrue(clip.selected.selected)
group = clips[0].get_parent()
self.assertEqual(len(group.get_children(False)), num_clips)
return timeline
def testGroup(self):
self.groupClips(2)
def testGroupSelection(self):
num_clips = 2
timeline = self.groupClips(num_clips)
layer = timeline.bTimeline.get_layers()[0]
clips = layer.get_clips()
self.assertEqual(len(clips), num_clips)
# Deselect one grouped clip clips
self.toggleClipSelection(clips[0])
# Make sure all the clips have been deselected
for clip in clips:
self.assertFalse(bool(clip.ui.get_state_flags() & Gtk.StateFlags.SELECTED))
self.assertFalse(clip.selected.selected)
def testGroupUngroup(self):
num_clips = 2
timeline = self.groupClips(num_clips)
self.assertEqual(len(timeline.selection.selected), num_clips)
timeline.parent.ungroup_action.emit("activate", None)
layer = timeline.bTimeline.get_layers()[0]
clips = layer.get_clips()
self.assertEqual(len(clips), num_clips)
for clip in clips:
self.assertIsNone(clip.get_parent())
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