Example #1
0
    def actionThumbnailView_trigger(self, event):
        log.info("Switch to Thumbnail View")

        # Get settings
        app = get_app()
        s = settings.get_settings()

        # Files
        if app.context_menu_object == "files":
            s.set("file_view", "thumbnail")
            self.tabFiles.layout().removeWidget(self.filesTreeView)
            self.filesTreeView.deleteLater()
            self.filesTreeView = None
            self.filesTreeView = FilesListView(self)
            self.tabFiles.layout().addWidget(self.filesTreeView)

        # Transitions
        elif app.context_menu_object == "transitions":
            s.set("transitions_view", "thumbnail")
            self.tabTransitions.layout().removeWidget(self.transitionsTreeView)
            self.transitionsTreeView.deleteLater()
            self.transitionsTreeView = None
            self.transitionsTreeView = TransitionsListView(self)
            self.tabTransitions.layout().addWidget(self.transitionsTreeView)

        # Effects
        elif app.context_menu_object == "effects":
            s.set("effects_view", "thumbnail")
            self.tabEffects.layout().removeWidget(self.effectsTreeView)
            self.effectsTreeView.deleteLater()
            self.effectsTreeView = None
            self.effectsTreeView = EffectsListView(self)
            self.tabEffects.layout().addWidget(self.effectsTreeView)
Example #2
0
    def __init__(self, window):
        self.app = get_app()
        self.window = window
        project = self.app.project
        s = settings.get_settings()

        # Get some settings from the project
        fps = project.get(["fps"])
        width = project.get(["width"])
        height = project.get(["height"])
        sample_rate = project.get(["sample_rate"])
        channels = project.get(["channels"])
        channel_layout = project.get(["channel_layout"])

        # Create an instance of a libopenshot Timeline object
        self.timeline = openshot.Timeline(width, height, openshot.Fraction(fps["num"], fps["den"]), sample_rate, channels,
                                          channel_layout)
        self.timeline.info.channel_layout = channel_layout
        self.timeline.info.has_audio = True
        self.timeline.info.has_video = True
        self.timeline.info.video_length = 99999
        self.timeline.info.duration = 999.99
        self.timeline.info.sample_rate = sample_rate
        self.timeline.info.channels = channels

        # Open the timeline reader
        self.timeline.Open()

        # Add self as listener to project data updates (at the beginning of the list)
        # This listener will receive events before others.
        self.app.updates.add_listener(self, 0)

        # Connect to signal
        self.window.MaxSizeChanged.connect(self.MaxSizeChangedCB)
Example #3
0
    def __init__(self, win):
        """ Constructor """
        self.tutorials = []
        self.win = win
        self.current_dialog = None

        # get translations
        app = get_app()
        _ = app._tr

        # get settings
        s = get_settings()
        self.tutorial_enabled = s.get("tutorial_enabled")
        self.tutorial_ids = s.get("tutorial_ids").split(",")

        # Add all possible tutorials
        self.tutorial_objects = [    {"id":"1", "x":20, "y":0, "object_id":"filesTreeView", "text":_("<b>Project Files:</b> Get started with your project by adding video, audio, and image files here. Drag and drop files from your file system.")},
                                     {"id":"2", "x":200, "y":-15, "object_id":"timeline", "text":_("<b>Timeline:</b> Arrange your clips on the timeline here. Overlap clips to create automatic transitions. Access lots of fun presets and options by right-clicking on clips.")},
                                     {"id":"3", "x":150, "y":100, "object_id":"dockVideoContents", "text":_("<b>Video Preview:</b> Watch your timeline video preview here. Use the buttons (play, rewind, fast-forward) to control the video playback.")},
                                     {"id":"4", "x":20, "y":-35, "object_id":"propertyTableView", "text":_("<b>Properties:</b> View and change advanced properties of clips and effects here. Right-clicking on clips is usually faster than manually changing properties.")},
                                     {"id":"5", "x":20, "y":10, "object_id":"transitionsTreeView", "text":_("<b>Transitions:</b> Create a gradual fade from one clip to another. Drag and drop a transition onto the timeline and position it on top of a clip (usually at the beginning or ending).")},
                                     {"id":"6", "x":20, "y":20, "object_id":"effectsTreeView", "text":_("<b>Effects:</b> Adjust brigthness, contrast, saturation, and add exciting special effects. Drag and drop an effect onto the timeline and position it on top of a clip (or track)")},
                                     {"id":"7", "x":-265, "y":-22, "object_id":"export_button", "text":_("<b>Export Video:</b> When you are ready to create your finished video, click this button to export your timeline as a single video file.")}
                                ]

        # Connect to dock widgets
        self.win.dockFiles.visibilityChanged.connect(functools.partial(self.process, "dockFiles"))
        self.win.dockTransitions.visibilityChanged.connect(functools.partial(self.process, "dockTransitions"))
        self.win.dockEffects.visibilityChanged.connect(functools.partial(self.process, "dockEffects"))
        self.win.dockProperties.visibilityChanged.connect(functools.partial(self.process, "dockProperties"))
        self.win.dockVideo.visibilityChanged.connect(functools.partial(self.process, "dockVideo"))

        # Process tutorials (1 by 1)
        if self.tutorial_enabled:
            self.process()
Example #4
0
    def btnAdvanced_clicked(self):
        _ = self.app._tr
        # use an external editor to edit the image
        try:
            # Get settings
            s = settings.get_settings()

            # get the title editor executable path
            prog = s.get("title_editor")

            # launch advanced title editor
            # debug info
            log.info("Advanced title editor command: {} {} ".format(prog, self.filename))

            p = subprocess.Popen([prog, self.filename])

            # wait for process to finish (so we can update the preview)
            p.communicate()

            # update image preview
            self.load_svg_template()
            self.display_svg()

        except OSError:
            msg = QMessageBox()
            msg.setText(_("Please install {} to use this function").format(prog.capitalize()))
            msg.exec_()
Example #5
0
    def btnAdvanced_clicked(self):
        _ = self.app._tr
        # use an external editor to edit the image
        try:
            # Get settings
            s = settings.get_settings()

            # get the title editor executable path
            prog = s.get("title_editor")

            # launch advanced title editor
            # debug info
            log.info("Advanced title editor command: {} {} ".format(prog, self.filename))

            p = subprocess.Popen([prog, self.filename])

            # wait for process to finish (so we can update the preview)
            p.communicate()

            # update image preview
            self.load_svg_template()
            self.display_svg()

        except OSError:
            msg = QMessageBox()
            msg.setText(_("Please install {} to use this function").format(prog.capitalize()))
            msg.exec_()
Example #6
0
    def __init__(self, window):
        self.app = get_app()
        self.window = window
        project = self.app.project
        s = settings.get_settings()

        # Get some settings from the project
        fps = project.get(["fps"])
        width = project.get(["width"])
        height = project.get(["height"])
        sample_rate = project.get(["sample_rate"])
        channels = project.get(["channels"])
        channel_layout = project.get(["channel_layout"])

        # Create an instance of a libopenshot Timeline object
        self.timeline = openshot.Timeline(
            width, height, openshot.Fraction(fps["num"], fps["den"]),
            sample_rate, channels, channel_layout)
        self.timeline.info.channel_layout = channel_layout
        self.timeline.info.has_audio = True
        self.timeline.info.has_video = True
        self.timeline.info.video_length = 99999
        self.timeline.info.duration = 999.99
        self.timeline.info.sample_rate = sample_rate
        self.timeline.info.channels = channels

        # Open the timeline reader
        self.timeline.Open()

        # Add self as listener to project data updates (at the beginning of the list)
        # This listener will receive events before others.
        self.app.updates.add_listener(self, 0)
Example #7
0
    def add_to_recent_files(self, file_path):
        """ Add this project to the recent files list """
        if not file_path or "backup.osp" in file_path:
            # Ignore backup recovery project
            return

        s = settings.get_settings()
        recent_projects = s.get("recent_projects")

        # Make sure file_path is absolute
        file_path = os.path.abspath(file_path)

        # Remove existing project
        if file_path in recent_projects:
            recent_projects.remove(file_path)

        # Remove oldest item (if needed)
        if len(recent_projects) > 10:
            del recent_projects[0]

        # Append file path to end of recent files
        recent_projects.append(file_path)

        # Save setting
        s.set("recent_projects", recent_projects)
        s.save()
Example #8
0
    def __init__(self):

        # Create dialog class
        QDialog.__init__(self)

        # Load UI from designer
        ui_util.load_ui(self, self.ui_path)

        # Init UI
        ui_util.init_ui(self)

        # Get settings
        self.s = settings.get_settings()

        # Dynamically load tabs from settings data
        self.settings_data = settings.get_settings().get_all_settings()

        # Track metrics
        track_metric_screen("preferences-screen")

        # Load all user values
        self.params = {}
        for item in self.settings_data:
            if "setting" in item and "value" in item:
                self.params[item["setting"]] = item

        # Connect search textbox
        self.txtSearch.textChanged.connect(self.txtSearch_changed)

        self.requires_restart = False
        self.category_names = {}
        self.category_tabs = {}
        self.category_sort = {}
        self.visible_category_names = {}

        # Tested hardware modes (default cpu mode with graphics card 0)
        self.hardware_tests_cards = {
            0: [
                0,
            ]
        }

        # Populate preferences
        self.Populate()

        # Restore normal cursor
        get_app().restoreOverrideCursor()
Example #9
0
    def __init__(self):

        # Create dialog class
        QDialog.__init__(self)

        # Load UI from designer
        ui_util.load_ui(self, self.ui_path)

        # Init UI
        ui_util.init_ui(self)

        # get translations
        app = get_app()
        _ = app._tr

        # Get settings
        self.s = settings.get_settings()

        # Track metrics
        track_metric_screen("profile-screen")

        # Loop through profiles
        self.profile_names = []
        self.profile_paths = {}
        for profile_folder in [info.USER_PROFILES_PATH, info.PROFILES_PATH]:
            for file in os.listdir(profile_folder):
                # Load Profile
                profile_path = os.path.join(profile_folder, file)
                profile = openshot.Profile(profile_path)

                # Add description of Profile to list
                self.profile_names.append(profile.info.description)
                self.profile_paths[profile.info.description] = profile_path

        # Sort list
        self.profile_names.sort()

        # Loop through sorted profiles
        box_index = 0
        selected_index = 0
        for profile_name in self.profile_names:

            # Add to dropdown
            self.cboProfile.addItem(profile_name,
                                    self.profile_paths[profile_name])

            # Set default (if it matches the project)
            if app.project.get(['profile']) == profile_name:
                selected_index = box_index

            # increment item counter
            box_index += 1

        # Connect signal
        self.cboProfile.currentIndexChanged.connect(
            functools.partial(self.dropdown_index_changed, self.cboProfile))

        # Set current item (from project)
        self.cboProfile.setCurrentIndex(selected_index)
Example #10
0
    def new(self):
        """ Try to load default project settings file, will raise error on failure """
        import openshot
        self._data = self.read_from_file(self.default_project_filepath)
        self.current_filepath = None
        self.has_unsaved_changes = False

        # Get default profile
        s = settings.get_settings()
        default_profile = s.get("default-profile")

        # Loop through profiles
        for profile_folder in [info.USER_PROFILES_PATH, info.PROFILES_PATH]:
            for file in os.listdir(profile_folder):
                # Load Profile and append description
                profile_path = os.path.join(profile_folder, file)
                profile = openshot.Profile(profile_path)

                if default_profile == profile.info.description:
                    log.info("Setting default profile to %s" %
                             profile.info.description)

                    # Update default profile
                    self._data["profile"] = profile.info.description
                    self._data["width"] = profile.info.width
                    self._data["height"] = profile.info.height
                    self._data["fps"] = {
                        "num": profile.info.fps.num,
                        "den": profile.info.fps.den
                    }
                    break

        # Get the default audio settings for the timeline (and preview playback)
        default_sample_rate = int(s.get("default-samplerate"))
        default_channel_ayout = s.get("default-channellayout")

        channels = 2
        channel_layout = openshot.LAYOUT_STEREO
        if default_channel_ayout == "LAYOUT_MONO":
            channels = 1
            channel_layout = openshot.LAYOUT_MONO
        elif default_channel_ayout == "LAYOUT_STEREO":
            channels = 2
            channel_layout = openshot.LAYOUT_STEREO
        elif default_channel_ayout == "LAYOUT_SURROUND":
            channels = 3
            channel_layout = openshot.LAYOUT_SURROUND
        elif default_channel_ayout == "LAYOUT_5POINT1":
            channels = 6
            channel_layout = openshot.LAYOUT_5POINT1
        elif default_channel_ayout == "LAYOUT_7POINT1":
            channels = 8
            channel_layout = openshot.LAYOUT_7POINT1

        # Set default samplerate and channels
        self._data["sample_rate"] = default_sample_rate
        self._data["channels"] = channels
        self._data["channel_layout"] = channel_layout
Example #11
0
    def __init__(self):

        # Create dialog class
        QDialog.__init__(self)

        # Load UI from designer
        ui_util.load_ui(self, self.ui_path)

        # Init UI
        ui_util.init_ui(self)

        # get translations
        app = get_app()
        _ = app._tr

        # Get settings
        self.s = settings.get_settings()

        # Track metrics
        track_metric_screen("profile-screen")

        # Loop through profiles
        self.profile_names = []
        self.profile_paths = {}
        for profile_folder in [info.USER_PROFILES_PATH, info.PROFILES_PATH]:
            for file in os.listdir(profile_folder):
                # Load Profile
                profile_path = os.path.join(profile_folder, file)
                profile = openshot.Profile(profile_path)

                # Add description of Profile to list
                self.profile_names.append(profile.info.description)
                self.profile_paths[profile.info.description] = profile_path

        # Sort list
        self.profile_names.sort()

        # Loop through sorted profiles
        box_index = 0
        selected_index = 0
        for profile_name in self.profile_names:

            # Add to dropdown
            self.cboProfile.addItem(profile_name, self.profile_paths[profile_name])

            # Set default (if it matches the project)
            if app.project.get(['profile']) == profile_name:
                selected_index = box_index

            # increment item counter
            box_index += 1


        # Connect signal
        self.cboProfile.currentIndexChanged.connect(functools.partial(self.dropdown_index_changed, self.cboProfile))

        # Set current item (from project)
        self.cboProfile.setCurrentIndex(selected_index)
Example #12
0
    def load_settings(self):
        s = settings.get_settings()

        # Window state and geometry (also toolbar and dock locations)
        if s.get('window_geometry'): self.restoreGeometry(qt_types.str_to_bytes(s.get('window_geometry')))
        if s.get('window_state'): self.restoreState(qt_types.str_to_bytes(s.get('window_state')))

        # Load Recent Projects
        self.load_recent_menu()
Example #13
0
    def load_settings(self):
        s = settings.get_settings()

        # Window state and geometry (also toolbar and dock locations)
        if s.get('window_state_v2'):
            self.restoreState(qt_types.str_to_bytes(s.get('window_state_v2')))
        if s.get('window_geometry_v2'):
            self.restoreGeometry(
                qt_types.str_to_bytes(s.get('window_geometry_v2')))
    def inject_params(self, path, frame=None):
        # determine if this is 'preview' mode?
        is_preview = False
        if frame:
            # if a frame is passed in, we are in preview mode.
            # This is used to turn the background color to off-white... instead of transparent
            is_preview = True

        # prepare string to inject
        user_params = "\n#BEGIN INJECTING PARAMS\n"
        for k, v in self.params.items():
            if type(v) == int or type(v) == float or type(v) == list or type(v) == bool:
                user_params += "params['{}'] = {}\n".format(k, v)
            if type(v) == str:
                user_params += "params['{}'] = u'{}'\n".format(k, v.replace("'", r"\'"))

        for k, v in self.get_project_params(is_preview).items():
            if type(v) == int or type(v) == float or type(v) == list or type(v) == bool:
                user_params += "params['{}'] = {}\n".format(k, v)
            if type(v) == str:
                user_params += "params['{}'] = u'{}'\n".format(k, v.replace("'", r"\'").replace("\\", "\\\\"))
        user_params += "#END INJECTING PARAMS\n"

        # Force the Frame to 1 frame (for previewing)
        if frame:
            user_params += "\n#ONLY RENDER 1 FRAME FOR PREVIEW\n"
            user_params += "params['{}'] = {}\n".format("start_frame", frame)
            user_params += "params['{}'] = {}\n".format("end_frame", frame)
            user_params += "#END ONLY RENDER 1 FRAME FOR PREVIEW\n"

        # If GPU rendering is selected, see if GPU enable code is available
        s = settings.get_settings()
        gpu_code_body = None
        if s.get("blender_gpu_enabled"):
            gpu_enable_py = os.path.join(info.PATH, "blender", "scripts", "gpu_enable.py")
            try:
                f = open(gpu_enable_py, 'r')
                gpu_code_body = f.read()
            except IOError as e:
                log.error("Could not load GPU enable code! {}".format(e))

        if gpu_code_body:
            log.info("Injecting GPU enable code from {}".format(gpu_enable_py))
            user_params += "\n#ENABLE GPU RENDERING\n"
            user_params += gpu_code_body
            user_params += "\n#END ENABLE GPU RENDERING\n"

        # Open new temp .py file, and inject the user parameters
        with open(path, 'r') as f:
            script_body = f.read()

        # modify script variable
        script_body = script_body.replace("# INJECT_PARAMS_HERE", user_params)

        # Write update script
        with open(path, "w", encoding="UTF-8", errors="strict") as f:
            f.write(script_body)
