Example #1
0
 def _newProjectLoaded(self, project):
     if self.render_output:
         # create renderer and set output file
         self.actioner = Renderer(self.current, pipeline=None, outfile=self.output_file)
     elif self.preview:
         # create previewer and set ui
         self.actioner = Previewer(self.current, pipeline=None, ui=self.gui)
         # hack to make the gtk.HScale seek slider UI behave properly
         self.gui._durationChangedCb(None, project.timeline.duration)
     if self.actioner:
         self.actioner.connect("eos", self._eosCb)
         # on error, all we need to do is shutdown which is the same as we do for EOS
         self.actioner.connect("error", self._eosCb)
         # configure the actioner and start acting!
         self.actioner.startAction()
Example #2
0
class InteractivePitivi(Pitivi):
    usage = _("""
      %prog [-r OUTPUT_FILE] [PROJECT_FILE]
      %prog -p [PROJECT_FILE]
      %prog -i [-a] [MEDIA_FILE]...""")

    description = _("""Starts the video editor, optionally loading PROJECT_FILE. If
no project is given, %prog creates a new project.
Alternatively, when -i is specified, arguments are treated as clips to be
imported into the project. If -a is specified, these clips will also be added to
the end of the project timeline.
When -r is specified, the given project file is rendered without opening the GUI.""")

    import_help = _("""Import each MEDIA_FILE into the project.""")

    add_help = _("""Add each MEDIA_FILE to timeline after importing.""")
    debug_help = _("""Run pitivi in the Python Debugger""")

    no_ui_help = _("""Run pitivi with no gui""")
    render_help = _("""Render the given project file to OUTPUT_FILE with no GUI.""")
    preview_help = _("""Preview the given project file without the full UI.""")

    def __init__(self):
        Pitivi.__init__(self)
        self.mainloop = gobject.MainLoop()
        self.actioner = None

    def _newProjectLoaded(self, project):
        if self.render_output:
            # create renderer and set output file
            self.actioner = Renderer(self.current, pipeline=None, outfile=self.output_file)
        elif self.preview:
            # create previewer and set ui
            self.actioner = Previewer(self.current, pipeline=None, ui=self.gui)
            # hack to make the gtk.HScale seek slider UI behave properly
            self.gui._durationChangedCb(None, project.timeline.duration)
        if self.actioner:
            self.actioner.connect("eos", self._eosCb)
            # on error, all we need to do is shutdown which is the same as we do for EOS
            self.actioner.connect("error", self._eosCb)
            # configure the actioner and start acting!
            self.actioner.startAction()

    def run(self, argv):
        # check for dependencies
        if not self._checkDependencies():
            return

        # parse cmdline options
        parser = self._createOptionParser()
        options, args = parser.parse_args(argv)

        # if we aren't importing sources then n_args should be at most
        # 1 + parameters that take individual arguments
        n_args = 1

        if options.debug:
            sys.excepthook = self._excepthook

        # validate options
        self.render_output = options.render_output
        self.preview = options.preview
        if options.render_output:
            options.no_ui = True
            n_args += 1

        if options.render_output and options.preview:
            parser.error("-p and -r cannot be used simultaneously")
            return

        if options.import_sources and (options.render_output or options.preview):
            parser.error("-r or -p and -i are incompatible")
            return

        if not options.import_sources and options.add_to_timeline:
            parser.error("-a requires -i")
            return

        if not options.import_sources and ((options.render_output and len(args) != 2)
                    or len(args) > n_args):
            parser.error("invalid arguments")
            return

        if options.no_ui:
            self.gui = None
        elif options.preview:
            # init ui for previewing
            self.gui = PitiviViewer()
            self.window = gtk.Window()
            self.window.connect("delete-event", self._deleteCb)
            self.window.add(self.gui)
            self.window.show_all()
        else:
            # create the ui
            self.gui = PitiviMainWindow(self)
            self.gui.show()

        if not options.import_sources and args:
            index = 0
            if options.render_output:
                self.output_file = "file://%s" % os.path.abspath(args[index])
                index += 1
            # load a project file
            project = "file://%s" % os.path.abspath(args[index])
            self.projectManager.loadProject(project)
        else:
            # load the passed filenames, optionally adding them to the timeline
            # (useful during development)
            self.projectManager.newBlankProject()
            uris = ["file://" + urllib.quote(os.path.abspath(path)) for path in args]
            self.current.sources.connect("source-added",
                    self._sourceAddedCb, uris, options.add_to_timeline)
            self.current.sources.connect("discovery-error",
                    self._discoveryErrorCb, uris)
            self.current.sources.addUris(uris)

        # run the mainloop
        self.mainloop.run()

    def _deleteCb(self, unused_widget, unused_data):
        self.shutdown()

    def _eosCb(self, unused_obj):
        if self.gui is None:
            self.shutdown()
        elif self.window is not None:
            self.gui.seek(0)

    def shutdown(self):
        if Pitivi.shutdown(self):
            if self.gui:
                self.gui.destroy()
            self.mainloop.quit()
            return True

        return False

    def _createOptionParser(self):
        parser = OptionParser(self.usage, description=self.description)
        parser.add_option("-i", "--import", help=self.import_help,
                dest="import_sources", action="store_true", default=False)
        parser.add_option("-a", "--add-to-timeline", help=self.add_help,
                action="store_true", default=False)
        parser.add_option("-d", "--debug", help=self.debug_help,
                action="store_true", default=False)
        parser.add_option("-n", "--no-ui", help=self.no_ui_help,
                action="store_true", default=False)
        parser.add_option("-r", "--render", help=self.render_help,
                dest="render_output", action="store_true", default=False)
        parser.add_option("-p", "--preview", help=self.preview_help,
                action="store_true", default=False)

        return parser


    def _checkDependencies(self):
        missing_deps = initial_checks()
        if missing_deps:
            message, detail = missing_deps
            dialog = gtk.MessageDialog(type=gtk.MESSAGE_ERROR,
                                       buttons=gtk.BUTTONS_OK)
            dialog.set_icon_name("pitivi")
            dialog.set_markup("<b>"+message+"</b>")
            dialog.format_secondary_text(detail)
            dialog.run()

            return False

        return True

    def _sourceAddedCb(self, sourcelist, factory,
            startup_uris, add_to_timeline):
        if self._maybePopStartupUri(startup_uris, factory.uri) \
                and add_to_timeline:
            self.action_log.begin("add clip")
            self.current.timeline.addSourceFactory(factory)
            self.action_log.commit()

    def _discoveryErrorCb(self, sourcelist, uri, error, debug, startup_uris):
        self._maybePopStartupUri(startup_uris, uri)

    def _maybePopStartupUri(self, startup_uris, uri):
        try:
            startup_uris.remove(uri)
        except ValueError:
            # uri is not a startup uri. This can happen if the user starts
            # importing sources while sources specified at startup are still
            # being processed. In practice this will never happen.
            return False

        if not startup_uris:
            self.current.sources.disconnect_by_function(self._sourceAddedCb)
            self.current.sources.disconnect_by_function(self._discoveryErrorCb)

        return True

    def _excepthook(self, exc_type, value, tback):
        import traceback
        import pdb
        traceback.print_tb(tback)
        pdb.post_mortem(tback)