[pitivi] Notify and play a sound when rendering is complete



commit bcf90cf446734e00e70b6c799d35dfc871f21b68
Author: Elad Alfassa <elad fedoraproject org>
Date:   Fri Nov 9 13:36:30 2012 -0500

    Notify and play a sound when rendering is complete
    
    Also reuse the render progress dialog at the end of rendering
    to allow the user to open the rendered movie in their default movie player.
    
    Fixes bug #650812
    
    Adds (soft) dependencies: libnotify with introspection support, pycanberra

 README                       |    6 +++-
 data/ui/renderingprogress.ui |   40 ++++++++++++++++++++++++++++++++----
 pitivi/render.py             |   45 +++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 83 insertions(+), 8 deletions(-)
---
diff --git a/README b/README
index 5cc3068..5437052 100644
--- a/README
+++ b/README
@@ -1,3 +1,5 @@
-In order to get more video effects, you should install the frei0r library
+In order to get more video effects, you should install the frei0r library.
+Other "soft" dependencies include:
+- pycanberra and libnotify for sounds and notifications when rendering completes
 
-Packagers should add it as a recommended package.
+Packagers should add them as recommended packages.
diff --git a/data/ui/renderingprogress.ui b/data/ui/renderingprogress.ui
index 9ce9019..f525a8e 100644
--- a/data/ui/renderingprogress.ui
+++ b/data/ui/renderingprogress.ui
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
-  <requires lib="gtk+" version="3.4"/>
+  <!-- interface-requires gtk+ 3.4 -->
   <object class="GtkDialog" id="render-progress">
     <property name="can_focus">False</property>
     <property name="border_width">12</property>
@@ -26,7 +26,6 @@
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
-                <property name="use_action_appearance">False</property>
                 <property name="use_stock">True</property>
                 <signal name="toggled" handler="_pauseButtonClickedCb" swapped="no"/>
               </object>
@@ -37,12 +36,11 @@
               </packing>
             </child>
             <child>
-              <object class="GtkButton" id="button5">
+              <object class="GtkButton" id="cancel_button">
                 <property name="label">gtk-cancel</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
-                <property name="use_action_appearance">False</property>
                 <property name="use_stock">True</property>
                 <signal name="clicked" handler="_cancelButtonClickedCb" swapped="no"/>
               </object>
@@ -52,6 +50,36 @@
                 <property name="position">1</property>
               </packing>
             </child>
+            <child>
+              <object class="GtkButton" id="play_rendered_file_button">
+                <property name="label">gtk-media-play</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+                <signal name="clicked" handler="_playRenderedFileButtonClickedCb" swapped="no"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="close_button">
+                <property name="label">gtk-close</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+                <signal name="clicked" handler="_closeButtonClickedCb" swapped="no"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">3</property>
+              </packing>
+            </child>
           </object>
           <packing>
             <property name="expand">False</property>
@@ -197,7 +225,9 @@
     </child>
     <action-widgets>
       <action-widget response="0">play_pause_button</action-widget>
-      <action-widget response="0">button5</action-widget>
+      <action-widget response="0">cancel_button</action-widget>
+      <action-widget response="0">play_rendered_file_button</action-widget>
+      <action-widget response="0">close_button</action-widget>
     </action-widgets>
   </object>
 </interface>
diff --git a/pitivi/render.py b/pitivi/render.py
index 033cb64..b2456ff 100644
--- a/pitivi/render.py
+++ b/pitivi/render.py
@@ -44,6 +44,17 @@ from pitivi.utils.widgets import GstElementSettingsDialog
 from pitivi.utils.ripple_update_group import RippleUpdateGroup
 from pitivi.utils.ui import model, frame_rates, audio_rates, audio_depths, \
     audio_channels, get_combo_value, set_combo_value, beautify_ETA
+try:
+    import pycanberra
+    has_canberra = True
+except ImportError:
+    has_canberra = False
+
+try:
+    from gi.repository import Notify
+    has_libnotify = True
+except ImportError:
+    has_libnotify = False
 
 
 #---------------- Private utils ---------------------------------------#
@@ -329,6 +340,7 @@ class RenderingProgressDialog(Signallable):
 
     def __init__(self, app, parent):
         self.app = app
+        self.main_render_dialog = parent
         self.builder = Gtk.Builder()
         self.builder.add_from_file(os.path.join(configure.get_ui_dir(),
             "renderingprogress.ui"))
@@ -338,6 +350,9 @@ class RenderingProgressDialog(Signallable):
         self.table1 = self.builder.get_object("table1")
         self.progressbar = self.builder.get_object("progressbar")
         self.play_pause_button = self.builder.get_object("play_pause_button")
+        self.play_rendered_file_button = self.builder.get_object("play_rendered_file_button")
+        self.close_button = self.builder.get_object("close_button")
+        self.cancel_button = self.builder.get_object("cancel_button")
         # Parent the dialog with mainwindow, since renderingdialog is hidden.
         # It allows this dialog to properly minimize together with mainwindow
         self.window.set_transient_for(self.app.gui)
@@ -348,6 +363,10 @@ class RenderingProgressDialog(Signallable):
         # TODO: show this widget for rendering statistics (bug 637079)
         self.table1.hide()
 
+        # We will only show the close/play buttons when the render is done:
+        self.play_rendered_file_button.hide()
+        self.close_button.hide()
+
     def updatePosition(self, fraction, estimated):
         self.progressbar.set_fraction(fraction)
         self.window.set_title(_("%d%% Rendered") % int(100 * fraction))
@@ -368,6 +387,15 @@ class RenderingProgressDialog(Signallable):
     def _pauseButtonClickedCb(self, unused_button):
         self.emit("pause")
 
+    def _closeButtonClickedCb(self, unused_button):
+        self.window.destroy()
+        if self.main_render_dialog.notification is not None:
+            self.main_render_dialog.notification.close()
+        self.main_render_dialog.window.show()
+
+    def _playRenderedFileButtonClickedCb(self, unused_button):
+        os.system('xdg-open "%s"' % self.main_render_dialog.outfile)
+
 
 class RenderDialog(Loggable):
     """Render dialog box.
@@ -396,6 +424,7 @@ class RenderDialog(Loggable):
             self._pipeline = self.project.pipeline
 
         self.outfile = None
+        self.notification = None
         self.settings = project.getSettings()
         self.timestarted = 0
 
@@ -975,7 +1004,21 @@ class RenderDialog(Loggable):
         if message.type == Gst.MessageType.EOS:  # Render complete
             self.debug("got EOS message, render complete")
             self._shutDown()
-            self._destroyProgressWindow()
+            self.progress.progressbar.set_text(_("Render complete"))
+            self.progress.window.set_title(_("Render complete"))
+            if has_libnotify:
+                Notify.init("pitivi")
+                if not self.progress.window.is_active():
+                    self.notification = Notify.Notification.new(_("Render complete"), _("<i>%s</i> has finished rendering." % self.fileentry.get_text()), "pitivi")
+                    self.notification.show()
+            if has_canberra:
+                canberra = pycanberra.Canberra()
+                canberra.play(1, pycanberra.CA_PROP_EVENT_ID, "complete-media", None)
+            self.progress.play_rendered_file_button.show()
+            self.progress.close_button.show()
+            self.progress.cancel_button.hide()
+            self.progress.play_pause_button.hide()
+
         elif message.type == Gst.MessageType.STATE_CHANGED and self.progress:
             prev, state, pending = message.parse_state_changed()
             if message.src == self._pipeline:



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