[pitivi] elements: Move the add effect logic to Clip
- From: Alexandru Băluț <alexbalut src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pitivi] elements: Move the add effect logic to Clip
- Date: Sun, 11 Dec 2016 14:43:23 +0000 (UTC)
commit 060cbe150eb088807005dcf77d9e97a40f8a474d
Author: Alexandru Băluț <alexandru balut gmail com>
Date: Fri Dec 9 20:55:02 2016 +0100
elements: Move the add effect logic to Clip
Reviewed-by: Thibault Saunier <tsaunier gnome org>
Differential Revision: https://phabricator.freedesktop.org/D1543
pitivi/clipproperties.py | 55 +++++------------------------------------
pitivi/effects.py | 32 +++++++++++++++++++++++-
pitivi/timeline/elements.py | 36 ++++++++++++++++++++++++++-
pitivi/utils/timeline.py | 2 +-
tests/test_effects.py | 30 +++++++++++++++++++++++
tests/test_utils_timeline.py | 19 +++++++++-----
6 files changed, 114 insertions(+), 60 deletions(-)
---
diff --git a/pitivi/clipproperties.py b/pitivi/clipproperties.py
index b7bbe24..5178bf3 100644
--- a/pitivi/clipproperties.py
+++ b/pitivi/clipproperties.py
@@ -27,11 +27,8 @@ from gi.repository import Gtk
from gi.repository import Pango
from pitivi.configure import get_ui_dir
-from pitivi.effects import ALLOWED_ONLY_ONCE_EFFECTS
-from pitivi.effects import AUDIO_EFFECT
from pitivi.effects import EffectsPropertiesManager
from pitivi.effects import HIDDEN_EFFECTS
-from pitivi.effects import VIDEO_EFFECT
from pitivi.undo.timeline import CommitTimelineFinalizingAction
from pitivi.utils.loggable import Loggable
from pitivi.utils.ui import disable_scroll
@@ -296,50 +293,6 @@ class EffectProperties(Gtk.Expander, Loggable):
effect.get_parent().remove(effect)
self._updateTreeview()
- def addEffectToClip(self, clip, factory_name, priority=None):
- """Adds the specified effect if it can be applied to the clip."""
- if factory_name in ALLOWED_ONLY_ONCE_EFFECTS:
- for effect in clip.find_track_elements(None, GES.TrackType.VIDEO,
- GES.BaseEffect):
- for elem in effect.get_nleobject().iterate_recurse():
- if elem.get_factory().get_name() == factory_name:
- self.error("Not adding %s as it would be duplicate"
- " and this is not allowed.", factory_name)
- # TODO Let the user know about why it did not work.
- return effect
-
- model = self.treeview.get_model()
- effect_info = self.app.effects.getInfo(factory_name)
- media_type = effect_info.media_type
-
- for track_element in clip.get_children(False):
- track_type = track_element.get_track_type()
- if track_type == GES.TrackType.AUDIO and media_type == AUDIO_EFFECT or \
- track_type == GES.TrackType.VIDEO and media_type == VIDEO_EFFECT:
- # Actually add the effect
- pipeline = self._project.pipeline
- with self.app.action_log.started("add effect",
- CommitTimelineFinalizingAction(pipeline)):
- effect = GES.Effect.new(effect_info.bin_description)
- clip.add(effect)
- if priority is not None and priority < len(model):
- clip.set_top_effect_priority(effect, priority)
- break
- return None
-
- def addEffectToCurrentSelection(self, factory_name):
- """Adds an effect to the current selection.
-
- Args:
- factory_name (str): The name of the GstElementFactory for creating
- the effect.
- """
- if not self.clip:
- return
- # Checking that this effect can be applied on this track object
- # Which means, it has the corresponding media_type
- self.addEffectToClip(self.clip, factory_name)
-
# pylint: disable=too-many-arguments
def _dragMotionCb(self, unused_tree_view, unused_drag_context, unused_x, unused_y, unused_timestamp):
self.debug(
@@ -362,7 +315,13 @@ class EffectProperties(Gtk.Expander, Loggable):
# An effect dragged probably from the effects list.
factory_name = str(selection_data.get_data(), "UTF-8")
drop_index = self.__get_new_effect_index(dest_row)
- self.addEffectToClip(self.clip, factory_name, drop_index)
+ effect_info = self.app.effects.getInfo(factory_name)
+ pipeline = self._project.pipeline
+ with self.app.action_log.started("add effect",
+ CommitTimelineFinalizingAction(pipeline)):
+ effect = self.clip.ui.add_effect(effect_info)
+ if effect:
+ self.clip.set_top_effect_priority(effect, drop_index)
elif drag_context.get_suggested_action() == Gdk.DragAction.MOVE:
# An effect dragged from the same treeview to change its position.
# Source
diff --git a/pitivi/effects.py b/pitivi/effects.py
index 88dc2fb..9ab5e82 100644
--- a/pitivi/effects.py
+++ b/pitivi/effects.py
@@ -34,6 +34,7 @@ from gettext import gettext as _
from gi.repository import Gdk
from gi.repository import GdkPixbuf
+from gi.repository import GES
from gi.repository import GLib
from gi.repository import Gst
from gi.repository import Gtk
@@ -191,6 +192,23 @@ class EffectInfo(object):
else:
return bin_description
+ def good_for_track_element(self, track_element):
+ """Checks the effect is compatible with the specified track element.
+
+ Args:
+ track_element (GES.TrackElement): The track element to check against.
+
+ Returns:
+ bool: Whether it makes sense to apply the effect to the track element.
+ """
+ track_type = track_element.get_track_type()
+ if track_type == GES.TrackType.AUDIO:
+ return self.media_type == AUDIO_EFFECT
+ elif track_type == GES.TrackType.VIDEO:
+ return self.media_type == VIDEO_EFFECT
+ else:
+ return False
+
class EffectsManager(object):
"""Keeps info about effects and their categories.
@@ -483,10 +501,20 @@ class EffectListWidget(Gtk.Box, Loggable):
return True
def _addSelectedEffect(self):
+ """Adds the selected effect to the single selected clip, if any."""
effect = self.getSelectedEffect()
- if not effect:
+ effect_info = self.app.effects.getInfo(effect)
+ if not effect_info:
+ return
+ timeline = self.app.gui.timeline_ui.timeline
+ clip = timeline.selection.getSingleClip()
+ if not clip:
return
- self.app.gui.clipconfig.effect_expander.addEffectToCurrentSelection(effect)
+ pipeline = timeline.ges_timeline.get_parent()
+ from pitivi.undo.timeline import CommitTimelineFinalizingAction
+ with self.app.action_log.started("add effect",
+ CommitTimelineFinalizingAction(pipeline)):
+ clip.ui.add_effect(effect_info)
def getSelectedEffect(self):
if self._draggedItems:
diff --git a/pitivi/timeline/elements.py b/pitivi/timeline/elements.py
index 2ceb6f9..90272f7 100644
--- a/pitivi/timeline/elements.py
+++ b/pitivi/timeline/elements.py
@@ -32,8 +32,12 @@ from matplotlib.backends.backend_gtk3cairo import FigureCanvasGTK3Cairo as Figur
from matplotlib.figure import Figure
from pitivi.configure import get_pixmap_dir
+from pitivi.effects import ALLOWED_ONLY_ONCE_EFFECTS
+from pitivi.effects import AUDIO_EFFECT
+from pitivi.effects import VIDEO_EFFECT
from pitivi.timeline.previewers import AudioPreviewer
from pitivi.timeline.previewers import VideoPreviewer
+from pitivi.undo.timeline import CommitTimelineFinalizingAction
from pitivi.utils.loggable import Loggable
from pitivi.utils.misc import disconnectAllByFunc
from pitivi.utils.misc import filename_from_uri
@@ -911,8 +915,11 @@ class Clip(Gtk.EventBox, Zoomable, Loggable):
self.timeline.selection.setSelection([self.ges_clip], SELECT)
self.app.gui.switchContextTab(self.ges_clip)
- self.app.gui.clipconfig.effect_expander.addEffectToClip(self.ges_clip,
- self.timeline.dropData)
+ effect_info = self.app.effects.getInfo(self.timeline.dropData)
+ pipeline = self.timeline.ges_timeline.get_parent()
+ with self.app.action_log.started("add effect",
+ CommitTimelineFinalizingAction(pipeline)):
+ self.add_effect(effect_info)
self.timeline.cleanDropData()
success = True
@@ -920,6 +927,31 @@ class Clip(Gtk.EventBox, Zoomable, Loggable):
return success
+ def add_effect(self, effect_info):
+ """Adds the specified effect if it can be applied to the clip.
+
+ Args:
+ effect_info (EffectInfo): The effect to add.
+ """
+ factory_name = effect_info.effect_name
+ if factory_name in ALLOWED_ONLY_ONCE_EFFECTS:
+ for effect in self.find_track_elements(None, GES.TrackType.VIDEO,
+ GES.BaseEffect):
+ for elem in effect.get_nleobject().iterate_recurse():
+ if elem.get_factory().get_name() == factory_name:
+ self.error("Not adding %s as it would be duplicate"
+ " and this is not allowed.", factory_name)
+ # TODO Let the user know about why it did not work.
+ return effect
+
+ for track_element in self.ges_clip.get_children(False):
+ if effect_info.good_for_track_element(track_element):
+ # Actually add the effect
+ effect = GES.Effect.new(effect_info.bin_description)
+ self.ges_clip.add(effect)
+ return effect
+ return None
+
def updatePosition(self):
layer = self.layer
if not layer or layer != self.get_parent():
diff --git a/pitivi/utils/timeline.py b/pitivi/utils/timeline.py
index 42a38dc..b99387b 100644
--- a/pitivi/utils/timeline.py
+++ b/pitivi/utils/timeline.py
@@ -175,7 +175,7 @@ class Selection(GObject.Object, Loggable):
return selected
- def getSingleClip(self, clip_type):
+ def getSingleClip(self, clip_type=GES.SourceClip):
"""Returns the single-selected clip, if any.
Args:
diff --git a/tests/test_effects.py b/tests/test_effects.py
index e368e4f..3800be5 100644
--- a/tests/test_effects.py
+++ b/tests/test_effects.py
@@ -19,7 +19,13 @@
"""Tests for the effects module."""
import unittest
+from gi.repository import GES
+
+from pitivi.effects import AUDIO_EFFECT
from pitivi.effects import EffectInfo
+from pitivi.effects import VIDEO_EFFECT
+from tests.common import create_timeline_container
+from tests.common import get_sample_uri
class EffectInfoTest(unittest.TestCase):
@@ -37,3 +43,27 @@ class EffectInfoTest(unittest.TestCase):
"""Tests the name_from_bin_description method."""
self.assertEqual(EffectInfo.name_from_bin_description("name"), "name")
self.assertEqual(EffectInfo.name_from_bin_description("glupload ! glname ! gldownload"), "glname")
+
+ def test_good_for_track_element(self):
+ """Tests the good_for_track_element method."""
+ uri = get_sample_uri("tears_of_steel.webm")
+ asset = GES.UriClipAsset.request_sync(uri)
+ ges_clip = asset.extract()
+
+ # Add the clip to a timeline so it gets tracks.
+ ges_timeline = create_timeline_container().timeline.ges_timeline
+ ges_timeline.append_layer()
+ ges_layer, = ges_timeline.get_layers()
+ ges_layer.add_clip(ges_clip)
+ track_elements = dict([(track_element.get_track_type(), track_element)
+ for track_element in ges_clip.get_children(recursive=True)])
+ audio_track_element = track_elements[GES.TrackType.AUDIO]
+ video_track_element = track_elements[GES.TrackType.VIDEO]
+
+ effect_info = EffectInfo(None, AUDIO_EFFECT, None, None, None)
+ self.assertTrue(effect_info.good_for_track_element(audio_track_element))
+ self.assertFalse(effect_info.good_for_track_element(video_track_element))
+
+ effect_info = EffectInfo(None, VIDEO_EFFECT, None, None, None)
+ self.assertFalse(effect_info.good_for_track_element(audio_track_element))
+ self.assertTrue(effect_info.good_for_track_element(video_track_element))
diff --git a/tests/test_utils_timeline.py b/tests/test_utils_timeline.py
index 15fc920..7420c2b 100644
--- a/tests/test_utils_timeline.py
+++ b/tests/test_utils_timeline.py
@@ -61,16 +61,21 @@ class TestSelection(TestCase):
clip2 = common.create_test_clip(GES.TitleClip)
# Selection empty.
- self.assertFalse(selection.getSingleClip(GES.TitleClip))
+ self.assertIsNone(selection.getSingleClip())
+ self.assertIsNone(selection.getSingleClip(GES.UriClip))
+ self.assertIsNone(selection.getSingleClip(GES.TitleClip))
- # Selection contains only a non-requested-type clip.
selection.setSelection([clip1], SELECT)
- self.assertFalse(selection.getSingleClip(GES.TitleClip))
+ self.assertEqual(selection.getSingleClip(), clip1)
+ self.assertEqual(selection.getSingleClip(GES.UriClip), clip1)
+ self.assertIsNone(selection.getSingleClip(GES.TitleClip))
- # Selection contains only requested-type clip.
selection.setSelection([clip2], SELECT)
- self.assertEqual(clip2, selection.getSingleClip(GES.TitleClip))
+ self.assertEqual(selection.getSingleClip(), clip2)
+ self.assertIsNone(selection.getSingleClip(GES.UriClip))
+ self.assertEqual(selection.getSingleClip(GES.TitleClip), clip2)
- # Selection contains more than one clip.
selection.setSelection([clip1, clip2], SELECT)
- self.assertFalse(selection.getSingleClip(GES.UriClip))
+ self.assertIsNone(selection.getSingleClip())
+ self.assertIsNone(selection.getSingleClip(GES.UriClip))
+ self.assertIsNone(selection.getSingleClip(GES.TitleClip))
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]