Example #15
0
    def new(self):
        """ Try to load default project settings file, will raise error on failure """
        import openshot
        self._data = self.read_from_file(self.default_project_filepath)
        self.current_filepath = None
        self.has_unsaved_changes = False

        # Get default profile
        s = settings.get_settings()
        default_profile = s.get("default-profile")

        # Loop through profiles
        for profile_folder in [info.USER_PROFILES_PATH, info.PROFILES_PATH]:
            for file in os.listdir(profile_folder):
                # Load Profile and append description
                profile_path = os.path.join(profile_folder, file)
                profile = openshot.Profile(profile_path)

                if default_profile == profile.info.description:
                    log.info("Setting default profile to %s" % profile.info.description)

                    # Update default profile
                    self._data["profile"] = profile.info.description
                    self._data["width"] = profile.info.width
                    self._data["height"] = profile.info.height
                    self._data["fps"] = {"num" : profile.info.fps.num, "den" : profile.info.fps.den}
                    break

        # Get the default audio settings for the timeline (and preview playback)
        default_sample_rate = int(s.get("default-samplerate"))
        default_channel_ayout = s.get("default-channellayout")

        channels = 2
        channel_layout = openshot.LAYOUT_STEREO
        if default_channel_ayout == "LAYOUT_MONO":
            channels = 1
            channel_layout = openshot.LAYOUT_MONO
        elif default_channel_ayout == "LAYOUT_STEREO":
            channels = 2
            channel_layout = openshot.LAYOUT_STEREO
        elif default_channel_ayout == "LAYOUT_SURROUND":
            channels = 3
            channel_layout = openshot.LAYOUT_SURROUND
        elif default_channel_ayout == "LAYOUT_5POINT1":
            channels = 6
            channel_layout = openshot.LAYOUT_5POINT1
        elif default_channel_ayout == "LAYOUT_7POINT1":
            channels = 8
            channel_layout = openshot.LAYOUT_7POINT1

        # Set default samplerate and channels
        self._data["sample_rate"] = default_sample_rate
        self._data["channels"] = channels
        self._data["channel_layout"] = channel_layout
Example #16
0
    def checkbox_metrics_callback(self, state):
        """ Callback for error and anonymous usage checkbox"""
        s = get_settings()
        if state == Qt.Checked:
            # Enabling metrics sending
            s.set("send_metrics", True)

            # Opt-in for metrics tracking
            track_metric_screen("metrics-opt-in")
        else:
            # Opt-out for metrics tracking
            track_metric_screen("metrics-opt-out")

            # Disable metric sending
            s.set("send_metrics", False)
Example #17
0
def load_theme():
    """ Load the current OS theme, or fallback to a default one """

    s = settings.get_settings()

    # If theme not reported by OS
    if QIcon.themeName() == '' and not s.get("theme") == "No Theme":

        # Address known Ubuntu bug of not reporting configured theme name, use default ubuntu theme
        if os.getenv('DESKTOP_SESSION') == 'ubuntu':
            QIcon.setThemeName('unity-icon-theme')

        # Windows/Mac use packaged theme
        else:
            QIcon.setThemeName(DEFAULT_THEME_NAME)
Example #18
0
    def checkbox_metrics_callback(self, state):
        """ Callback for error and anonymous usage checkbox"""
        s = get_settings()
        if state == Qt.Checked:
            # Enabling metrics sending
            s.set("send_metrics", True)

            # Opt-in for metrics tracking
            track_metric_screen("metrics-opt-in")
        else:
            # Opt-out for metrics tracking
            track_metric_screen("metrics-opt-out")

            # Disable metric sending
            s.set("send_metrics", False)
    def run(self):
        # Running
        self.running = True

        # Get settings
        s = settings.get_settings()

        # Get port from settings
        port = s.get("debug-port")
        debug_enabled = s.get("debug-mode")

        # Set port on ZmqLogger singleton
        openshot.ZmqLogger.Instance().Connection("tcp://*:%s" % port)

        # Set filepath for ZmqLogger also
        openshot.ZmqLogger.Instance().Path(
            os.path.join(info.USER_PATH, 'libopenshot.log'))

        # Enable / Disable logger
        openshot.ZmqLogger.Instance().Enable(debug_enabled)

        # Socket to talk to server
        context = zmq.Context()
        socket = context.socket(zmq.SUB)
        socket.setsockopt_string(zmq.SUBSCRIBE, '')

        poller = zmq.Poller()
        poller.register(socket, zmq.POLLIN)

        log.info("Connecting to libopenshot with debug port: %s" % port)
        socket.connect("tcp://localhost:%s" % port)

        while self.running:
            msg = None

            # Receive all debug message sent from libopenshot (if any)
            socks = dict(poller.poll(1000))
            if socks:
                if socks.get(socket) == zmq.POLLIN:
                    msg = socket.recv(zmq.NOBLOCK)

            # Log the message (if any)
            if msg:
                log.info(msg.strip().decode('UTF-8'))
Example #20
0
    def __init__(self, win):
        """ Constructor """
        self.win = win
        self.dock = win.dockTutorial
        self.current_dialog = None

        # get translations
        app = get_app()
        _ = app._tr

        # get settings
        s = get_settings()
        self.tutorial_enabled = s.get("tutorial_enabled")
        self.tutorial_ids = s.get("tutorial_ids").split(",")

        # Add all possible tutorials
        self.tutorial_objects = [    {"id":"0", "x":400, "y":0, "object_id":"filesTreeView", "text":_("<b>Welcome!</b> Magic VideoX Pro is an award-winning, open-source video editing application! This tutorial will walk you through the basics.<br><br>Would you like to automatically send errors and metrics to help improve Magic VideoX Pro?"), "arrow":False},
                                     {"id":"1", "x":20, "y":0, "object_id":"filesTreeView", "text":_("<b>Project Files:</b> Get started with your project by adding video, audio, and image files here. Drag and drop files from your file system."), "arrow":True},
                                     {"id":"2", "x":200, "y":-15, "object_id":"timeline", "text":_("<b>Timeline:</b> Arrange your clips on the timeline here. Overlap clips to create automatic transitions. Access lots of fun presets and options by right-clicking on clips."), "arrow":True},
                                     {"id":"3", "x":200, "y":100, "object_id":"dockVideoContents", "text":_("<b>Video Preview:</b> Watch your timeline video preview here. Use the buttons (play, rewind, fast-forward) to control the video playback."), "arrow":True},
                                     {"id":"4", "x":20, "y":-35, "object_id":"propertyTableView", "text":_("<b>Properties:</b> View and change advanced properties of clips and effects here. Right-clicking on clips is usually faster than manually changing properties."), "arrow":True},
                                     {"id":"5", "x":20, "y":10, "object_id":"transitionsTreeView", "text":_("<b>Transitions:</b> Create a gradual fade from one clip to another. Drag and drop a transition onto the timeline and position it on top of a clip (usually at the beginning or ending)."), "arrow":True},
                                     {"id":"6", "x":20, "y":20, "object_id":"effectsTreeView", "text":_("<b>Effects:</b> Adjust brightness, contrast, saturation, and add exciting special effects. Drag and drop an effect onto the timeline and position it on top of a clip (or track)"), "arrow":True},
                                     {"id":"7", "x":-265, "y":-22, "object_id":"export_button", "text":_("<b>Export Video:</b> When you are ready to create your finished video, click this button to export your timeline as a single video file."), "arrow":True}
                                ]

        # Configure tutorial frame
        self.dock.setTitleBarWidget(QWidget()) # Prevents window decoration
        self.dock.setAttribute(Qt.WA_NoSystemBackground, True)
        self.dock.setAttribute(Qt.WA_TranslucentBackground, True)
        self.dock.setWindowFlags(Qt.FramelessWindowHint)
        self.dock.setFloating(True)


        # Connect to interface dock widgets
        self.win.dockFiles.visibilityChanged.connect(functools.partial(self.process, "dockFiles"))
        self.win.dockTransitions.visibilityChanged.connect(functools.partial(self.process, "dockTransitions"))
        self.win.dockEffects.visibilityChanged.connect(functools.partial(self.process, "dockEffects"))
        self.win.dockProperties.visibilityChanged.connect(functools.partial(self.process, "dockProperties"))
        self.win.dockVideo.visibilityChanged.connect(functools.partial(self.process, "dockVideo"))

        # Process tutorials (1 by 1)
        if self.tutorial_enabled:
            self.process()
Example #21
0
    def __init__(self, win):
        """ Constructor """
        self.win = win
        self.dock = win.dockTutorial
        self.current_dialog = None

        # get translations
        app = get_app()
        _ = app._tr

        # get settings
        s = get_settings()
        self.tutorial_enabled = s.get("tutorial_enabled")
        self.tutorial_ids = s.get("tutorial_ids").split(",")

        # Add all possible tutorials
        self.tutorial_objects = [    {"id":"0", "x":400, "y":0, "object_id":"filesTreeView", "text":_("<b>Welcome!</b> OpenShot Video Editor is an award-winning, open-source video editing application! This tutorial will walk you through the basics.<br><br>Would you like to automatically send errors and metrics to help improve OpenShot?"), "arrow":False},
                                     {"id":"1", "x":20, "y":0, "object_id":"filesTreeView", "text":_("<b>Project Files:</b> Get started with your project by adding video, audio, and image files here. Drag and drop files from your file system."), "arrow":True},
                                     {"id":"2", "x":200, "y":-15, "object_id":"timeline", "text":_("<b>Timeline:</b> Arrange your clips on the timeline here. Overlap clips to create automatic transitions. Access lots of fun presets and options by right-clicking on clips."), "arrow":True},
                                     {"id":"3", "x":200, "y":100, "object_id":"dockVideoContents", "text":_("<b>Video Preview:</b> Watch your timeline video preview here. Use the buttons (play, rewind, fast-forward) to control the video playback."), "arrow":True},
                                     {"id":"4", "x":20, "y":-35, "object_id":"propertyTableView", "text":_("<b>Properties:</b> View and change advanced properties of clips and effects here. Right-clicking on clips is usually faster than manually changing properties."), "arrow":True},
                                     {"id":"5", "x":20, "y":10, "object_id":"transitionsTreeView", "text":_("<b>Transitions:</b> Create a gradual fade from one clip to another. Drag and drop a transition onto the timeline and position it on top of a clip (usually at the beginning or ending)."), "arrow":True},
                                     {"id":"6", "x":20, "y":20, "object_id":"effectsTreeView", "text":_("<b>Effects:</b> Adjust brightness, contrast, saturation, and add exciting special effects. Drag and drop an effect onto the timeline and position it on top of a clip (or track)"), "arrow":True},
                                     {"id":"7", "x":-265, "y":-22, "object_id":"export_button", "text":_("<b>Export Video:</b> When you are ready to create your finished video, click this button to export your timeline as a single video file."), "arrow":True}
                                ]

        # Configure tutorial frame
        self.dock.setTitleBarWidget(QWidget()) # Prevents window decoration
        self.dock.setAttribute(Qt.WA_NoSystemBackground, True)
        self.dock.setAttribute(Qt.WA_TranslucentBackground, True)
        self.dock.setWindowFlags(Qt.FramelessWindowHint)
        self.dock.setFloating(True)


        # Connect to interface dock widgets
        self.win.dockFiles.visibilityChanged.connect(functools.partial(self.process, "dockFiles"))
        self.win.dockTransitions.visibilityChanged.connect(functools.partial(self.process, "dockTransitions"))
        self.win.dockEffects.visibilityChanged.connect(functools.partial(self.process, "dockEffects"))
        self.win.dockProperties.visibilityChanged.connect(functools.partial(self.process, "dockProperties"))
        self.win.dockVideo.visibilityChanged.connect(functools.partial(self.process, "dockVideo"))

        # Process tutorials (1 by 1)
        if self.tutorial_enabled:
            self.process()
Example #22
0
    def add_to_recent_files(self, file_path):
        """ Add this project to the recent files list """

        s = settings.get_settings()
        recent_projects = s.get("recent_projects")

        # Remove existing project
        if file_path in recent_projects:
            recent_projects.remove(file_path)

        # Remove oldest item (if needed)
        if len(recent_projects) > 10:
            del recent_projects[0]

        # Append file path to end of recent files
        recent_projects.append(file_path)

        # Save setting
        s.set("recent_projects", recent_projects)
Example #23
0
    def add_to_recent_files(self, file_path):
        """ Add this project to the recent files list """

        s = settings.get_settings()
        recent_projects = s.get("recent_projects")

        # Remove existing project
        if file_path in recent_projects:
            recent_projects.remove(file_path)

        # Remove oldest item (if needed)
        if len(recent_projects) > 10:
            del recent_projects[0]

        # Append file path to end of recent files
        recent_projects.append(file_path)

        # Save setting
        s.set("recent_projects", recent_projects)
    def __init__(self, window):
        QWebView.__init__(self)
        self.document_is_ready = False
        self.window = window
        self.setAcceptDrops(True)

        # Get settings
        self.settings_obj = settings.get_settings()

        # Add self as listener to project data updates (used to update the timeline)
        get_app().updates.add_listener(self)

        # set url from configuration (QUrl takes absolute paths for file system paths, create from QFileInfo)
        self.setUrl(
            QUrl.fromLocalFile(QFileInfo(self.html_path).absoluteFilePath()))

        # Connect signal of javascript initialization to our javascript reference init function
        self.page().mainFrame().javaScriptWindowObjectCleared.connect(
            self.setup_js_data)
    def run(self):
        # Running
        self.running = True

        # Get settings
        s = settings.get_settings()

        # Get port from settings
        port = s.get("debug-port")
        debug_enabled = s.get("debug-mode")

        # Set port on ZmqLogger singleton
        openshot.ZmqLogger.Instance().Connection("tcp://*:%s" % port)

        # Set filepath for ZmqLogger also
        openshot.ZmqLogger.Instance().Path(os.path.join(info.USER_PATH, 'libopenshot.log'))

        # Enable / Disable logger
        openshot.ZmqLogger.Instance().Enable(debug_enabled)

        # Socket to talk to server
        context = zmq.Context()
        socket = context.socket(zmq.SUB)
        socket.setsockopt_string(zmq.SUBSCRIBE, '')

        poller = zmq.Poller()
        poller.register(socket, zmq.POLLIN)

        log.info("Connecting to libopenshot with debug port: %s" % port)
        socket.connect ("tcp://localhost:%s" % port)

        while self.running:
            msg = None

            # Receive all debug message sent from libopenshot (if any)
            socks = dict(poller.poll(1000))
            if socks:
                if socks.get(socket) == zmq.POLLIN:
                    msg = socket.recv(zmq.NOBLOCK)

            # Log the message (if any)
            if msg:
                log.info(msg.strip().decode('UTF-8'))
Example #26
0
    def new(self):
        """ Try to load default project settings file, will raise error on failure """
        import openshot
        self._data = self.read_from_file(self.default_project_filepath)
        self.current_filepath = None
        self.has_unsaved_changes = False

        # Get default profile
        s = settings.get_settings()
        default_profile = s.get("default-profile")

        # Loop through profiles
        for file in os.listdir(info.PROFILES_PATH):
            # Load Profile and append description
            profile_path = os.path.join(info.PROFILES_PATH, file)
            profile = openshot.Profile(profile_path)

            if default_profile == profile.info.description:
                log.info("Setting default profile to %s" % profile.info.description)

                # Update default profile
                self._data["profile"] = profile.info.description
                self._data["width"] = profile.info.width
                self._data["height"] = profile.info.height
                self._data["fps"] = {"num" : profile.info.fps.num, "den" : profile.info.fps.den}

        # Clear any previous thumbnails
        try:
            if os.path.exists(info.THUMBNAIL_PATH):
                # Remove thumbnail folder
                shutil.rmtree(info.THUMBNAIL_PATH)
                # Create thumbnail folder
                os.mkdir(info.THUMBNAIL_PATH)

            # Clear any blender animations
            if os.path.exists(info.BLENDER_PATH):
                # Remove blender folder
                shutil.rmtree(info.BLENDER_PATH)
                # Create blender folder
                os.mkdir(info.BLENDER_PATH)
        except:
            pass
