[pitivi] Initialize the project settings from the first imported asset



commit a78b504bdbdee434791db67ddb842e944f76c2e9
Author: Alexandru Băluț <alexandru balut gmail com>
Date:   Mon Oct 19 23:02:20 2015 +0200

    Initialize the project settings from the first imported asset
    
    Either the user does not care about the project settings and then the
    project settings dialog when starting a new project scares him, or
    the user is an advanced user, in which case they'll know when they need
    to change the project settings and where to find them.
    
    Fixes https://phabricator.freedesktop.org/T3161
    
    Differential Revision: https://phabricator.freedesktop.org/D387
    Reviewed-by: Thibault Saunier <tsaunier gnome org>

 pitivi/dialogs/startupwizard.py |    1 -
 pitivi/mainwindow.py            |    3 +-
 pitivi/project.py               |   42 +++++++++++++++++++++--
 tests/test_project.py           |   70 ++++++++++++++++++++++++++++++++++----
 4 files changed, 102 insertions(+), 14 deletions(-)
---
diff --git a/pitivi/dialogs/startupwizard.py b/pitivi/dialogs/startupwizard.py
index dbfcf64..76df4b0 100644
--- a/pitivi/dialogs/startupwizard.py
+++ b/pitivi/dialogs/startupwizard.py
@@ -104,7 +104,6 @@ class StartUpWizard(object):
         """Handle a click on the New (Project) button."""
         self.app.project_manager.newBlankProject()
         self.hide()
-        self.app.gui.showProjectSettingsDialog()
 
     def _loadCb(self, unused_recent_chooser):
         """
diff --git a/pitivi/mainwindow.py b/pitivi/mainwindow.py
index b49b1dd..1eff8d9 100644
--- a/pitivi/mainwindow.py
+++ b/pitivi/mainwindow.py
@@ -585,8 +585,7 @@ class PitiviMainWindow(Gtk.ApplicationWindow, Loggable):
 # Toolbar/Menu actions callback
 
     def _newProjectMenuCb(self, unused_action, unused_param):
-        if self.app.project_manager.newBlankProject() is not False:
-            self.showProjectSettingsDialog()
+        self.app.project_manager.newBlankProject()
 
     def _openProjectCb(self, unused_action, unused_param):
         self.openProject()
diff --git a/pitivi/project.py b/pitivi/project.py
index 03b24b9..df86177 100644
--- a/pitivi/project.py
+++ b/pitivi/project.py
@@ -716,8 +716,8 @@ class Project(Loggable, GES.Project):
 
     def __init__(self, app, name="", uri=None, scenario=None, **unused_kwargs):
         """
-        @param name: the name of the project
-        @param uri: the uri of the project
+        @param name: The name of the project, if it's a new empty project.
+        @param uri: The URI of the project it will be loaded from.
         """
         Loggable.__init__(self)
         GES.Project.__init__(self, uri=uri, extractable_type=GES.Timeline)
@@ -767,9 +767,12 @@ class Project(Loggable, GES.Project):
         self.aencoder = DEFAULT_AUDIO_ENCODER
         self._ensureAudioRestrictions()
         self._ensureVideoRestrictions()
+        has_default_settings = not bool(uri) and not bool(scenario)
+        self._has_default_audio_settings = has_default_settings
+        self._has_default_video_settings = has_default_settings
 
         # FIXME That does not really belong to here and should be savable into
-        # The serilized file. For now, just let it be here.
+        # The serialized file. For now, just let it be here.
         # A (muxer -> containersettings) map.
         self._containersettings_cache = {}
         # A (vencoder -> vcodecsettings) map.
@@ -873,9 +876,11 @@ class Project(Loggable, GES.Project):
         return False
 
     def setVideoRestriction(self, name, value):
+        self._has_default_video_settings = False
         return Project._set_restriction(self.video_profile, name, value)
 
     def __setAudioRestriction(self, name, value):
+        self._has_default_audio_settings = False
         return Project._set_restriction(self.audio_profile, name, value)
 
     @property
@@ -1029,6 +1034,7 @@ class Project(Loggable, GES.Project):
         get calls
         """
         self._handle_asset_loaded(asset=asset)
+        self._maybeInitSettingsFromAsset(asset)
 
     def do_loading_error(self, unused_error, unused_asset_id, unused_type):
         """ vmethod, get called on "asset-loading-error"""
@@ -1309,6 +1315,36 @@ class Project(Loggable, GES.Project):
         if not self.audiorate:
             self.audiorate = 44100
 
