[pitivi] elements: Move the add effect logic to Clip



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]