Example #27
0
    def hide_tips(self, tid, user_clicked=False):
        """ Hide the current tip, and don't show anymore """
        s = get_settings()

        # Loop through and find current tid
        for tutorial_object in self.tutorial_objects:
            # Get details
            tutorial_id = tutorial_object["id"]
            if tutorial_id == tid:
                # Hide dialog
                self.close_dialogs()
                # Update settings that this tutorial is completed
                if tid not in self.tutorial_ids:
                    self.tutorial_ids.append(str(tid))
                    s.set("tutorial_ids", ",".join(self.tutorial_ids))

        # Mark tutorial as completed (if settings)
        if user_clicked:
            # Disable all tutorials
            self.tutorial_enabled = False
            s.set("tutorial_enabled", False)
Example #28
0
    def hide_tips(self, tid, user_clicked=False):
        """ Hide the current tip, and don't show anymore """
        s = get_settings()

        # Loop through and find current tid
        for tutorial_object in self.tutorial_objects:
            # Get details
            tutorial_id = tutorial_object["id"]
            if tutorial_id == tid:
                # Hide dialog
                self.close_dialogs()
                # Update settings that this tutorial is completed
                if tid not in self.tutorial_ids:
                    self.tutorial_ids.append(str(tid))
                    s.set("tutorial_ids", ",".join(self.tutorial_ids))

        # Mark tutorial as completed (if settings)
        if user_clicked:
            # Disable all tutorials
            self.tutorial_enabled = False
            s.set("tutorial_enabled", False)
Example #29
0
	def error_with_blender(self, version=None, command_output=None):
		""" Show a friendly error message regarding the blender executable or version. """
		_ = self.app._tr
		s = settings.get_settings()
		
		version_message = ""
		if version:
			version_message = _("\n\nVersion Detected:\n{}").format(version)
			
		if command_output:
			version_message = _("\n\nError Output:\n{}").format(command_output)
		
		# show error message
		blender_version = "2.62"
		# Handle exception
		msg = QMessageBox()
		msg.setText(_("Blender, the free open source 3D content creation suite is required for this action (http://www.blender.org).\n\nPlease check the preferences in OpenShot and be sure the Blender executable is correct.  This setting should be the path of the 'blender' executable on your computer.  Also, please be sure that it is pointing to Blender version {} or greater.\n\nBlender Path:\n{}{}").format(blender_version, s.get("blender_command"), version_message))
		msg.exec_()

		# Enable the Render button again
		self.enable_interface()
Example #30
0
    def load_recent_menu(self):
        """ Clear and load the list of recent menu items """
        s = settings.get_settings()
        _ = get_app()._tr  # Get translation function

        # Get list of recent projects
        recent_projects = s.get("recent_projects")

        # Add Recent Projects menu (after Open File)
        import functools
        if not self.recent_menu:
            # Create a new recent menu
            self.recent_menu = self.menuFile.addMenu(QIcon.fromTheme("document-open-recent"), _("Recent Projects"))
            self.menuFile.insertMenu(self.actionRecent_Placeholder, self.recent_menu)
        else:
            # Clear the existing children
            self.recent_menu.clear()

        # Add recent projects to menu
        for file_path in reversed(recent_projects):
            new_action = self.recent_menu.addAction(file_path)
            new_action.triggered.connect(functools.partial(self.recent_project_clicked, file_path))
    def error_with_blender(self, version=None, command_output=None):
        """ Show a friendly error message regarding the blender executable or version. """
        _ = self.app._tr
        s = settings.get_settings()

        version_message = ""
        if version:
            version_message = _("\n\nVersion Detected:\n{}").format(version)
            log.error("Blender version detected: {}".format(version))

        if command_output:
            version_message = _("\n\nError Output:\n{}").format(command_output)
            log.error("Blender error output:\n{}".format(command_output))

        msg = QMessageBox()
        msg.setText(_(
            "Blender, the free open source 3D content creation suite is required for this action (http://www.blender.org).\n\nPlease check the preferences in OpenShot and be sure the Blender executable is correct.  This setting should be the path of the 'blender' executable on your computer.  Also, please be sure that it is pointing to Blender version {} or greater.\n\nBlender Path:\n{}{}").format(
            info.BLENDER_MIN_VERSION, s.get("blender_command"), version_message))
        msg.exec_()

        # Enable the Render button again
        self.enable_interface()
Example #32
0
    def accept(self):
        """ Start exporting video, but don't close window """
        # Get settings
        self.s = settings.get_settings()

        # Disable controls
        self.txtFileName.setEnabled(False)
        self.txtExportFolder.setEnabled(False)
        self.tabWidget.setEnabled(False)
        self.export_button.setEnabled(False)
        self.exporting = True

        # Test Succeeded
        # Determine final exported file path
        file_name_with_ext = "%s.%s" % (self.txtFileName.text().strip(), self.txtVideoFormat.text().strip())
        export_file_path = os.path.join(self.txtExportFolder.text().strip(), file_name_with_ext)
        log.info(export_file_path)

        # Translate object
        _ = get_app()._tr

        # Handle exception
        if os.path.exists(export_file_path):
            # File already exists! Prompt user
            ret = QMessageBox.question(self, _("Export Video"), _("%s already exists.\nDo you want to replace it?") % file_name_with_ext,
                                       QMessageBox.No | QMessageBox.Yes)
            if ret == QMessageBox.No:
                # Stop and don't do anything
                # Re-enable controls
                self.txtFileName.setEnabled(True)
                self.txtExportFolder.setEnabled(True)
                self.tabWidget.setEnabled(True)
                self.export_button.setEnabled(True)
                self.exporting = False
                return

        # Create FFmpegWriter
        try:
            w = openshot.FFmpegWriter(export_file_path)

            # Set video options
            w.SetVideoOptions(True,
                              self.txtVideoCodec.text(),
                              openshot.Fraction(self.txtFrameRateNum.value(),
                                                self.txtFrameRateDen.value()),
                              self.txtWidth.value(),
                              self.txtHeight.value(),
                              openshot.Fraction(self.txtPixelRatioNum.value(),
                                                self.txtPixelRatioDen.value()),
                              False,
                              False,
                              int(self.convert_to_bytes(self.txtVideoBitRate.text())))

            # Set audio options
            w.SetAudioOptions(True,
                              self.txtAudioCodec.text(),
                              self.txtSampleRate.value(),
                              self.txtChannels.value(),
                              self.cboChannelLayout.currentData(),
                              int(self.convert_to_bytes(self.txtAudioBitrate.text())))

            # Open the writer
            w.Open()

            # Init progress bar
            self.progressExportVideo.setMinimum(self.txtStartFrame.value())
            self.progressExportVideo.setMaximum(self.txtEndFrame.value())

            # Write each frame in the selected range
            for frame in range(self.txtStartFrame.value(), self.txtEndFrame.value() + 1):
                # Update progress bar
                self.progressExportVideo.setValue(frame)
                # Process events (to show the progress bar moving)
                QCoreApplication.processEvents()

                # Write the frame object to the video
                w.WriteFrame(get_app().window.timeline_sync.timeline.GetFrame(frame))

                # Check if we need to bail out
                if not self.exporting:
                    break

            # Close writer
            w.Close()


        except Exception as e:
            # TODO: Find a better way to catch the error. This is the only way I have found that
            # does not throw an error
            error_type_str = str(e)
            log.info("Error type string: %s" % error_type_str)

            if "InvalidChannels" in error_type_str:
                log.info("Error setting invalid # of channels (%s)" % (self.txtChannels.value()))
                track_metric_error("invalid-channels-%s-%s-%s-%s" % (self.txtVideoFormat.text(), self.txtVideoCodec.text(), self.txtAudioCodec.text(), self.txtChannels.value()))

            elif "InvalidSampleRate" in error_type_str:
                log.info("Error setting invalid sample rate (%s)" % (self.txtSampleRate.value()))
                track_metric_error("invalid-sample-rate-%s-%s-%s-%s" % (self.txtVideoFormat.text(), self.txtVideoCodec.text(), self.txtAudioCodec.text(), self.txtSampleRate.value()))

            elif "InvalidFormat" in error_type_str:
                log.info("Error setting invalid format (%s)" % (self.txtVideoFormat.text()))
                track_metric_error("invalid-format-%s" % (self.txtVideoFormat.text()))

            elif "InvalidCodec" in error_type_str:
                log.info("Error setting invalid codec (%s/%s/%s)" % (self.txtVideoFormat.text(), self.txtVideoCodec.text(), self.txtAudioCodec.text()))
                track_metric_error("invalid-codec-%s-%s-%s" % (self.txtVideoFormat.text(), self.txtVideoCodec.text(), self.txtAudioCodec.text()))

            elif "ErrorEncodingVideo" in error_type_str:
                log.info("Error encoding video frame (%s/%s/%s)" % (self.txtVideoFormat.text(), self.txtVideoCodec.text(), self.txtAudioCodec.text()))
                track_metric_error("video-encode-%s-%s-%s" % (self.txtVideoFormat.text(), self.txtVideoCodec.text(), self.txtAudioCodec.text()))

            # Show friendly error
            friendly_error = error_type_str.split("> ")[0].replace("<", "")

            # Prompt error message
            msg = QMessageBox()
            _ = get_app()._tr
            msg.setWindowTitle(_("Export Error"))
            msg.setText(_("Sorry, there was an error exporting your video: \n%s") % friendly_error)
            msg.exec_()

        # Accept dialog
        super(Export, self).accept()

        # Restore timeline settings
        self.restoreTimeline()

        log.info("End Accept")
Example #33
0
	def __init__(self):
		
		#Create dialog class
		QDialog.__init__(self)
		
		#Load UI from designer
		ui_util.load_ui(self, self.ui_path)
		
		#Init UI
		ui_util.init_ui(self)

		#get translations
		app = get_app()
		_ = app._tr
		
		# Get settings
		self.s = settings.get_settings()
		
		# Dynamically load tabs from settings data
		self.settings_data = settings.get_settings().get_all_settings()
		
		# Load all user values
		self.params = {}
		for item in self.settings_data:
			if "setting" in item and "value" in item:
				self.params[item["setting"]] = item
		
		self.category_names = {}
		self.category_tabs = {}
		# Loop through settings and find all unique categories
		for item in self.settings_data:
			category = item["category"]
			setting_type = item["type"]
			
			if not setting_type == "hidden":
				# Load setting
				if not category in self.category_names:
					self.category_names[category] = []
					
					# Add new category as a tab
					tabWidget = QWidget(self)
					self.tabCategories.addTab(tabWidget, _(category))
					self.category_tabs[category] = tabWidget
					
					# Add form layout to this tab
					layout = QFormLayout(tabWidget)
				
				# Append settings into correct category
				self.category_names[category].append(item)
				
		# Loop through each category setting, and add them to the tabs
		for category in self.category_tabs.keys():
			tabWidget = self.category_tabs[category]

			# Loop through settings for each category
			for param in self.category_names[category]:
				
				# Create Label
				widget = None
				label = QLabel()
				label.setText(_(param["title"]))
				label.setToolTip(_(param["title"]))
	
				if param["type"] == "spinner":
					# create spinner
					widget = QDoubleSpinBox()
					widget.setMinimum(float(param["min"]))
					widget.setMaximum(float(param["max"]))
					widget.setValue(float(param["value"]))
					widget.setSingleStep(1.0)
					widget.setToolTip(param["title"])
					widget.valueChanged.connect(functools.partial(self.spinner_value_changed, param))
					
				elif param["type"] == "text":
					# create spinner
					widget = QLineEdit()
					widget.setText(_(param["value"]))
					widget.textChanged.connect(functools.partial(self.text_value_changed, widget, param))
					
				elif param["type"] == "bool":
					# create spinner
					widget = QCheckBox()
					if param["value"] == True:
						widget.setCheckState(Qt.Checked)
					else:
						widget.setCheckState(Qt.Unchecked)
					widget.stateChanged.connect(functools.partial(self.bool_value_changed, widget, param))
					
				elif param["type"] == "dropdown":
	
					# create spinner
					widget = QComboBox()

					# Add normal values
					box_index = 0
					for value_item in param["values"]:
						k = value_item["name"]
						v = value_item["value"]
						# add dropdown item
						widget.addItem(_(k), v)
						
						# select dropdown (if default)
						if v == param["value"]:
							widget.setCurrentIndex(box_index)
						box_index = box_index + 1
						
					widget.currentIndexChanged.connect(functools.partial(self.dropdown_index_changed, widget, param))


				# Add Label and Widget to the form
				if (widget and label):
					tabWidget.layout().addRow(label, widget)
				elif (label):
					tabWidget.layout().addRow(label)
Example #34
0
    def __init__(self, files=None, position=0.0):
        # Create dialog class
        QDialog.__init__(self)

        # Load UI from Designer
        ui_util.load_ui(self, self.ui_path)

        # Init UI
        ui_util.init_ui(self)

        # Get settings
        self.settings = settings.get_settings()

        # Get translation object
        self.app = get_app()
        _ = self.app._tr

        # Track metrics
        track_metric_screen("add-to-timeline-screen")

        # Add custom treeview to window
        self.treeFiles = TimelineTreeView(self)
        self.vboxTreeParent.insertWidget(0, self.treeFiles)

        # Update data in model
        self.treeFiles.timeline_model.update_model(files)

        # Refresh view
        self.treeFiles.refresh_view()

        # Init start position
        self.txtStartTime.setValue(position)

        # Init default image length
        self.txtImageLength.setValue(self.settings.get("default-image-length"))
        self.txtImageLength.valueChanged.connect(self.updateTotal)
        self.cmbTransition.currentIndexChanged.connect(self.updateTotal)
        self.cmbFade.currentIndexChanged.connect(self.updateTotal)
        self.txtFadeLength.valueChanged.connect(self.updateTotal)
        self.txtTransitionLength.valueChanged.connect(self.updateTotal)

        # Add all tracks to dropdown
        tracks = Track.filter()
        for track in reversed(tracks):
            # Add to dropdown
            self.cmbTrack.addItem(_('Track %s' % track.data['number']), track.data['number'])

        # Add all fade options
        self.cmbFade.addItem(_('None'), None)
        self.cmbFade.addItem(_('Fade In'), 'Fade In')
        self.cmbFade.addItem(_('Fade Out'), 'Fade Out')
        self.cmbFade.addItem(_('Fade In & Out'), 'Fade In & Out')

        # Add all zoom options
        self.cmbZoom.addItem(_('None'), None)
        self.cmbZoom.addItem(_('Random'), 'Random')
        self.cmbZoom.addItem(_('Zoom In'), 'Zoom In')
        self.cmbZoom.addItem(_('Zoom Out'), 'Zoom Out')

        # Add all transitions
        transitions_dir = os.path.join(info.PATH, "transitions")
        common_dir = os.path.join(transitions_dir, "common")
        extra_dir = os.path.join(transitions_dir, "extra")
        transition_groups = [{"type": "common", "dir": common_dir, "files": os.listdir(common_dir)},
                             {"type": "extra", "dir": extra_dir, "files": os.listdir(extra_dir)}]

        self.cmbTransition.addItem(_('None'), None)
        self.cmbTransition.addItem(_('Random'), 'random')
        self.transitions = []
        for group in transition_groups:
            type = group["type"]
            dir = group["dir"]
            files = group["files"]

            for filename in sorted(files):
                path = os.path.join(dir, filename)
                (fileBaseName, fileExtension) = os.path.splitext(filename)

                # Skip hidden files (such as .DS_Store, etc...)
                if filename[0] == "." or "thumbs.db" in filename.lower():
                    continue

                # split the name into parts (looking for a number)
                suffix_number = None
                name_parts = fileBaseName.split("_")
                if name_parts[-1].isdigit():
                    suffix_number = name_parts[-1]

                # get name of transition
                trans_name = fileBaseName.replace("_", " ").capitalize()

                # replace suffix number with placeholder (if any)
                if suffix_number:
                    trans_name = trans_name.replace(suffix_number, "%s")
                    trans_name = _(trans_name) % suffix_number
                else:
                    trans_name = _(trans_name)

                # Check for thumbnail path (in build-in cache)
                thumb_path = os.path.join(info.IMAGES_PATH, "cache",  "{}.png".format(fileBaseName))

                # Check built-in cache (if not found)
                if not os.path.exists(thumb_path):
                    # Check user folder cache
                    thumb_path = os.path.join(info.CACHE_PATH, "{}.png".format(fileBaseName))

                # Add item
                self.transitions.append(path)
                self.cmbTransition.addItem(QIcon(thumb_path), _(trans_name), path)

        # Connections
        self.btnMoveUp.clicked.connect(self.btnMoveUpClicked)
        self.btnMoveDown.clicked.connect(self.btnMoveDownClicked)
        self.btnShuffle.clicked.connect(self.btnShuffleClicked)
        self.btnRemove.clicked.connect(self.btnRemoveClicked)
        self.btnBox.accepted.connect(self.accept)
        self.btnBox.rejected.connect(self.reject)

        # Update total
        self.updateTotal()
Example #35
0
    def save_settings(self):
        s = settings.get_settings()

        # Save window state and geometry (saves toolbar and dock locations)
        s.set('window_state', qt_types.bytes_to_str(self.saveState()))
        s.set('window_geometry', qt_types.bytes_to_str(self.saveGeometry()))