+    def _maybeInitSettingsFromAsset(self, asset):
+        """Update the project settings to match the specified asset."""
+        if not (self._has_default_video_settings or
+                self._has_default_audio_settings):
+            # Both audio and video settings have been set already by the user.
+            return
+        if not isinstance(asset, GES.UriClipAsset):
+            # We are only interested in actual files, not in titles, for example.
+            return
+        info = asset.get_info()
+        video_streams = info.get_video_streams()
+        if video_streams and self._has_default_video_settings:
+            video = video_streams[0]
+            if not video.is_image():
+                self.videowidth = video.get_width()
+                self.videoheight = video.get_height()
+                if video.get_framerate_num() > 0:
+                    # The asset has a non-variable framerate.
+                    self.videorate = Gst.Fraction(video.get_framerate_num(),
+                                                  video.get_framerate_denom())
+                self.videopar = Gst.Fraction(video.get_par_num(),
+                                             video.get_par_denom())
+                self._has_default_video_settings = False
+        audio_streams = info.get_audio_streams()
+        if audio_streams and self._has_default_audio_settings:
+            audio = audio_streams[0]
+            self.audiochannels = audio.get_channels()
+            self.audiorate = audio.get_sample_rate()
+            self._has_default_audio_settings = False
+
     def _emitChange(self, signal, key=None, value=None):
         if key and value:
             self.emit(signal, key, value)
diff --git a/tests/test_project.py b/tests/test_project.py
index 8bbae73..34444e7 100644
--- a/tests/test_project.py
+++ b/tests/test_project.py
@@ -28,8 +28,10 @@ from gi.repository import GES
 from gi.repository import GLib
 from gi.repository import Gst
 
+from tests import common
+
 from pitivi.application import Pitivi
-from pitivi.project import ProjectManager
+from pitivi.project import ProjectManager, Project
 from pitivi.utils.misc import uri_is_reachable
 
 
@@ -37,9 +39,10 @@ def _createRealProject(name=None):
     app = Pitivi()
     project_manager = ProjectManager(app)
     project_manager.newBlankProject()
+    project = project_manager.current_project
     if name:
-        project_manager.current_project.name = name
-    return project_manager.current_project
+        project.name = name
+    return project
 
 
 class MockProject(object):
@@ -310,7 +313,7 @@ class TestProjectManager(TestCase):
                          "Backup file not deleted when project closed")
 
 
-class TestProjectLoading(TestCase):
+class TestProjectLoading(common.TestCase):
 
     def setUp(self):
         self.mainloop = GLib.MainLoop()
@@ -374,11 +377,10 @@ class TestProjectLoading(TestCase):
         def quit(mainloop):
             mainloop.quit()
 
-        # Create a blank project and save it.
+        # Create a blank project and add an asset.
         project = _createRealProject()
         result = [False, False, False]
-        uris = ["file://%s/samples/tears_of_steel.webm" %
-                os.path.dirname(os.path.abspath(__file__))]
+        uris = [self.getSampleUri("tears_of_steel.webm")]
         project.connect("loaded", loaded, self.mainloop, result, uris)
         project.connect("done-importing", added, self.mainloop, result, uris)
 
@@ -392,7 +394,13 @@ class TestProjectLoading(TestCase):
         self.assertTrue(result[2], "Asset re-adding failed")
 
 
-class TestProjectChanging(TestCase):
+class TestProjectSettings(common.TestCase):
+
+    def setUp(self):
+        self.mainloop = GLib.MainLoop()
+
+    def tearDown(self):
+        pass
 
     def testAudio(self):
         project = _createRealProject(name="noname")
@@ -412,6 +420,52 @@ class TestProjectChanging(TestCase):
         project.videopar = Gst.Fraction(2, 7)
         self.assertEqual(Gst.Fraction(2, 7), project.videopar)
 
+    def testInitialization(self):
+        def loaded(project, timeline, mainloop, uris):
+            project.addUris(uris)
+
+        def added(project, mainloop):
+            mainloop.quit()
+
+        def quit(mainloop):
+            mainloop.quit()
+
+        # Create a blank project and add some assets.
+        project = _createRealProject()
+        self.assertTrue(project._has_default_video_settings)
+        self.assertTrue(project._has_default_audio_settings)
+
+        uris = [self.getSampleUri("flat_colour1_640x480.png"),
+                self.getSampleUri("tears_of_steel.webm"),
+                self.getSampleUri("1sec_simpsons_trailer.mp4")]
+        project.connect("loaded", loaded, self.mainloop, uris)
+        project.connect("done-importing", added, self.mainloop)
+
+        self.assertTrue(project.createTimeline())
+        GLib.timeout_add_seconds(5, quit, self.mainloop)
+        self.mainloop.run()
+
+        assets = project.list_assets(GES.UriClip)
+        self.assertEqual(3, len(assets), assets)
+
+        self.assertFalse(project._has_default_video_settings)
+        self.assertFalse(project._has_default_audio_settings)
+
+        # The audio settings should match tears_of_steel.webm
+        self.assertEqual(1, project.audiochannels)
+        self.assertEqual(44100, project.audiorate)
+
+        # The video settings should match tears_of_steel.webm
+        self.assertEqual(960, project.videowidth)
+        self.assertEqual(400, project.videoheight)
+        self.assertEqual(Gst.Fraction(25, 1), project.videorate)
+        self.assertEqual(Gst.Fraction(1, 1), project.videopar)
+
+    def testLoad(self):
+        project = Project(uri="fake.xges", app=None)
+        self.assertFalse(project._has_default_video_settings)
+        self.assertFalse(project._has_default_audio_settings)
+
 
 class TestExportSettings(TestCase):
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]