Example #36
0
    def __init__(self):

        # Create dialog class
        QDialog.__init__(self)

        # Load UI from designer
        ui_util.load_ui(self, self.ui_path)

        # Init UI
        ui_util.init_ui(self)

        # get translations
        app = get_app()
        _ = app._tr

        # Get settings
        self.s = settings.get_settings()

        # Dynamically load tabs from settings data
        self.settings_data = settings.get_settings().get_all_settings()

        # Track metrics
        track_metric_screen("preferences-screen")

        # Load all user values
        self.params = {}
        for item in self.settings_data:
            if "setting" in item and "value" in item:
                self.params[item["setting"]] = item

        self.requires_restart = False
        self.category_names = {}
        self.category_tabs = {}
        # Loop through settings and find all unique categories
        for item in self.settings_data:
            category = item["category"]
            setting_type = item["type"]

            if not setting_type == "hidden":
                # Load setting
                if not category in self.category_names:
                    self.category_names[category] = []

                    # Add new category as a tab
                    tabWidget = QWidget(self)
                    self.tabCategories.addTab(tabWidget, _(category))
                    self.category_tabs[category] = tabWidget

                    # Add form layout to this tab
                    layout = QFormLayout(tabWidget)

                # Append settings into correct category
                self.category_names[category].append(item)

        # Loop through each category setting, and add them to the tabs
        for category in self.category_tabs.keys():
            tabWidget = self.category_tabs[category]

            # Loop through settings for each category
            for param in self.category_names[category]:

                # Create Label
                widget = None
                label = QLabel()
                label.setText(_(param["title"]))
                label.setToolTip(_(param["title"]))

                if param["type"] == "spinner":
                    # create QDoubleSpinBox
                    widget = QDoubleSpinBox()
                    widget.setMinimum(float(param["min"]))
                    widget.setMaximum(float(param["max"]))
                    widget.setValue(float(param["value"]))
                    widget.setSingleStep(1.0)
                    widget.setToolTip(param["title"])
                    widget.valueChanged.connect(
                        functools.partial(self.spinner_value_changed, param))

                if param["type"] == "spinner-int":
                    # create QDoubleSpinBox
                    widget = QSpinBox()
                    widget.setMinimum(int(param["min"]))
                    widget.setMaximum(int(param["max"]))
                    widget.setValue(int(param["value"]))
                    widget.setSingleStep(1.0)
                    widget.setToolTip(param["title"])
                    widget.valueChanged.connect(
                        functools.partial(self.spinner_value_changed, param))

                elif param["type"] == "text":
                    # create QLineEdit
                    widget = QLineEdit()
                    widget.setText(_(param["value"]))
                    widget.textChanged.connect(
                        functools.partial(self.text_value_changed, widget,
                                          param))

                elif param["type"] == "bool":
                    # create spinner
                    widget = QCheckBox()
                    if param["value"] == True:
                        widget.setCheckState(Qt.Checked)
                    else:
                        widget.setCheckState(Qt.Unchecked)
                    widget.stateChanged.connect(
                        functools.partial(self.bool_value_changed, widget,
                                          param))

                elif param["type"] == "dropdown":

                    # create spinner
                    widget = QComboBox()

                    # Get values
                    value_list = param["values"]
                    # Overwrite value list (for profile dropdown)
                    if param["setting"] == "default-profile":
                        value_list = []
                        # Loop through profiles
                        for profile_folder in [
                                info.USER_PROFILES_PATH, info.PROFILES_PATH
                        ]:
                            for file in os.listdir(profile_folder):
                                # Load Profile and append description
                                profile_path = os.path.join(
                                    profile_folder, file)
                                profile = openshot.Profile(profile_path)
                                value_list.append({
                                    "name":
                                    profile.info.description,
                                    "value":
                                    profile.info.description
                                })
                        # Sort profile list
                        value_list.sort(key=operator.itemgetter("name"))

                    # Overwrite value list (for language dropdown)
                    if param["setting"] == "default-language":
                        value_list = []
                        # Loop through languages
                        for locale, language, country in get_all_languages():
                            # Load Profile and append description
                            if language:
                                lang_name = "%s (%s)" % (language, locale)
                                value_list.append({
                                    "name": lang_name,
                                    "value": locale
                                })
                        # Sort profile list
                        value_list.sort(key=operator.itemgetter("name"))
                        # Add Default to top of list
                        value_list.insert(0, {
                            "name": _("Default"),
                            "value": "Default"
                        })

                    # Add normal values
                    box_index = 0
                    for value_item in value_list:
                        k = value_item["name"]
                        v = value_item["value"]
                        # add dropdown item
                        widget.addItem(_(k), v)

                        # select dropdown (if default)
                        if v == param["value"]:
                            widget.setCurrentIndex(box_index)
                        box_index = box_index + 1

                    widget.currentIndexChanged.connect(
                        functools.partial(self.dropdown_index_changed, widget,
                                          param))

                # Add Label and Widget to the form
                if (widget and label):
                    tabWidget.layout().addRow(label, widget)
                elif (label):
                    tabWidget.layout().addRow(label)
    def initTimeline(self, cuts, clips_json):
        project = get_app().project
        fps = project.get(["fps"])
        width = project.get(["width"])
        height = project.get(["height"])
        sample_rate = project.get(["sample_rate"])
        channels = project.get(["channels"])
        channel_layout = project.get(["channel_layout"])
        '''
        self.file_path = file.absolute_path()
        self.video_length = int(file.data['video_length'])
        self.fps_num = int(file.data['fps']['num'])
        self.fps_den = int(file.data['fps']['den'])
        self.fps = float(self.fps_num) / float(self.fps_den)
        self.width = int(file.data['width'])
        self.height = int(file.data['height'])
        self.sample_rate = int(file.data['sample_rate'])
        self.channels = int(file.data['channels'])
        self.channel_layout = int(file.data['channel_layout'])

        # Open video file with Reader
        log.info(self.file_path)
        '''

        # Create an instance of a libopenshot Timeline object
        timeline = openshot.Timeline(width, height, openshot.Fraction(fps["num"], fps["den"]), sample_rate,
                                   channels, channel_layout)

        try:
            # Add clip for current preview file
            clip = openshot.Clip("/Users/admin/Downloads/BLACKPINK_Kill_This_Love.mp4")

            # Show waveform for audio files
            if not clip.Reader().info.has_video and clip.Reader().info.has_audio:
                clip.Waveform(True)

            # Set has_audio property
            #timeline.info.has_audio = clip.Reader().info.has_audio

            timeline.AddClip(clip)

        except:
            log.error('Failed to load media file into preview player: %s' % self.file_path)
            return None

        timeline.Open()
        return timeline
        try:
            import json
        except ImportError:
            import simplejson as json

        s = settings.get_settings()
        project = get_app().project
        # Get some settings from the project
        fps = project.get(["fps"])
        width = project.get(["width"])
        height = project.get(["height"])
        sample_rate = project.get(["sample_rate"])
        channels = project.get(["channels"])
        channel_layout = project.get(["channel_layout"])

        # Create an instance of a libopenshot Timeline object
        timeline = openshot.Timeline(width, height, openshot.Fraction(fps["num"], fps["den"]), sample_rate,
                                          channels, channel_layout)
        timeline.info.channel_layout = channel_layout
        timeline.info.has_audio = True
        timeline.info.has_video = True
        timeline.info.video_length = 99999
        timeline.info.duration = 999.99
        timeline.info.sample_rate = sample_rate
        timeline.info.channels = channels

        # Open the timeline reader
        timeline.Open()
#self.timeline.ApplyMapperToClips

        print("0------", timeline.info)
        #return timeline

        clips = self.jsonToClips(clips_json)
        print("222222222222221111", clips)
        for cut in cuts:
            intersecting_clips = self.getIntersectClips(clips, float(cut["start"]))
            print("111111111", intersecting_clips, fps)
            if intersecting_clips:
                for clip in intersecting_clips:
                    print("222222222", clip["reader"]["path"])
                    path = clip["reader"]["path"]
                    print("-----000000", path)
                    c = openshot.Clip(path)
                    #c.Start(cut["start"])
                    #c.End(cut["end"])
                    #c.Position = 0#cut["start"]

                    # Append missing attributes to Clip JSON
                    #new_clip = json.loads(c.Json(), strict=False)
                    #new_clip.SetJson(clip.Json())
                    #new_clip["start"] = cut["start"]
                    #new_clip["end"] = cut["end"]
                    #new_clip["position"] = 0#cut["start"]
                    try:
                        # Add clip for current preview file
                        #c.SetJson(new_clip)
                        c.display = openshot.FRAME_DISPLAY_CLIP

                        timeline.AddClip(c)
                        #print('add into preview video player: %s', c.Json())
                    except:
                        log.error('Failed to add into preview video player: %s' % c.Json())

                # Get list of clip ids
                #clip_ids = [c.id for c in intersecting_clips]
                #self.timeline.Slice_Triggered(0, clip_ids, trans_ids, playhead_position)
        # Open and set reader
        #timeline.Open()
        return timeline

        # Connect to signal
        #self.window.MaxSizeChanged.connect(self.MaxSizeChangedCB)

        '''
        if action.type == "load":
                # This JSON is initially loaded to libopenshot to update the timeline
                self.timeline.SetJson(action.json(only_value=True))
                self.timeline.Open()  # Re-Open the Timeline reader

                # The timeline's profile changed, so update all clips
                self.timeline.ApplyMapperToClips()

                # Refresh current frame (since the entire timeline was updated)
                self.window.refreshFrameSignal.emit()

            else:
                # This JSON DIFF is passed to libopenshot to update the timeline
                self.timeline.ApplyJsonDiff(action.json(is_array=True))
        '''
        '''
Example #38
0
    def __init__(self, id, text, arrow, *args):
        # Invoke parent init
        QWidget.__init__(self, *args)

        # get translations
        app = get_app()
        _ = app._tr

        # Keep track of widget to position next to
        self.id = id
        self.arrow = arrow

        # Create vertical box
        vbox = QVBoxLayout()
        vbox.setContentsMargins(32,10,10,10)

        # Add label
        self.label = QLabel(self)
        self.label.setText(text)
        self.label.setTextFormat(Qt.RichText)
        self.label.setWordWrap(True)
        self.label.setStyleSheet("margin-left: 20px;")
        vbox.addWidget(self.label)

        # Add error and anonymous metrics checkbox (for ID=0) tooltip
        # This is a bit of a hack, but since it's the only exception, it's
        # probably okay for now.
        if self.id == "0":
            # Get settings
            s = get_settings()

            # create spinner
            checkbox_metrics = QCheckBox()
            checkbox_metrics.setText(_("Yes, I would like to improve OpenShot!"))
            checkbox_metrics.setStyleSheet("margin-left: 25px; margin-bottom: 5px;")
            if s.get("send_metrics"):
                checkbox_metrics.setCheckState(Qt.Checked)
            else:
                checkbox_metrics.setCheckState(Qt.Unchecked)
            checkbox_metrics.stateChanged.connect(functools.partial(self.checkbox_metrics_callback))
            vbox.addWidget(checkbox_metrics)

        # Add button box
        hbox = QHBoxLayout()
        hbox.setContentsMargins(20,10,0,0)

        # Create buttons
        self.btn_close_tips = QPushButton(self)
        self.btn_close_tips.setText(_("Hide Tutorial"))
        self.btn_next_tip = QPushButton(self)
        self.btn_next_tip.setText(_("Next"))
        self.btn_next_tip.setStyleSheet("font-weight:bold;")
        hbox.addWidget(self.btn_close_tips)
        hbox.addWidget(self.btn_next_tip)
        vbox.addLayout(hbox)

        # Set layout
        self.setLayout(vbox)

        # Set size
        self.setMinimumWidth(350)
        self.setMinimumHeight(100)

        # Make transparent
        self.setAttribute(Qt.WA_NoSystemBackground, True)
        self.setAttribute(Qt.WA_TranslucentBackground, True)
Example #39
0
    def LoadFile(self, path=None):
        """ Load a media file into the video player """
        # Check to see if this path is already loaded
        # TODO: Determine why path is passed in as an empty string instead of None
        if path == self.clip_path or (not path and not self.clip_path):
            return

        log.info("LoadFile %s" % path)
        s = settings.get_settings()

        # Determine the current frame of the timeline (when switching to a clip)
        seek_position = 1
        if path and not self.clip_path:
            # Track the current frame
            self.original_position = self.player.Position()

        # If blank path, switch back to self.timeline reader
        if not path:
            # Return to self.timeline reader
            log.info("Set timeline reader again in player: %s" % self.timeline)
            self.player.Reader(self.timeline)

            # Clear clip reader reference
            self.clip_reader = None
            self.clip_path = None

            # Switch back to last timeline position
            seek_position = self.original_position
        else:
            # Get extension of media path
            ext = os.path.splitext(path)

            # Create new timeline reader (to preview selected clip)
            s = settings.get_settings()
            project = get_app().project

            # Get some settings from the project
            fps = project.get(["fps"])
            width = project.get(["width"])
            height = project.get(["height"])
            sample_rate = project.get(["sample_rate"])
            channels = project.get(["channels"])
            channel_layout = project.get(["channel_layout"])

            # Create an instance of a libopenshot Timeline object
            self.clip_reader = openshot.Timeline(width, height, openshot.Fraction(fps["num"], fps["den"]), sample_rate, channels, channel_layout)
            self.clip_reader.info.channel_layout = channel_layout
            self.clip_reader.info.has_audio = True
            self.clip_reader.info.has_video = True
            self.clip_reader.info.video_length = 999999
            self.clip_reader.info.duration = 999999
            self.clip_reader.info.sample_rate = sample_rate
            self.clip_reader.info.channels = channels

            try:
                # Add clip for current preview file
                new_clip = openshot.Clip(path)
                self.clip_reader.AddClip(new_clip)
            except:
                log.error('Failed to load media file into video player: %s' % path)
                return

            # Assign new clip_reader
            self.clip_path = path

            # Keep track of previous clip readers (so we can Close it later)
            self.previous_clips.append(new_clip)
            self.previous_clip_readers.append(self.clip_reader)

            # Open and set reader
            self.clip_reader.Open()
            self.player.Reader(self.clip_reader)

        # Close and destroy old clip readers (leaving the 3 most recent)
        while len(self.previous_clip_readers) > 3:
            log.info('Removing old clips from preview: %s' % self.previous_clip_readers[0])
            previous_clip = self.previous_clips.pop(0)
            previous_clip.Close()
            previous_reader = self.previous_clip_readers.pop(0)
            previous_reader.Close()

        # Seek to frame 1, and resume speed
        self.Seek(seek_position)
Example #40
0
    def __init__(self):

        # Create dialog class
        QDialog.__init__(self)

        # Load UI from designer
        ui_util.load_ui(self, self.ui_path)

        # Init UI
        ui_util.init_ui(self)

        # get translations
        app = get_app()
        _ = app._tr

        # Get settings
        self.s = settings.get_settings()

        # Dynamically load tabs from settings data
        self.settings_data = settings.get_settings().get_all_settings()

        # Track metrics
        track_metric_screen("preferences-screen")

        # Load all user values
        self.params = {}
        for item in self.settings_data:
            if "setting" in item and "value" in item:
                self.params[item["setting"]] = item

        self.requires_restart = False
        self.category_names = {}
        self.category_tabs = {}
        # Loop through settings and find all unique categories
        for item in self.settings_data:
            category = item["category"]
            setting_type = item["type"]

            if not setting_type == "hidden":
                # Load setting
                if not category in self.category_names:
                    self.category_names[category] = []

                    # Add new category as a tab
                    tabWidget = QWidget(self)
                    self.tabCategories.addTab(tabWidget, _(category))
                    self.category_tabs[category] = tabWidget

                    # Add form layout to this tab
                    layout = QFormLayout(tabWidget)

                # Append settings into correct category
                self.category_names[category].append(item)

        # Loop through each category setting, and add them to the tabs
        for category in self.category_tabs.keys():
            tabWidget = self.category_tabs[category]

            # Loop through settings for each category
            for param in self.category_names[category]:

                # Create Label
                widget = None
                label = QLabel()
                label.setText(_(param["title"]))
                label.setToolTip(_(param["title"]))

                if param["type"] == "spinner":
                    # create QDoubleSpinBox
                    widget = QDoubleSpinBox()
                    widget.setMinimum(float(param["min"]))
                    widget.setMaximum(float(param["max"]))
                    widget.setValue(float(param["value"]))
                    widget.setSingleStep(1.0)
                    widget.setToolTip(param["title"])
                    widget.valueChanged.connect(functools.partial(self.spinner_value_changed, param))

                if param["type"] == "spinner-int":
                    # create QDoubleSpinBox
                    widget = QSpinBox()
                    widget.setMinimum(int(param["min"]))
                    widget.setMaximum(int(param["max"]))
                    widget.setValue(int(param["value"]))
                    widget.setSingleStep(1.0)
                    widget.setToolTip(param["title"])
                    widget.valueChanged.connect(functools.partial(self.spinner_value_changed, param))

                elif param["type"] == "text":
                    # create QLineEdit
                    widget = QLineEdit()
                    widget.setText(_(param["value"]))
                    widget.textChanged.connect(functools.partial(self.text_value_changed, widget, param))

                elif param["type"] == "bool":
                    # create spinner
                    widget = QCheckBox()
                    if param["value"] == True:
                        widget.setCheckState(Qt.Checked)
                    else:
                        widget.setCheckState(Qt.Unchecked)
                    widget.stateChanged.connect(functools.partial(self.bool_value_changed, widget, param))

                elif param["type"] == "dropdown":

                    # create spinner
                    widget = QComboBox()

                    # Get values
                    value_list = param["values"]
                    # Overwrite value list (for profile dropdown)
                    if param["setting"] == "default-profile":
                        value_list = []
                        # Loop through profiles
                        for profile_folder in [info.USER_PROFILES_PATH, info.PROFILES_PATH]:
                            for file in os.listdir(profile_folder):
                                # Load Profile and append description
                                profile_path = os.path.join(profile_folder, file)
                                profile = openshot.Profile(profile_path)
                                value_list.append({"name":profile.info.description, "value":profile.info.description})
                        # Sort profile list
                        value_list.sort(key=operator.itemgetter("name"))

                    # Overwrite value list (for language dropdown)
                    if param["setting"] == "default-language":
                        value_list = []
                        # Loop through languages
                        for locale, language, country in get_all_languages():
                            # Load Profile and append description
                            if language:
                                lang_name = "%s (%s)" % (language, locale)
                                value_list.append({"name":lang_name, "value":locale})
                        # Sort profile list
                        value_list.sort(key=operator.itemgetter("name"))
                        # Add Default to top of list
                        value_list.insert(0, {"name":_("Default"), "value":"Default"})


                    # Add normal values
                    box_index = 0
                    for value_item in value_list:
                        k = value_item["name"]
                        v = value_item["value"]
                        # add dropdown item
                        widget.addItem(_(k), v)

                        # select dropdown (if default)
                        if v == param["value"]:
                            widget.setCurrentIndex(box_index)
                        box_index = box_index + 1

                    widget.currentIndexChanged.connect(functools.partial(self.dropdown_index_changed, widget, param))


                # Add Label and Widget to the form
                if (widget and label):
                    tabWidget.layout().addRow(label, widget)
                elif (label):
                    tabWidget.layout().addRow(label)
Example #41
0
def init_language():
    """ Find the current locale, and install the correct translators """

    # Get app instance
    app = QCoreApplication.instance()

    # Setup of our list of translators and paths
    translator_types = (
        {
            "type": 'QT',
            "pattern":
            'qt_%s',  # Older versions of Qt use this file (built-in translations)
            "path": QLibraryInfo.location(QLibraryInfo.TranslationsPath)
        },
        {
            "type": 'QT',
            "pattern":
            'qtbase_%s',  # Newer versions of Qt use this file (built-in translations)
            "path": QLibraryInfo.location(QLibraryInfo.TranslationsPath)
        },
        {
            "type": 'QT',
            "pattern": 'qt_%s',
            "path": os.path.join(info.PATH, 'locale', 'QT')
        },  # Optional path where we package QT translations
        {
            "type": 'QT',
            "pattern": 'qtbase_%s',
            "path": os.path.join(info.PATH, 'locale', 'QT')
        },  # Optional path where we package QT translations
        {
            "type": 'OpenShot',
            "pattern": os.path.join('%s', 'LC_MESSAGES',
                                    'OpenShot'),  # Our custom translations
            "path": os.path.join(info.PATH, 'locale')
        },
    )

    # Determine the environment locale, or default to system locale name
    locale_names = [
        os.environ.get('LANG',
                       QLocale().system().name()),
        os.environ.get('LOCALE',
                       QLocale().system().name())
    ]

    # Determine if the user has overwritten the language (in the preferences)
    preference_lang = settings.get_settings().get('default-language')
    if preference_lang != "Default":
        # Append preference lang to top of list
        locale_names.insert(0, preference_lang)

    # Output all system languages detected
    log.info("Qt Detected Languages: {}".format(
        QLocale().system().uiLanguages()))
    log.info("LANG Environment Variable: {}".format(
        os.environ.get('LANG',
                       QLocale().system().name())))
    log.info("LOCALE Environment Variable: {}".format(
        os.environ.get('LOCALE',
                       QLocale().system().name())))

    # Default the locale to C, for number formatting
    locale.setlocale(locale.LC_ALL, 'C')

    # Loop through environment variables
    found_language = False
    for locale_name in locale_names:

        # Don't try on default locale, since it fails to load what is the default language
        if 'en_US' in locale_name:
            log.info("Skipping English language (no need for translation): {}".
                     format(locale_name))
            continue

        # Go through each translator and try to add for current locale
        for type in translator_types:
            trans = QTranslator(app)
            if find_language_match(type["pattern"], type["path"], trans,
                                   locale_name):
                # Install translation
                app.installTranslator(trans)
                found_language = True

        # Exit if found language
        if found_language:
            log.info(
                "Exiting translation system (since we successfully loaded: {})"
                .format(locale_name))
            break
    def Render(self, blend_file_path, target_script, preview_mode=False):
        """ Worker's Render method which invokes the Blender rendering commands """

        # Init regex expression used to determine blender's render progress
        s = settings.get_settings()

        _ = get_app()._tr

        # get the blender executable path
        self.blender_exec_path = s.get("blender_command")
        self.preview_mode = preview_mode
        self.frame_detected = False
        self.last_frame = 0
        self.version = None
        self.command_output = ""
        self.process = None
        self.is_running = False

        blender_frame_re = re.compile(r"Fra:([0-9,]*)")
        blender_saved_re = re.compile(r"Saved: '(.*\.png)")
        blender_version_re = re.compile(r"Blender (.*?) ")

        startupinfo = None
        if sys.platform == 'win32':
            startupinfo = subprocess.STARTUPINFO()
            startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW

        try:
            # Shell the blender command to create the image sequence
            command_get_version = [self.blender_exec_path, '-v']
            command_render = [self.blender_exec_path, '-b', blend_file_path, '-P', target_script]

            # Check the version of Blender
            import shlex
            log.info("Checking Blender version, command: {}".format(
                " ".join([shlex.quote(x) for x in command_get_version])))

            self.process = subprocess.Popen(
                command_get_version,
                stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
                startupinfo=startupinfo,
            )

            # Check the version of Blender
            try:
                # Give Blender up to 10 seconds to respond
                (out, err) = self.process.communicate(timeout=10)
            except subprocess.TimeoutExpired:
                self.blender_error_nodata.emit()
                return

            ver_string = out.decode('utf-8')
            ver_match = blender_version_re.search(ver_string)

            if not ver_match:
                raise Exception("No Blender version detected in output")

            self.version = ver_match.group(1)
            log.info("Found Blender version {}".format(self.version))

            if self.version < info.BLENDER_MIN_VERSION:
                # Wrong version of Blender.
                self.blender_version_error.emit(self.version)
                return

            # debug info
            log.info("Running Blender, command: {}".format(
                " ".join([shlex.quote(x) for x in command_render])))
            log.info("Blender output:")

            # Run real command to render Blender project
            self.process = subprocess.Popen(
                command_render, bufsize=512,
                stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
                startupinfo=startupinfo,
            )
            self.is_running = True

        except subprocess.SubprocessError:
            # Error running command.  Most likely the blender executable path in
            # the settings is incorrect, or is not a supported Blender version
            self.is_running = False
            self.blender_error_nodata.emit()
            raise
        except Exception as ex:
            log.error("{}".format(ex))
            return

        while self.is_running and self.process.poll() is None:
            for outline in iter(self.process.stdout.readline, b''):
                line = outline.decode('utf-8').strip()

                # Skip blank output
                if not line:
                    continue

                # append all output into a variable, and log
                self.command_output = self.command_output + line + "\n"
                log.info("  {}".format(line))

                # Look for progress info in the Blender Output
                output_frame = blender_frame_re.search(line)
                output_saved = blender_saved_re.search(line)

                # Does it have a match?
                if output_frame or output_saved:
                    # Yes, we have a match
                    self.frame_detected = True

                if output_frame:
                    current_frame = int(output_frame.group(1))

                    # Update progress bar
                    if current_frame != self.last_frame and not self.preview_mode:
                        # update progress on frame change, if in 'render' mode
                        self.progress.emit(current_frame)

                    self.last_frame = current_frame

                if output_saved:
                    # Update preview image
                    self.image_updated.emit(output_saved.group(1))

        log.info("Blender process exited.")

        # Re-enable the interface
        self.enable_interface.emit()

        # Check if NO FRAMES are detected
        if not self.frame_detected:
            # Show Error that no frames are detected.  This is likely caused by
            # the wrong command being executed... or an error in Blender.
            self.blender_error_with_data.emit(_("No frame was found in the output from Blender"))

        # Done with render (i.e. close window)
        elif self.is_running and not self.preview_mode:
            # only add file to project data if in 'render' mode and not canceled
            self.finished.emit()

        # Thread finished
        if not self.is_running:
            # close window if thread was killed
            self.closed.emit()

        # mark thread as finished
        self.is_running = False
Example #43
0
    def LoadFile(self, path=None):
        """ Load a media file into the video player """
        s = settings.get_settings()

        # Check to see if this path is already loaded
        # TODO: Determine why path is passed in as an empty string instead of None
        if path == self.clip_path or (not path and not self.clip_path):
            return

        # Determine the current frame of the timeline (when switching to a clip)
        seek_position = 1
        if path and not self.clip_path:
            # Track the current frame
            self.original_position = self.player.Position()

        # Stop player (very important to prevent crashing)
        self.original_speed = self.player.Speed()
        self.player.Speed(0)

        # If blank path, switch back to self.timeline reader
        if not path:
            # Return to self.timeline reader
            log.info("Set timeline reader again in player: %s" % self.timeline)
            self.player.Reader(self.timeline)

            # Clear clip reader reference
            self.clip_reader = None
            self.clip_path = None

            # Switch back to last timeline position
            seek_position = self.original_position
        else:
            # Get extension of media path
            ext = os.path.splitext(path)

            # Load Reader based on extension
            new_reader = None
            if ext in ['.avi', 'mov', 'mkv', 'mpg', 'mpeg', 'mp3', 'mp4', 'mts', 'ogg', 'wav', 'wmv', 'webm', 'vob']:
                try:
                    new_reader = openshot.FFmpegReader(path)
                    new_reader.Open()
                except:
                    try:
                        new_reader = openshot.QtImageReader(path)
                        new_reader.Open()
                    except:
                        log.error('Failed to load media file into video player: %s' % path)
                        return
            else:
                try:
                    new_reader = openshot.QtImageReader(path)
                    new_reader.Open()
                except:
                    try:
                        new_reader = openshot.FFmpegReader(path)
                        new_reader.Open()
                    except:
                        log.error('Failed to load media file into video player: %s' % path)
                        return



            # Wrap reader in FrameMapper (to match current settings of timeline)
            new_mapper = openshot.FrameMapper(new_reader, self.timeline.info.fps, openshot.PULLDOWN_NONE, self.timeline.info.sample_rate,
                                                    self.timeline.info.channels, self.timeline.info.channel_layout)

            # Keep track of previous clip readers (so we can Close it later)
            self.previous_clip_mappers.append(new_mapper)
            self.previous_clip_readers.append(new_reader)

            # Assign new clip_reader
            self.clip_reader = new_mapper
            self.clip_path = path

            # Open reader
            self.clip_reader.Open()

            log.info("Set new FrameMapper reader in player: %s" % self.clip_reader)
            self.player.Reader(self.clip_reader)

        # Close and destroy old clip readers (leaving the 3 most recent)
        while len(self.previous_clip_readers) > 3:
            log.info('Removing old clip reader: %s' % self.previous_clip_readers[0])
            self.previous_clip_mappers.pop(0)
            self.previous_clip_readers.pop(0)

        # Seek to frame 1, and resume speed
        self.player.Seek(seek_position)
        self.player.Speed(self.original_speed)
Example #44
0
    def __init__(self):

        # Create dialog class
        QDialog.__init__(self)

        # Load UI from designer
        ui_util.load_ui(self, self.ui_path)

        # Init UI
        ui_util.init_ui(self)

        # get translations
        app = get_app()
        _ = app._tr

        # Get settings
        self.s = settings.get_settings()

        # Dynamically load tabs from settings data
        self.settings_data = settings.get_settings().get_all_settings()

        # Track metrics
        track_metric_screen("preferences-screen")

        # Load all user values
        self.params = {}
        for item in self.settings_data:
            if "setting" in item and "value" in item:
                self.params[item["setting"]] = item

        self.requires_restart = False
        self.category_names = {}
        self.category_tabs = {}
        self.category_sort = {}

        # Loop through settings and find all unique categories
        for item in self.settings_data:
            category = item.get("category")
            setting_type = item.get("type")
            sort_category = item.get("sort")

            # Indicate sorted category
            if sort_category:
                self.category_sort[category] = sort_category

            if not setting_type == "hidden":
                # Load setting
                if not category in self.category_names:
                    self.category_names[category] = []

                    # Create scrollarea
                    scroll_area = QScrollArea(self)
                    scroll_area.setWidgetResizable(True)
                    scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
                    scroll_area.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

                    # Create tab widget and layout
                    layout = QVBoxLayout()
                    tabWidget = QWidget(self)
                    tabWidget.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
                    tabWidget.setLayout(layout)
                    scroll_area.setWidget(tabWidget)

                    # Add tab
                    self.tabCategories.addTab(scroll_area, _(category))
                    self.category_tabs[category] = tabWidget

                # Append translated title
                item["title_tr"] = _(item.get("title"))

                # Append settings into correct category
                self.category_names[category].append(item)

        # Loop through each category setting, and add them to the tabs
        for category in self.category_tabs.keys():
            tabWidget = self.category_tabs[category]

            # Get list of items in category
            params = self.category_names[category]
            if self.category_sort.get(category):
                # Sort this category by translated title
                params.sort(key=operator.itemgetter("title_tr"))

            # Loop through settings for each category
            for param in params:

                # Create Label
                widget = None
                extraWidget = None
                label = QLabel()
                label.setText(_(param["title"]))
                label.setToolTip(_(param["title"]))

                if param["type"] == "spinner":
                    # create QDoubleSpinBox
                    widget = QDoubleSpinBox()
                    widget.setMinimum(float(param["min"]))
                    widget.setMaximum(float(param["max"]))
                    widget.setValue(float(param["value"]))
                    widget.setSingleStep(1.0)
                    widget.setToolTip(param["title"])
                    widget.valueChanged.connect(functools.partial(self.spinner_value_changed, param))

                if param["type"] == "spinner-int":
                    # create QDoubleSpinBox
                    widget = QSpinBox()
                    widget.setMinimum(int(param["min"]))
                    widget.setMaximum(int(param["max"]))
                    widget.setValue(int(param["value"]))
                    widget.setSingleStep(1.0)
                    widget.setToolTip(param["title"])
                    widget.valueChanged.connect(functools.partial(self.spinner_value_changed, param))

                elif param["type"] == "text":
                    # create QLineEdit
                    widget = QLineEdit()
                    widget.setText(_(param["value"]))
                    widget.textChanged.connect(functools.partial(self.text_value_changed, widget, param))

                elif param["type"] == "browse":
                    # create QLineEdit
                    widget = QLineEdit()
                    widget.setText(_(param["value"]))
                    widget.textChanged.connect(functools.partial(self.text_value_changed, widget, param))
                    extraWidget = QPushButton(_("Browse..."))
                    extraWidget.clicked.connect(functools.partial(self.selectExecutable, widget, param))

                elif param["type"] == "bool":
                    # create spinner
                    widget = QCheckBox()
                    if param["value"] == True:
                        widget.setCheckState(Qt.Checked)
                    else:
                        widget.setCheckState(Qt.Unchecked)
                    widget.stateChanged.connect(functools.partial(self.bool_value_changed, widget, param))

                elif param["type"] == "dropdown":

                    # create spinner
                    widget = QComboBox()

                    # Get values
                    value_list = param["values"]
                    # Overwrite value list (for profile dropdown)
                    if param["setting"] == "default-profile":
                        value_list = []
                        # Loop through profiles
                        for profile_folder in [info.USER_PROFILES_PATH, info.PROFILES_PATH]:
                            for file in os.listdir(profile_folder):
                                # Load Profile and append description
                                profile_path = os.path.join(profile_folder, file)
                                profile = openshot.Profile(profile_path)
                                value_list.append({"name":profile.info.description, "value":profile.info.description})
                        # Sort profile list
                        value_list.sort(key=operator.itemgetter("name"))

                    # Overwrite value list (for language dropdown)
                    if param["setting"] == "default-language":
                        value_list = []
                        # Loop through languages
                        for locale, language, country in get_all_languages():
                            # Load Profile and append description
                            if language:
                                lang_name = "%s (%s)" % (language, locale)
                                value_list.append({"name":lang_name, "value":locale})
                        # Sort profile list
                        value_list.sort(key=operator.itemgetter("name"))
                        # Add Default to top of list
                        value_list.insert(0, {"name":_("Default"), "value":"Default"})


                    # Add normal values
                    box_index = 0
                    for value_item in value_list:
                        k = value_item["name"]
                        v = value_item["value"]
                        # add dropdown item
                        widget.addItem(_(k), v)

                        # select dropdown (if default)
                        if v == param["value"]:
                            widget.setCurrentIndex(box_index)
                        box_index = box_index + 1

                    widget.currentIndexChanged.connect(functools.partial(self.dropdown_index_changed, widget, param))


                # Add Label and Widget to the form
                if (widget and label):
                    # Add minimum size
                    label.setMinimumWidth(180);
                    label.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
                    widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)

                    # Create HBox layout
                    layout_hbox = QHBoxLayout()
                    layout_hbox.addWidget(label)
                    layout_hbox.addWidget(widget)

                    if (extraWidget):
                        layout_hbox.addWidget(extraWidget)

                    # Add widget to layout
                    tabWidget.layout().addLayout(layout_hbox)
                elif (label):
                    # Add widget to layout
                    tabWidget.layout().addWidget(label)

            # Add stretch to bottom of layout
            tabWidget.layout().addStretch()
import urllib.parse
from copy import deepcopy
from classes import info
from classes import language
from classes.logger import log
from classes import settings
import openshot

from PyQt5.QtCore import QT_VERSION_STR
from PyQt5.Qt import PYQT_VERSION_STR

# Get libopenshot version
libopenshot_version = openshot.GetVersion()

# Get settings
s = settings.get_settings()

# Determine OS version
os_version = "X11; Linux %s" % platform.machine()
linux_distro = "None"
try:
    if platform.system() == "Darwin":
        v = platform.mac_ver()
        os_version = "Macintosh; Intel Mac OS X %s" % v[0].replace(".", "_")
        linux_distro = "OS X %s" % v[0]

    elif platform.system() == "Windows":
        v = platform.win32_ver()
        # TODO: Upgrade windows python (on build server) version to 3.5, so it correctly identifies Windows 10
        os_version = "Windows NT %s; %s" % (v[0], v[1])
        linux_distro = "Windows %s" % "-".join(platform.win32_ver())
Example #46
0
    def Render(self, blend_file_path, target_script, preview_mode=False):
        """ Worker's Render method which invokes the Blender rendering commands """
        log.info("QThread Render Method Invoked")

        # Init regex expression used to determine blender's render progress
        s = settings.get_settings()

        # get the blender executable path
        self.blender_exec_path = s.get("blender_command")
        self.blender_frame_expression = re.compile(r"Fra:([0-9,]*).*Mem:(.*?) .*Part ([0-9,]*)-([0-9,]*)")
        self.blender_saved_expression = re.compile(r"Saved: (.*.png)(.*)")
        self.blender_version = re.compile(r"Blender (.*?) ")
        self.blend_file_path = blend_file_path
        self.target_script = target_script
        self.preview_mode = preview_mode
        self.frame_detected = False
        self.version = None
        self.command_output = ""
        self.process = None
        self.is_running = True
        _ = get_app()._tr

        try:
            # Shell the blender command to create the image sequence
            command_get_version = [self.blender_exec_path, '-v']
            command_render = [self.blender_exec_path, '-b', self.blend_file_path, '-P', self.target_script]
            self.process = subprocess.Popen(command_get_version, stdout=subprocess.PIPE)

            # Check the version of Blender
            self.version = self.blender_version.findall(str(self.process.stdout.readline()))

            if self.version:
                if float(self.version[0]) < 2.62:
                    # change cursor to "default" and stop running blender command
                    self.is_running = False

                    # Wrong version of Blender.  Must be 2.62+:
                    self.blender_version_error.emit(float(self.version[0]))
                    return

            # debug info
            log.info(
                "Blender command: {} {} '{}' {} '{}'".format(command_render[0], command_render[1], command_render[2],
                                                             command_render[3], command_render[4]))

            # Run real command to render Blender project
            self.process = subprocess.Popen(command_render, stdout=subprocess.PIPE)

        except:
            # Error running command.  Most likely the blender executable path in the settings
            # is not correct, or is not the correct version of Blender (i.e. 2.62+)
            self.is_running = False
            self.blender_error_nodata.emit()
            return

        while self.is_running and self.process.poll() is None:

            # Look for progress info in the Blender Output
            line = str(self.process.stdout.readline())
            self.command_output = self.command_output + line + "\n"  # append all output into a variable
            output_frame = self.blender_frame_expression.findall(line)

            # Does it have a match?
            if output_frame:
                # Yes, we have a match
                self.frame_detected = True
                current_frame = output_frame[0][0]
                memory = output_frame[0][1]
                current_part = output_frame[0][2]
                max_parts = output_frame[0][3]

                # Update progress bar
                if not self.preview_mode:
                    # only update progress if in 'render' mode
                    self.progress.emit(float(current_frame), float(current_part), float(max_parts))

            # Look for progress info in the Blender Output
            output_saved = self.blender_saved_expression.findall(str(line))

            # Does it have a match?
            if output_saved:
                # Yes, we have a match
                self.frame_detected = True
                image_path = output_saved[0][0]
                time_saved = output_saved[0][1]

                # Update preview image
                self.image_updated.emit(image_path)


        # Re-enable the interface
        self.enable_interface.emit()

        # Check if NO FRAMES are detected
        if not self.frame_detected:
            # Show Error that no frames are detected.  This is likely caused by
            # the wrong command being executed... or an error in Blender.
            self.blender_error_with_data.emit(_("No frame was found in the output from Blender"))

        # Done with render (i.e. close window)
        elif not self.preview_mode:
            # only close window if in 'render' mode
            self.finished.emit()

        # Thread finished
        log.info("Blender render thread finished")
        if self.is_running == False:
            # close window if thread was killed
            self.closed.emit()

        # mark thread as finished
        self.is_running = False
Example #47
0
    def __init__(self):

        # Create dialog class
        QDialog.__init__(self)

        # Load UI from designer
        ui_util.load_ui(self, self.ui_path)

        # Init UI
        ui_util.init_ui(self)

        # get translations
        app = get_app()
        _ = app._tr

        # Get settings
        self.s = settings.get_settings()

        # Track metrics
        track_metric_screen("export-screen")

        # Dynamically load tabs from settings data
        self.settings_data = settings.get_settings().get_all_settings()

        # Add buttons to interface
        self.export_button = QPushButton(_('Export Video'))
        self.buttonBox.addButton(self.export_button,
                                 QDialogButtonBox.AcceptRole)
        self.buttonBox.addButton(QPushButton(_('Cancel')),
                                 QDialogButtonBox.RejectRole)
        self.exporting = False

        # Clear timeline preview cache (to get more avaiable memory)
        if get_app().window.cache_object:
            get_app().window.cache_object.Clear()

        # Hide audio channels
        self.lblChannels.setVisible(False)
        self.txtChannels.setVisible(False)

        # Get the original timeline settings
        width = get_app().window.timeline_sync.timeline.info.width
        height = get_app().window.timeline_sync.timeline.info.height
        fps = get_app().window.timeline_sync.timeline.info.fps
        sample_rate = get_app().window.timeline_sync.timeline.info.sample_rate
        channels = get_app().window.timeline_sync.timeline.info.channels
        channel_layout = get_app(
        ).window.timeline_sync.timeline.info.channel_layout

        # Create new "export" openshot.Timeline object
        self.timeline = openshot.Timeline(width, height,
                                          openshot.Fraction(fps.num, fps.den),
                                          sample_rate, channels,
                                          channel_layout)
        # Init various properties
        self.timeline.info.channel_layout = get_app(
        ).window.timeline_sync.timeline.info.channel_layout
        self.timeline.info.has_audio = get_app(
        ).window.timeline_sync.timeline.info.has_audio
        self.timeline.info.has_video = get_app(
        ).window.timeline_sync.timeline.info.has_video
        self.timeline.info.video_length = get_app(
        ).window.timeline_sync.timeline.info.video_length
        self.timeline.info.duration = get_app(
        ).window.timeline_sync.timeline.info.duration
        self.timeline.info.sample_rate = get_app(
        ).window.timeline_sync.timeline.info.sample_rate
        self.timeline.info.channels = get_app(
        ).window.timeline_sync.timeline.info.channels

        # Load the "export" Timeline reader with the JSON from the real timeline
        json_timeline = json.dumps(get_app().project._data)
        self.timeline.SetJson(json_timeline)

        # Open the "export" Timeline reader
        self.timeline.Open()

        # Default export path
        recommended_path = recommended_path = os.path.join(info.HOME_PATH)
        if app.project.current_filepath:
            recommended_path = os.path.dirname(app.project.current_filepath)

        export_path = get_app().project.get(["export_path"])
        if os.path.exists(export_path):
            # Use last selected export path
            self.txtExportFolder.setText(export_path)
        else:
            # Default to home dir
            self.txtExportFolder.setText(recommended_path)

        # Is this a saved project?
        if not get_app().project.current_filepath:
            # Not saved yet
            self.txtFileName.setText(_("Untitled Project"))
        else:
            # Yes, project is saved
            # Get just the filename
            parent_path, filename = os.path.split(
                get_app().project.current_filepath)
            filename, ext = os.path.splitext(filename)
            self.txtFileName.setText(
                filename.replace("_", " ").replace("-", " ").capitalize())

        # Default image type
        self.txtImageFormat.setText("%05.png")

        # Loop through Export To options
        export_options = [_("Video & Audio"), _("Image Sequence")]
        for option in export_options:
            # append profile to list
            self.cboExportTo.addItem(option)

        # Add channel layouts
        self.channel_layout_choices = []
        for layout in [(openshot.LAYOUT_MONO, _("Mono (1 Channel)")),
                       (openshot.LAYOUT_STEREO, _("Stereo (2 Channel)")),
                       (openshot.LAYOUT_SURROUND, _("Surround (3 Channel)")),
                       (openshot.LAYOUT_5POINT1, _("Surround (5.1 Channel)")),
                       (openshot.LAYOUT_7POINT1, _("Surround (7.1 Channel)"))]:
            log.info(layout)
            self.channel_layout_choices.append(layout[0])
            self.cboChannelLayout.addItem(layout[1], layout[0])

        # Connect signals
        self.btnBrowse.clicked.connect(
            functools.partial(self.btnBrowse_clicked))
        self.cboSimpleProjectType.currentIndexChanged.connect(
            functools.partial(self.cboSimpleProjectType_index_changed,
                              self.cboSimpleProjectType))
        self.cboProfile.currentIndexChanged.connect(
            functools.partial(self.cboProfile_index_changed, self.cboProfile))
        self.cboSimpleTarget.currentIndexChanged.connect(
            functools.partial(self.cboSimpleTarget_index_changed,
                              self.cboSimpleTarget))
        self.cboSimpleVideoProfile.currentIndexChanged.connect(
            functools.partial(self.cboSimpleVideoProfile_index_changed,
                              self.cboSimpleVideoProfile))
        self.cboSimpleQuality.currentIndexChanged.connect(
            functools.partial(self.cboSimpleQuality_index_changed,
                              self.cboSimpleQuality))
        self.cboChannelLayout.currentIndexChanged.connect(self.updateChannels)
        get_app().window.ExportFrame.connect(self.updateProgressBar)

        # ********* Advaned Profile List **********
        # Loop through profiles
        self.profile_names = []
        self.profile_paths = {}
        for profile_folder in [info.USER_PROFILES_PATH, info.PROFILES_PATH]:
            for file in os.listdir(profile_folder):
                # Load Profile
                profile_path = os.path.join(profile_folder, file)
                profile = openshot.Profile(profile_path)

                # Add description of Profile to list
                self.profile_names.append(profile.info.description)
                self.profile_paths[profile.info.description] = profile_path

        # Sort list
        self.profile_names.sort()

        # Loop through sorted profiles
        box_index = 0
        self.selected_profile_index = 0
        for profile_name in self.profile_names:

            # Add to dropdown
            self.cboProfile.addItem(profile_name,
                                    self.profile_paths[profile_name])

            # Set default (if it matches the project)
            if app.project.get(['profile']) == profile_name:
                self.selected_profile_index = box_index

            # increment item counter
            box_index += 1

        # ********* Simple Project Type **********
        # load the simple project type dropdown
        presets = []
        for file in os.listdir(info.EXPORT_PRESETS_DIR):
            xmldoc = xml.parse(os.path.join(info.EXPORT_PRESETS_DIR, file))
            type = xmldoc.getElementsByTagName("type")
            presets.append(_(type[0].childNodes[0].data))

        # Exclude duplicates
        type_index = 0
        selected_type = 0
        presets = list(set(presets))
        for item in sorted(presets):
            self.cboSimpleProjectType.addItem(item, item)
            if item == _("All Formats"):
                selected_type = type_index
            type_index += 1

        # Always select 'All Formats' option
        self.cboSimpleProjectType.setCurrentIndex(selected_type)

        # Populate all profiles
        self.populateAllProfiles(app.project.get(['profile']))

        # Connect framerate signals
        self.txtFrameRateNum.valueChanged.connect(self.updateFrameRate)
        self.txtFrameRateDen.valueChanged.connect(self.updateFrameRate)
        self.txtWidth.valueChanged.connect(self.updateFrameRate)
        self.txtHeight.valueChanged.connect(self.updateFrameRate)
        self.txtSampleRate.valueChanged.connect(self.updateFrameRate)
        self.txtChannels.valueChanged.connect(self.updateFrameRate)
        self.cboChannelLayout.currentIndexChanged.connect(self.updateFrameRate)

        # Determine the length of the timeline (in frames)
        self.updateFrameRate()
Example #48
0
    def Render(self, blend_file_path, target_script, preview_mode=False):
        """ Worker's Render method which invokes the Blender rendering commands """
        log.info("QThread Render Method Invoked")

        # Init regex expression used to determine blender's render progress
        s = settings.get_settings()

        # get the blender executable path
        self.blender_exec_path = s.get("blender_command")
        self.blender_frame_expression = re.compile(
            r"Fra:([0-9,]*).*Mem:(.*?) .*Part ([0-9,]*)-([0-9,]*)")
        self.blender_saved_expression = re.compile(r"Saved: '(.*.png)(.*)'")
        self.blender_version = re.compile(r"Blender (.*?) ")
        self.blend_file_path = blend_file_path
        self.target_script = target_script
        self.preview_mode = preview_mode
        self.frame_detected = False
        self.version = None
        self.command_output = ""
        self.process = None
        self.is_running = True
        _ = get_app()._tr

        try:
            # Shell the blender command to create the image sequence
            command_get_version = [self.blender_exec_path, '-v']
            command_render = [
                self.blender_exec_path, '-b', self.blend_file_path, '-P',
                self.target_script
            ]
            self.process = subprocess.Popen(command_get_version,
                                            stdout=subprocess.PIPE)

            # Check the version of Blender
            self.version = self.blender_version.findall(
                str(self.process.stdout.readline()))

            if self.version:
                if float(self.version[0]) < 2.78:
                    # change cursor to "default" and stop running blender command
                    self.is_running = False

                    # Wrong version of Blender.  Must be 2.62+:
                    self.blender_version_error.emit(float(self.version[0]))
                    return

            # debug info
            log.info("Blender command: {} {} '{}' {} '{}'".format(
                command_render[0], command_render[1], command_render[2],
                command_render[3], command_render[4]))

            # Run real command to render Blender project
            self.process = subprocess.Popen(command_render,
                                            stdout=subprocess.PIPE)

        except:
            # Error running command.  Most likely the blender executable path in the settings
            # is not correct, or is not the correct version of Blender (i.e. 2.62+)
            self.is_running = False
            self.blender_error_nodata.emit()
            return

        while self.is_running and self.process.poll() is None:

            # Look for progress info in the Blender Output
            line = str(self.process.stdout.readline())
            self.command_output = self.command_output + line + "\n"  # append all output into a variable
            output_frame = self.blender_frame_expression.findall(line)

            # Does it have a match?
            if output_frame:
                # Yes, we have a match
                self.frame_detected = True
                current_frame = output_frame[0][0]
                memory = output_frame[0][1]
                current_part = output_frame[0][2]
                max_parts = output_frame[0][3]

                # Update progress bar
                if not self.preview_mode:
                    # only update progress if in 'render' mode
                    self.progress.emit(float(current_frame),
                                       float(current_part), float(max_parts))

            # Look for progress info in the Blender Output
            output_saved = self.blender_saved_expression.findall(str(line))
            log.info("Image detected from blender regex: %s" % output_saved)

            # Does it have a match?
            if output_saved:
                # Yes, we have a match
                self.frame_detected = True
                image_path = output_saved[0][0]
                time_saved = output_saved[0][1]

                # Update preview image
                self.image_updated.emit(image_path)

        # Re-enable the interface
        self.enable_interface.emit()

        # Check if NO FRAMES are detected
        if not self.frame_detected:
            # Show Error that no frames are detected.  This is likely caused by
            # the wrong command being executed... or an error in Blender.
            self.blender_error_with_data.emit(
                _("No frame was found in the output from Blender"))

        # Done with render (i.e. close window)
        elif not self.preview_mode:
            # only close window if in 'render' mode
            self.finished.emit()

        # Thread finished
        log.info("Blender render thread finished")
        if self.is_running == False:
            # close window if thread was killed
            self.closed.emit()

        # mark thread as finished
        self.is_running = False
Example #49
0
    def __init__(self, files=None, position=0.0):
        # Create dialog class
        QDialog.__init__(self)

        # Load UI from Designer
        ui_util.load_ui(self, self.ui_path)

        # Init UI
        ui_util.init_ui(self)

        # Get settings
        self.settings = settings.get_settings()

        # Get translation object
        self.app = get_app()
        _ = self.app._tr

        # Track metrics
        track_metric_screen("add-to-timeline-screen")

        # Add custom treeview to window
        self.treeFiles = TimelineTreeView(self)
        self.vboxTreeParent.insertWidget(0, self.treeFiles)

        # Update data in model
        self.treeFiles.timeline_model.update_model(files)

        # Refresh view
        self.treeFiles.refresh_view()

        # Init start position
        self.txtStartTime.setValue(position)

        # Init default image length
        self.txtImageLength.setValue(self.settings.get("default-image-length"))
        self.txtImageLength.valueChanged.connect(self.updateTotal)
        self.cmbTransition.currentIndexChanged.connect(self.updateTotal)
        self.cmbFade.currentIndexChanged.connect(self.updateTotal)
        self.txtFadeLength.valueChanged.connect(self.updateTotal)
        self.txtTransitionLength.valueChanged.connect(self.updateTotal)

        # Add all tracks to dropdown
        tracks = Track.filter()
        for track in reversed(tracks):
            # Add to dropdown
            self.cmbTrack.addItem(_('Track %s' % track.data['number']),
                                  track.data['number'])

        # Add all fade options
        self.cmbFade.addItem(_('None'), None)
        self.cmbFade.addItem(_('Fade In'), 'Fade In')
        self.cmbFade.addItem(_('Fade Out'), 'Fade Out')
        self.cmbFade.addItem(_('Fade In & Out'), 'Fade In & Out')

        # Add all zoom options
        self.cmbZoom.addItem(_('None'), None)
        self.cmbZoom.addItem(_('Random'), 'Random')
        self.cmbZoom.addItem(_('Zoom In'), 'Zoom In')
        self.cmbZoom.addItem(_('Zoom Out'), 'Zoom Out')

        # Add all transitions
        transitions_dir = os.path.join(info.PATH, "transitions")
        common_dir = os.path.join(transitions_dir, "common")
        extra_dir = os.path.join(transitions_dir, "extra")
        transition_groups = [{
            "type": "common",
            "dir": common_dir,
            "files": os.listdir(common_dir)
        }, {
            "type": "extra",
            "dir": extra_dir,
            "files": os.listdir(extra_dir)
        }]

        self.cmbTransition.addItem(_('None'), None)
        self.cmbTransition.addItem(_('Random'), 'random')
        self.transitions = []
        for group in transition_groups:
            type = group["type"]
            dir = group["dir"]
            files = group["files"]

            for filename in sorted(files):
                path = os.path.join(dir, filename)
                (fileBaseName, fileExtension) = os.path.splitext(filename)

                # Skip hidden files (such as .DS_Store, etc...)
                if filename[0] == "." or "thumbs.db" in filename.lower():
                    continue

                # split the name into parts (looking for a number)
                suffix_number = None
                name_parts = fileBaseName.split("_")
                if name_parts[-1].isdigit():
                    suffix_number = name_parts[-1]

                # get name of transition
                trans_name = fileBaseName.replace("_", " ").capitalize()

                # replace suffix number with placeholder (if any)
                if suffix_number:
                    trans_name = trans_name.replace(suffix_number, "%s")
                    trans_name = _(trans_name) % suffix_number
                else:
                    trans_name = _(trans_name)

                # Check for thumbnail path (in build-in cache)
                thumb_path = os.path.join(info.IMAGES_PATH, "cache",
                                          "{}.png".format(fileBaseName))

                # Check built-in cache (if not found)
                if not os.path.exists(thumb_path):
                    # Check user folder cache
                    thumb_path = os.path.join(info.CACHE_PATH,
                                              "{}.png".format(fileBaseName))

                # Add item
                self.transitions.append(path)
                self.cmbTransition.addItem(QIcon(thumb_path), _(trans_name),
                                           path)

        # Connections
        self.btnMoveUp.clicked.connect(self.btnMoveUpClicked)
        self.btnMoveDown.clicked.connect(self.btnMoveDownClicked)
        self.btnShuffle.clicked.connect(self.btnShuffleClicked)
        self.btnRemove.clicked.connect(self.btnRemoveClicked)
        self.btnBox.accepted.connect(self.accept)
        self.btnBox.rejected.connect(self.reject)

        # Update total
        self.updateTotal()
Example #50
0
    def __init__(self):

        # Create dialog class
        QDialog.__init__(self)

        # Load UI from designer
        ui_util.load_ui(self, self.ui_path)

        # Init UI
        ui_util.init_ui(self)

        # get translations
        app = get_app()
        _ = app._tr

        # Get settings
        self.s = settings.get_settings()

        # Dynamically load tabs from settings data
        self.settings_data = settings.get_settings().get_all_settings()

        # Track metrics
        track_metric_screen("preferences-screen")

        # Load all user values
        self.params = {}
        for item in self.settings_data:
            if "setting" in item and "value" in item:
                self.params[item["setting"]] = item

        self.requires_restart = False
        self.category_names = {}
        self.category_tabs = {}
        self.category_sort = {}

        # Loop through settings and find all unique categories
        for item in self.settings_data:
            category = item.get("category")
            setting_type = item.get("type")
            sort_category = item.get("sort")

            # Indicate sorted category
            if sort_category:
                self.category_sort[category] = sort_category

            if not setting_type == "hidden":
                # Load setting
                if not category in self.category_names:
                    self.category_names[category] = []

                    # Create scrollarea
                    scroll_area = QScrollArea(self)
                    scroll_area.setWidgetResizable(True)
                    scroll_area.setVerticalScrollBarPolicy(
                        Qt.ScrollBarAsNeeded)
                    scroll_area.setSizePolicy(QSizePolicy.Expanding,
                                              QSizePolicy.Expanding)

                    # Create tab widget and layout
                    layout = QVBoxLayout()
                    tabWidget = QWidget(self)
                    tabWidget.setSizePolicy(QSizePolicy.Preferred,
                                            QSizePolicy.Preferred)
                    tabWidget.setLayout(layout)
                    scroll_area.setWidget(tabWidget)

                    # Add tab
                    self.tabCategories.addTab(scroll_area, _(category))
                    self.category_tabs[category] = tabWidget

                # Append translated title
                item["title_tr"] = _(item.get("title"))

                # Append settings into correct category
                self.category_names[category].append(item)

        # Loop through each category setting, and add them to the tabs
        for category in self.category_tabs.keys():
            tabWidget = self.category_tabs[category]

            # Get list of items in category
            params = self.category_names[category]
            if self.category_sort.get(category):
                # Sort this category by translated title
                params.sort(key=operator.itemgetter("title_tr"))

            # Loop through settings for each category
            for param in params:

                # Create Label
                widget = None
                extraWidget = None
                label = QLabel()
                label.setText(_(param["title"]))
                label.setToolTip(_(param["title"]))

                if param["type"] == "spinner":
                    # create QDoubleSpinBox
                    widget = QDoubleSpinBox()
                    widget.setMinimum(float(param["min"]))
                    widget.setMaximum(float(param["max"]))
                    widget.setValue(float(param["value"]))
                    widget.setSingleStep(1.0)
                    widget.setToolTip(param["title"])
                    widget.valueChanged.connect(
                        functools.partial(self.spinner_value_changed, param))

                if param["type"] == "spinner-int":
                    # create QDoubleSpinBox
                    widget = QSpinBox()
                    widget.setMinimum(int(param["min"]))
                    widget.setMaximum(int(param["max"]))
                    widget.setValue(int(param["value"]))
                    widget.setSingleStep(1.0)
                    widget.setToolTip(param["title"])
                    widget.valueChanged.connect(
                        functools.partial(self.spinner_value_changed, param))

                elif param["type"] == "text":
                    # create QLineEdit
                    widget = QLineEdit()
                    widget.setText(_(param["value"]))
                    widget.textChanged.connect(
                        functools.partial(self.text_value_changed, widget,
                                          param))

                elif param["type"] == "browse":
                    # create QLineEdit
                    widget = QLineEdit()
                    widget.setText(_(param["value"]))
                    widget.textChanged.connect(
                        functools.partial(self.text_value_changed, widget,
                                          param))
                    extraWidget = QPushButton(_("Browse..."))
                    extraWidget.clicked.connect(
                        functools.partial(self.selectExecutable, widget,
                                          param))

                elif param["type"] == "bool":
                    # create spinner
                    widget = QCheckBox()
                    if param["value"] == True:
                        widget.setCheckState(Qt.Checked)
                    else:
                        widget.setCheckState(Qt.Unchecked)
                    widget.stateChanged.connect(
                        functools.partial(self.bool_value_changed, widget,
                                          param))

                elif param["type"] == "dropdown":

                    # create spinner
                    widget = QComboBox()

                    # Get values
                    value_list = param["values"]
                    # Overwrite value list (for profile dropdown)
                    if param["setting"] == "default-profile":
                        value_list = []
                        # Loop through profiles
                        for profile_folder in [
                                info.USER_PROFILES_PATH, info.PROFILES_PATH
                        ]:
                            for file in os.listdir(profile_folder):
                                # Load Profile and append description
                                profile_path = os.path.join(
                                    profile_folder, file)
                                profile = openshot.Profile(profile_path)
                                value_list.append({
                                    "name":
                                    profile.info.description,
                                    "value":
                                    profile.info.description
                                })
                        # Sort profile list
                        value_list.sort(key=operator.itemgetter("name"))

                    # Overwrite value list (for language dropdown)
                    if param["setting"] == "default-language":
                        value_list = []
                        # Loop through languages
                        for locale, language, country in get_all_languages():
                            # Load Profile and append description
                            if language:
                                lang_name = "%s (%s)" % (language, locale)
                                value_list.append({
                                    "name": lang_name,
                                    "value": locale
                                })
                        # Sort profile list
                        value_list.sort(key=operator.itemgetter("name"))
                        # Add Default to top of list
                        value_list.insert(0, {
                            "name": _("Default"),
                            "value": "Default"
                        })

                    # Add normal values
                    box_index = 0
                    for value_item in value_list:
                        k = value_item["name"]
                        v = value_item["value"]
                        # add dropdown item
                        widget.addItem(_(k), v)

                        # select dropdown (if default)
                        if v == param["value"]:
                            widget.setCurrentIndex(box_index)
                        box_index = box_index + 1

                    widget.currentIndexChanged.connect(
                        functools.partial(self.dropdown_index_changed, widget,
                                          param))

                # Add Label and Widget to the form
                if (widget and label):
                    # Add minimum size
                    label.setMinimumWidth(180)
                    label.setSizePolicy(QSizePolicy.Preferred,
                                        QSizePolicy.Preferred)
                    widget.setSizePolicy(QSizePolicy.Expanding,
                                         QSizePolicy.Preferred)

                    # Create HBox layout
                    layout_hbox = QHBoxLayout()
                    layout_hbox.addWidget(label)
                    layout_hbox.addWidget(widget)

                    if (extraWidget):
                        layout_hbox.addWidget(extraWidget)

                    # Add widget to layout
                    tabWidget.layout().addLayout(layout_hbox)
                elif (label):
                    # Add widget to layout
                    tabWidget.layout().addWidget(label)

            # Add stretch to bottom of layout
            tabWidget.layout().addStretch()
Example #51
0
    def __init__(self):

        # Create dialog class
        QDialog.__init__(self)

        # Load UI from designer
        ui_util.load_ui(self, self.ui_path)

        # Init UI
        ui_util.init_ui(self)

        # get translations
        app = get_app()
        _ = app._tr

        # Get settings
        self.s = settings.get_settings()

        # Dynamically load tabs from settings data
        self.settings_data = settings.get_settings().get_all_settings()

        # Add buttons to interface
        self.export_button = QPushButton(_('Export Video'))
        self.buttonBox.addButton(self.export_button, QDialogButtonBox.AcceptRole)
        self.buttonBox.addButton(QPushButton(_('Cancel')), QDialogButtonBox.RejectRole)
        self.exporting = False

        # Default export path
        recommended_path = recommended_path = os.path.join(info.HOME_PATH)
        if app.project.current_filepath:
            recommended_path = os.path.dirname(app.project.current_filepath)

        export_path = get_app().project.get(["export_path"])
        if os.path.exists(export_path):
            # Use last selected export path
            self.txtExportFolder.setText(export_path)
        else:
            # Default to home dir
            self.txtExportFolder.setText(recommended_path)

        # Is this a saved project?
        if not get_app().project.current_filepath:
            # Not saved yet
            self.txtFileName.setText(_("Untitled Project"))
        else:
            # Yes, project is saved
            # Get just the filename
            parent_path, filename = os.path.split(get_app().project.current_filepath)
            filename, ext = os.path.splitext(filename)
            self.txtFileName.setText(filename.replace("_", " ").replace("-", " ").capitalize())

        # Default image type
        self.txtImageFormat.setText("%05.png")

        # Loop through Export To options
        export_options = [_("Video & Audio"), _("Image Sequence")]
        for option in export_options:
            # append profile to list
            self.cboExportTo.addItem(option)

        # Connect signals
        self.btnBrowse.clicked.connect(functools.partial(self.btnBrowse_clicked))
        self.cboSimpleProjectType.currentIndexChanged.connect(
            functools.partial(self.cboSimpleProjectType_index_changed, self.cboSimpleProjectType))
        self.cboProfile.currentIndexChanged.connect(functools.partial(self.cboProfile_index_changed, self.cboProfile))
        self.cboSimpleTarget.currentIndexChanged.connect(
            functools.partial(self.cboSimpleTarget_index_changed, self.cboSimpleTarget))
        self.cboSimpleVideoProfile.currentIndexChanged.connect(
            functools.partial(self.cboSimpleVideoProfile_index_changed, self.cboSimpleVideoProfile))
        self.cboSimpleQuality.currentIndexChanged.connect(
            functools.partial(self.cboSimpleQuality_index_changed, self.cboSimpleQuality))


        # ********* Advaned Profile List **********
        # Loop through profiles
        self.profile_names = []
        self.profile_paths = {}
        for file in os.listdir(info.PROFILES_PATH):
            # Load Profile
            profile_path = os.path.join(info.PROFILES_PATH, file)
            profile = openshot.Profile(profile_path)

            # Add description of Profile to list
            self.profile_names.append(profile.info.description)
            self.profile_paths[profile.info.description] = profile_path

        # Sort list
        self.profile_names.sort()

        # Loop through sorted profiles
        box_index = 0
        self.selected_profile_index = 0
        for profile_name in self.profile_names:

            # Add to dropdown
            self.cboProfile.addItem(profile_name, self.profile_paths[profile_name])

            # Set default (if it matches the project)
            if app.project.get(['profile']) == profile_name:
                self.selected_profile_index = box_index

            # increment item counter
            box_index += 1


        # ********* Simple Project Type **********
        # load the simple project type dropdown
        presets = []
        for file in os.listdir(info.EXPORT_PRESETS_DIR):
            xmldoc = xml.parse(os.path.join(info.EXPORT_PRESETS_DIR, file))
            type = xmldoc.getElementsByTagName("type")
            presets.append(_(type[0].childNodes[0].data))

        # Exclude duplicates
        presets = list(set(presets))
        for item in sorted(presets):
            self.cboSimpleProjectType.addItem(item, item)

        # Populate all profiles
        self.populateAllProfiles(app.project.get(['profile']))

        # Connect framerate signals
        self.txtFrameRateNum.valueChanged.connect(self.updateFrameRate)
        self.txtFrameRateDen.valueChanged.connect(self.updateFrameRate)
        self.txtWidth.valueChanged.connect(self.updateFrameRate)
        self.txtHeight.valueChanged.connect(self.updateFrameRate)
        self.txtSampleRate.valueChanged.connect(self.updateFrameRate)
        self.txtChannels.valueChanged.connect(self.updateFrameRate)

        # Determine the length of the timeline (in frames)
        self.updateFrameRate()
Example #52
0
from copy import deepcopy
from classes import info
from classes import language
from classes.logger import log
from classes import settings
import openshot

from PyQt5.QtCore import QT_VERSION_STR
from PyQt5.Qt import PYQT_VERSION_STR


# Get libopenshot version
libopenshot_version = openshot.GetVersion()

# Get settings
s = settings.get_settings()

# Determine OS version
os_version = "X11; Linux %s" % platform.machine()
linux_distro = "None"
try:
    if platform.system() == "Darwin":
        v = platform.mac_ver()
        os_version = "Macintosh; Intel Mac OS X %s" % v[0].replace(".", "_")
        linux_distro = "OS X %s" % v[0]

    elif platform.system() == "Windows":
        v = platform.win32_ver()
        # TODO: Upgrade windows python (on build server) version to 3.5, so it correctly identifies Windows 10
        os_version = "Windows NT %s; %s" % (v[0], v[1])
        linux_distro = "Windows %s" % "-".join(platform.win32_ver())
Example #53
0
    def LoadFile(self, path=None):
        """ Load a media file into the video player """
        s = settings.get_settings()

        # Check to see if this path is already loaded
        # TODO: Determine why path is passed in as an empty string instead of None
        if path == self.clip_path or (not path and not self.clip_path):
            return

        # Determine the current frame of the timeline (when switching to a clip)
        seek_position = 1
        if path and not self.clip_path:
            # Track the current frame
            self.original_position = self.player.Position()

        # Stop player (very important to prevent crashing)
        self.original_speed = self.player.Speed()
        self.player.Speed(0)

        # If blank path, switch back to self.timeline reader
        if not path:
            # Return to self.timeline reader
            log.info("Set timeline reader again in player: %s" % self.timeline)
            self.player.Reader(self.timeline)

            # Clear clip reader reference
            self.clip_reader = None
            self.clip_path = None

            # Switch back to last timeline position
            seek_position = self.original_position
        else:
            # Get extension of media path
            ext = os.path.splitext(path)

            # Load Reader based on extension
            new_reader = None
            if ext in [
                    '.avi', 'mov', 'mkv', 'mpg', 'mpeg', 'mp3', 'mp4', 'mts',
                    'ogg', 'wav', 'wmv', 'webm', 'vob'
            ]:
                try:
                    new_reader = openshot.FFmpegReader(path)
                    new_reader.Open()
                except:
                    try:
                        new_reader = openshot.QtImageReader(path)
                        new_reader.Open()
                    except:
                        log.error(
                            'Failed to load media file into video player: %s' %
                            path)
                        return
            else:
                try:
                    new_reader = openshot.QtImageReader(path)
                    new_reader.Open()
                except:
                    try:
                        new_reader = openshot.FFmpegReader(path)
                        new_reader.Open()
                    except:
                        log.error(
                            'Failed to load media file into video player: %s' %
                            path)
                        return

            # Wrap reader in FrameMapper (to match current settings of timeline)
            new_mapper = openshot.FrameMapper(
                new_reader, self.timeline.info.fps, openshot.PULLDOWN_NONE,
                self.timeline.info.sample_rate, self.timeline.info.channels,
                self.timeline.info.channel_layout)

            # Keep track of previous clip readers (so we can Close it later)
            self.previous_clip_mappers.append(new_mapper)
            self.previous_clip_readers.append(new_reader)

            # Assign new clip_reader
            self.clip_reader = new_mapper
            self.clip_path = path

            # Open reader
            self.clip_reader.Open()

            log.info("Set new FrameMapper reader in player: %s" %
                     self.clip_reader)
            self.player.Reader(self.clip_reader)

        # Close and destroy old clip readers (leaving the 3 most recent)
        while len(self.previous_clip_readers) > 3:
            log.info('Removing old clip reader: %s' %
                     self.previous_clip_readers[0])
            self.previous_clip_mappers.pop(0)
            self.previous_clip_readers.pop(0)

        # Seek to frame 1, and resume speed
        self.player.Seek(seek_position)
        self.player.Speed(self.original_speed)
Example #54
0
    def __init__(self, id, text, arrow, *args):
        # Invoke parent init
        QWidget.__init__(self, *args)

        # get translations
        app = get_app()
        _ = app._tr

        # Keep track of widget to position next to
        self.id = id
        self.arrow = arrow

        # Create vertical box
        vbox = QVBoxLayout()
        vbox.setContentsMargins(32, 10, 10, 10)

        # Add label
        self.label = QLabel(self)
        self.label.setText(text)
        self.label.setTextFormat(Qt.RichText)
        self.label.setWordWrap(True)
        self.label.setStyleSheet("margin-left: 20px;")
        vbox.addWidget(self.label)

        # Add error and anonymous metrics checkbox (for ID=0) tooltip
        # This is a bit of a hack, but since it's the only exception, it's
        # probably okay for now.
        if self.id == "0":
            # Get settings
            s = get_settings()

            # create spinner
            checkbox_metrics = QCheckBox()
            checkbox_metrics.setText(
                _("Yes, I would like to improve OpenShot!"))
            checkbox_metrics.setStyleSheet(
                "margin-left: 25px; margin-bottom: 5px;")
            if s.get("send_metrics"):
                checkbox_metrics.setCheckState(Qt.Checked)
            else:
                checkbox_metrics.setCheckState(Qt.Unchecked)
            checkbox_metrics.stateChanged.connect(
                functools.partial(self.checkbox_metrics_callback))
            vbox.addWidget(checkbox_metrics)

        # Add button box
        hbox = QHBoxLayout()
        hbox.setContentsMargins(20, 10, 0, 0)

        # Create buttons
        self.btn_close_tips = QPushButton(self)
        self.btn_close_tips.setText(_("Hide Tutorial"))
        self.btn_next_tip = QPushButton(self)
        self.btn_next_tip.setText(_("Next"))
        self.btn_next_tip.setStyleSheet("font-weight:bold;")
        hbox.addWidget(self.btn_close_tips)
        hbox.addWidget(self.btn_next_tip)
        vbox.addLayout(hbox)

        # Set layout
        self.setLayout(vbox)

        # Set size
        self.setMinimumWidth(350)
        self.setMinimumHeight(100)

        # Make transparent
        self.setAttribute(Qt.WA_NoSystemBackground, True)
        self.setAttribute(Qt.WA_TranslucentBackground, True)
Example #55
0
def init_language():
    """ Find the current locale, and install the correct translators """

    # Get app instance
    app = QCoreApplication.instance()

    # Setup of our list of translators and paths
    translator_types = (
        {"type": 'QT',
         "pattern": 'qt_%s',        # Older versions of Qt use this file (built-in translations)
         "path": QLibraryInfo.location(QLibraryInfo.TranslationsPath)},
        {"type": 'QT',
         "pattern": 'qtbase_%s',    # Newer versions of Qt use this file (built-in translations)
         "path": QLibraryInfo.location(QLibraryInfo.TranslationsPath)},
        {"type": 'QT',
         "pattern": 'qt_%s',
         "path": os.path.join(info.PATH, 'locale', 'QT')}, # Optional path where we package QT translations
        {"type": 'QT',
         "pattern": 'qtbase_%s',
         "path": os.path.join(info.PATH, 'locale', 'QT')}, # Optional path where we package QT translations
        {"type": 'OpenShot',
         "pattern": os.path.join('%s', 'LC_MESSAGES', 'OpenShot'),  # Our custom translations
         "path": os.path.join(info.PATH, 'locale')},
    )

    # Determine the environment locale, or default to system locale name
    locale_names = [os.environ.get('LANG', QLocale().system().name()),
                    os.environ.get('LOCALE', QLocale().system().name())
                    ]

    # Determine if the user has overwritten the language (in the preferences)
    preference_lang = settings.get_settings().get('default-language')
    if preference_lang != "Default":
        # Append preference lang to top of list
        locale_names.insert(0, preference_lang)

    # Output all system languages detected
    log.info("Qt Detected Languages: {}".format(QLocale().system().uiLanguages()))
    log.info("LANG Environment Variable: {}".format(os.environ.get('LANG', QLocale().system().name())))
    log.info("LOCALE Environment Variable: {}".format(os.environ.get('LOCALE', QLocale().system().name())))

    # Default the locale to C, for number formatting
    locale.setlocale(locale.LC_ALL, 'C')

    # Loop through environment variables
    found_language = False
    for locale_name in locale_names:

        # Don't try on default locale, since it fails to load what is the default language
        if 'en_US' in locale_name:
            log.info("Skipping English language (no need for translation): {}".format(locale_name))
            continue

        # Go through each translator and try to add for current locale
        for type in translator_types:
            trans = QTranslator(app)
            if find_language_match(type["pattern"], type["path"], trans, locale_name):
                # Install translation
                app.installTranslator(trans)
                found_language = True

        # Exit if found language
        if found_language:
            log.info("Exiting translation system (since we successfully loaded: {})".format(locale_name))
            break
Example #56
0
    def LoadFile(self, path=None):
        """ Load a media file into the video player """
        # Check to see if this path is already loaded
        # TODO: Determine why path is passed in as an empty string instead of None
        if path == self.clip_path or (not path and not self.clip_path):
            return

        log.info("LoadFile %s" % path)
        s = settings.get_settings()

        # Determine the current frame of the timeline (when switching to a clip)
        seek_position = 1
        if path and not self.clip_path:
            # Track the current frame
            self.original_position = self.player.Position()

        # If blank path, switch back to self.timeline reader
        if not path:
            # Return to self.timeline reader
            log.info("Set timeline reader again in player: %s" % self.timeline)
            self.player.Reader(self.timeline)

            # Clear clip reader reference
            self.clip_reader = None
            self.clip_path = None

            # Switch back to last timeline position
            seek_position = self.original_position
        else:
            # Get extension of media path
            ext = os.path.splitext(path)

            # Create new timeline reader (to preview selected clip)
            s = settings.get_settings()
            project = get_app().project

            # Get some settings from the project
            fps = project.get(["fps"])
            width = project.get(["width"])
            height = project.get(["height"])
            sample_rate = project.get(["sample_rate"])
            channels = project.get(["channels"])
            channel_layout = project.get(["channel_layout"])

            # Create an instance of a libopenshot Timeline object
            self.clip_reader = openshot.Timeline(
                width, height, openshot.Fraction(fps["num"], fps["den"]),
                sample_rate, channels, channel_layout)
            self.clip_reader.info.channel_layout = channel_layout
            self.clip_reader.info.has_audio = True
            self.clip_reader.info.has_video = True
            self.clip_reader.info.video_length = 999999
            self.clip_reader.info.duration = 999999
            self.clip_reader.info.sample_rate = sample_rate
            self.clip_reader.info.channels = channels

            try:
                # Add clip for current preview file
                new_clip = openshot.Clip(path)
                self.clip_reader.AddClip(new_clip)
            except:
                log.error('Failed to load media file into video player: %s' %
                          path)
                return

            # Assign new clip_reader
            self.clip_path = path

            # Keep track of previous clip readers (so we can Close it later)
            self.previous_clips.append(new_clip)
            self.previous_clip_readers.append(self.clip_reader)

            # Open and set reader
            self.clip_reader.Open()
            self.player.Reader(self.clip_reader)

        # Close and destroy old clip readers (leaving the 3 most recent)
        while len(self.previous_clip_readers) > 3:
            log.info('Removing old clips from preview: %s' %
                     self.previous_clip_readers[0])
            previous_clip = self.previous_clips.pop(0)
            previous_clip.Close()
            previous_reader = self.previous_clip_readers.pop(0)
            previous_reader.Close()

        # Seek to frame 1, and resume speed
        self.Seek(seek_position)
Example #57
0
def init_language():
    """ Find the current locale, and install the correct translators """

    # Get app instance
    app = QCoreApplication.instance()

    # Setup of our list of translators and paths
    translator_types = (
        {
            "type": 'QT',
            "prefix":
            'qt_',  # Older versions of Qt use this file (built-in translations)
            "path": QLibraryInfo.location(QLibraryInfo.TranslationsPath)
        },
        {
            "type": 'QT',
            "prefix":
            'qtbase_',  # Newer versions of Qt use this file (built-in translations)
            "path": QLibraryInfo.location(QLibraryInfo.TranslationsPath)
        },
        {
            "type": 'QT',
            "prefix": 'qt_',
            "path": os.path.join(info.PATH, 'language')
        },  # Optional path where we package QT translations
        {
            "type": 'QT',
            "prefix": 'qtbase_',
            "path": os.path.join(info.PATH, 'language')
        },  # Optional path where we package QT translations
        {
            "type": 'OpenShot',
            "prefix": 'OpenShot.',  # Our custom translations
            "path": language_path
        },
    )

    # Determine the environment locale, or default to system locale name
    locale_names = [
        os.environ.get('LANG',
                       QLocale().system().name()),
        os.environ.get('LOCALE',
                       QLocale().system().name())
    ]

    # Get the user's configured language preference
    preference_lang = settings.get_settings().get('default-language')

    # Output all languages detected from various sources
    log.info("Qt Detected Languages: {}".format(
        QLocale().system().uiLanguages()))
    log.info("LANG Environment Variable: {}".format(os.environ.get('LANG',
                                                                   "")))
    log.info("LOCALE Environment Variable: {}".format(
        os.environ.get('LOCALE', "")))
    log.info("OpenShot Preference Language: {}".format(preference_lang))

    # Check if the language preference is something other than "Default"
    if preference_lang == "en_US":
        # Override language list with en_US, don't add to it
        locale_names = ["en_US"]
    elif preference_lang != "Default":
        # Prepend preference setting to list
        locale_names.insert(0, preference_lang)

    # If the user has used the --lang command line arg, override with that
    # (We've already checked that it's in SUPPORTED_LANGUAGES)
    if info.CMDLINE_LANGUAGE:
        locale_names = [info.CMDLINE_LANGUAGE]
        log.info("Language overridden on command line, using: {}".format(
            info.CMDLINE_LANGUAGE))

    # Default the locale to C, for number formatting
    locale.setlocale(locale.LC_ALL, 'C')

    # Loop through environment variables
    found_language = False
    for locale_name in locale_names:

        # Go through each translator and try to add for current locale
        for type in translator_types:
            trans = QTranslator(app)
            if find_language_match(type["prefix"], type["path"], trans,
                                   locale_name):
                # Install translation
                app.installTranslator(trans)
                found_language = True

        # Exit if found language for type: "OpenShot"
        if found_language:
            log.debug(
                "Exiting translation system (since we successfully loaded: {})"
                .format(locale_name))
            info.CURRENT_LANGUAGE = locale_name
            break
Example #58
0
    def __init__(self):

        # Create main window base class
        QMainWindow.__init__(self)

        # set window on app for reference during initialization of children
        get_app().window = self

        # Load UI from designer
        ui_util.load_ui(self, self.ui_path)

        # Load user settings for window
        s = settings.get_settings()
        self.recent_menu = None

        # Init UI
        ui_util.init_ui(self)

        # Setup toolbars that aren't on main window, set initial state of items, etc
        self.setup_toolbars()

        # Add window as watcher to receive undo/redo status updates
        get_app().updates.add_watcher(self)

        # Track the selected file(s)
        self.selected_files = []
        self.selected_clips = []
        self.selected_transitions = []
        self.selected_markers = []
        self.selected_tracks = []
        self.selected_effects = []

        # Init fullscreen menu visibility
        self.init_fullscreen_menu()

        # Setup timeline
        self.timeline = TimelineWebView(self)
        self.frameWeb.layout().addWidget(self.timeline)

        # Set Window title
        self.SetWindowTitle()

        # Setup files tree
        if s.get("file_view") == "details":
            self.filesTreeView = FilesTreeView(self)
        else:
            self.filesTreeView = FilesListView(self)
        self.tabFiles.layout().addWidget(self.filesTreeView)

        # Setup transitions tree
        if s.get("transitions_view") == "details":
            self.transitionsTreeView = TransitionsTreeView(self)
        else:
            self.transitionsTreeView = TransitionsListView(self)
        self.tabTransitions.layout().addWidget(self.transitionsTreeView)

        # Setup effects tree
        if s.get("effects_view") == "details":
            self.effectsTreeView = EffectsTreeView(self)
        else:
            self.effectsTreeView = EffectsListView(self)
        self.tabEffects.layout().addWidget(self.effectsTreeView)

        # Setup properties table
        self.propertyTableView = PropertiesTableView(self)
        self.dockPropertiesContent.layout().addWidget(self.propertyTableView, 3, 1)

        # Setup video preview QWidget
        self.videoPreview = VideoWidget()
        self.tabVideo.layout().insertWidget(0, self.videoPreview)

        # Load window state and geometry
        self.load_settings()

        # Create the timeline sync object (used for previewing timeline)
        self.timeline_sync = TimelineSync()

        # Start the preview thread
        self.preview_parent = PreviewParent()
        self.preview_parent.Init(self, self.timeline_sync.timeline)
        self.preview_thread = self.preview_parent.worker