Exemplo n.º 1
0
    def cboProfile_index_changed(self, widget, index):
        selected_profile_path = widget.itemData(index)
        log.info(selected_profile_path)

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

        # Load profile
        profile = openshot.Profile(selected_profile_path)

        # Load profile settings into advanced editor
        self.txtWidth.setValue(profile.info.width)
        self.txtHeight.setValue(profile.info.height)
        self.txtFrameRateNum.setValue(profile.info.fps.num)
        self.txtFrameRateDen.setValue(profile.info.fps.den)
        self.txtAspectRatioNum.setValue(profile.info.display_ratio.num)
        self.txtAspectRatioDen.setValue(profile.info.display_ratio.den)
        self.txtPixelRatioNum.setValue(profile.info.pixel_ratio.num)
        self.txtPixelRatioDen.setValue(profile.info.pixel_ratio.den)

        # Load the interlaced options
        self.cboInterlaced.clear()
        self.cboInterlaced.addItem(_("Yes"), "Yes")
        self.cboInterlaced.addItem(_("No"), "No")
        if profile.info.interlaced_frame:
            self.cboInterlaced.setCurrentIndex(0)
        else:
            self.cboInterlaced.setCurrentIndex(1)
Exemplo n.º 2
0
    def dropdown_index_changed(self, widget, index):
        # Get profile path
        value = self.cboProfile.itemData(index)
        log.info(value)

        # Load profile
        profile = openshot.Profile(value)

        # Set labels
        self.lblSize.setText("%sx%s" %
                             (profile.info.width, profile.info.height))
        self.lblFPS.setText("%0.2f" %
                            (profile.info.fps.num / profile.info.fps.den))
        self.lblOther.setText(
            "DAR: %s/%s, SAR: %s/%s, Interlaced: %s" %
            (profile.info.display_ratio.num, profile.info.display_ratio.den,
             profile.info.pixel_ratio.num, profile.info.pixel_ratio.den,
             profile.info.interlaced_frame))

        # Update timeline settings
        get_app().updates.update(["profile"], profile.info.description)
        get_app().updates.update(["width"], profile.info.width)
        get_app().updates.update(["height"], profile.info.height)
        get_app().updates.update(["fps"], {
            "num": profile.info.fps.num,
            "den": profile.info.fps.den
        })

        # Force ApplyMapperToClips to apply these changes
        get_app().window.timeline_sync.timeline.ApplyMapperToClips()

        # Update Window Title
        get_app().window.SetWindowTitle(profile.info.description)
Exemplo n.º 3
0
    def dropdown_activated(self, index):
        # Ignore if the selection wasn't changed
        if index == self.initial_index:
            return

        win = get_app().window
        proj = get_app().project
        updates = get_app().updates

        # Get profile path & load
        value = self.cboProfile.itemData(index)
        profile = openshot.Profile(value)

        # Get current FPS (prior to changing)
        current_fps = proj.get("fps")
        current_fps_float = float(current_fps["num"]) / float(
            current_fps["den"])
        fps_factor = float(profile.info.fps.ToFloat() / current_fps_float)

        # Update timeline settings
        updates.update(["profile"], profile.info.description)
        updates.update(["width"], profile.info.width)
        updates.update(["height"], profile.info.height)
        updates.update(["fps"], {
            "num": profile.info.fps.num,
            "den": profile.info.fps.den,
        })
        updates.update(
            ["display_ratio"], {
                "num": profile.info.display_ratio.num,
                "den": profile.info.display_ratio.den,
            })
        updates.update(
            ["pixel_ratio"], {
                "num": profile.info.pixel_ratio.num,
                "den": profile.info.pixel_ratio.den,
            })

        # Rescale all keyframes and reload project
        if fps_factor != 1.0:
            # Get a copy of rescaled project data (this does not modify the active project... yet)
            rescaled_app_data = proj.rescale_keyframes(fps_factor)

            # Apply rescaled data to active project
            proj._data = rescaled_app_data

            # Distribute all project data through update manager
            updates.load(rescaled_app_data)

        # Force ApplyMapperToClips to apply these changes
        win.timeline_sync.timeline.ApplyMapperToClips()

        # Update Window Title and stored index
        win.SetWindowTitle(profile.info.description)
        self.initial_index = index

        # Reset the playhead position (visually it moves anyway)
        win.SeekSignal.emit(1)
        # Refresh frame (since size of preview might have changed)
        QTimer.singleShot(500, win.refreshFrameSignal.emit)
Exemplo n.º 4
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)
Exemplo n.º 5
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
Exemplo n.º 6
0
    def dropdown_index_changed(self, widget, index):
        # Get profile path
        value = self.cboProfile.itemData(index)
        log.info(value)

        # Load profile
        profile = openshot.Profile(value)

        # Set labels
        self.lblSize.setText("%sx%s" %
                             (profile.info.width, profile.info.height))
        self.lblFPS.setText("%0.2f" %
                            (profile.info.fps.num / profile.info.fps.den))
        self.lblOther.setText(
            "DAR: %s/%s, SAR: %s/%s, Interlaced: %s" %
            (profile.info.display_ratio.num, profile.info.display_ratio.den,
             profile.info.pixel_ratio.num, profile.info.pixel_ratio.den,
             profile.info.interlaced_frame))

        # Get current FPS (prior to changing)
        current_fps = get_app().project.get(["fps"])
        current_fps_float = float(current_fps["num"]) / float(
            current_fps["den"])
        new_fps_float = float(profile.info.fps.num) / float(
            profile.info.fps.den)
        fps_factor = new_fps_float / current_fps_float

        # Update timeline settings
        get_app().updates.update(["profile"], profile.info.description)
        get_app().updates.update(["width"], profile.info.width)
        get_app().updates.update(["height"], profile.info.height)
        get_app().updates.update(["fps"], {
            "num": profile.info.fps.num,
            "den": profile.info.fps.den
        })

        # Rescale all keyframes and reload project
        if fps_factor != 1.0:
            get_app().project.rescale_keyframes(fps_factor)

        # Force ApplyMapperToClips to apply these changes
        get_app().window.timeline_sync.timeline.ApplyMapperToClips()

        # Update Window Title
        get_app().window.SetWindowTitle(profile.info.description)

        # Update max size (to size of video preview viewport)
        viewport_rect = get_app().window.videoPreview.centeredViewport(
            get_app().window.videoPreview.width(),
            get_app().window.videoPreview.height())
        get_app().window.timeline_sync.timeline.SetMaxSize(
            viewport_rect.width(), viewport_rect.height())

        # Refresh frame (since size of preview might have changed)
        QTimer.singleShot(500, get_app().window.refreshFrameSignal.emit)
Exemplo n.º 7
0
    def dropdown_index_changed(self, index):
        # Get profile path
        value = self.cboProfile.itemData(index)

        # Load profile
        profile = openshot.Profile(value)

        # Set labels
        self.lblSize.setText("%sx%s" %
                             (profile.info.width, profile.info.height))
        self.lblFPS.setText("%0.2f" %
                            (profile.info.fps.num / profile.info.fps.den))
        self.lblOther.setText(
            "DAR: %s/%s, SAR: %s/%s, Interlaced: %s" %
            (profile.info.display_ratio.num, profile.info.display_ratio.den,
             profile.info.pixel_ratio.num, profile.info.pixel_ratio.den,
             profile.info.interlaced_frame))
Exemplo n.º 8
0
    def dropdown_index_changed(self, index):
        # Get profile path
        value = self.cboProfile.itemData(index)

        # Load profile
        profile = openshot.Profile(value)

        # Set labels
        self.lblSize.setText("%sx%s" %
                             (profile.info.width, profile.info.height))
        self.lblFPS.setText("%0.2f" % (profile.info.fps.ToFloat()))
        # (Note: Takes advantage of openshot.Fraction's __string__ method
        # which outputs the value with the format "{num}:{den}")
        self.lblOther.setText(
            "DAR: %s, SAR: %s, Interlaced: %s" %
            (profile.info.display_ratio, profile.info.pixel_ratio,
             profile.info.interlaced_frame))
Exemplo n.º 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()

        # 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)
Exemplo n.º 10
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()
Exemplo n.º 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()

        # 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()
Exemplo n.º 12
0
    def new(self):
        """ Try to load default project settings file, will raise error on failure """
        import openshot

        # Try to load user default project
        if os.path.exists(info.USER_DEFAULT_PROJECT):
            try:
                self._data = self.read_from_file(info.USER_DEFAULT_PROJECT)
            except (FileNotFoundError, PermissionError) as ex:
                log.warning(
                    "Unable to load user project defaults from {}: {}".format(
                        info.USER_DEFAULT_PROJECT, ex))
            except Exception:
                raise
            else:
                log.info("Loaded user project defaults from {}".format(
                    info.USER_DEFAULT_PROJECT))
        else:
            # Fall back to OpenShot defaults, if user defaults didn't load
            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
                    }
                    self._data["display_ratio"] = {
                        "num": profile.info.display_ratio.num,
                        "den": profile.info.display_ratio.den
                    }
                    self._data["pixel_ratio"] = {
                        "num": profile.info.pixel_ratio.num,
                        "den": profile.info.pixel_ratio.den
                    }
                    break

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

        channels = 2
        channel_layout = openshot.LAYOUT_STEREO
        if default_channel_layout == "LAYOUT_MONO":
            channels = 1
            channel_layout = openshot.LAYOUT_MONO
        elif default_channel_layout == "LAYOUT_STEREO":
            channels = 2
            channel_layout = openshot.LAYOUT_STEREO
        elif default_channel_layout == "LAYOUT_SURROUND":
            channels = 3
            channel_layout = openshot.LAYOUT_SURROUND
        elif default_channel_layout == "LAYOUT_5POINT1":
            channels = 6
            channel_layout = openshot.LAYOUT_5POINT1
        elif default_channel_layout == "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

        # Set default project ID
        self._data["id"] = self.generate_id()
Exemplo n.º 13
0
    def __init__(self):

        # Create dialog class
        QDialog.__init__(self)

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

        # get translations
        _ = get_app()._tr

        # Pause playback (to prevent crash since we are fixing to change the timeline's max size)
        get_app().window.actionPlay_trigger(None, force="pause")

        # Track metrics
        track_metric_screen("profile-screen")

        # Keep track of starting selection
        self.initial_index = 0

        # 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):
                profile_path = os.path.join(profile_folder, file)
                try:
                    # Load Profile
                    profile = openshot.Profile(profile_path)

                    # Add description of Profile to list
                    profile_name = "%s (%sx%s)" % (profile.info.description,
                                                   profile.info.width,
                                                   profile.info.height)
                    self.profile_names.append(profile_name)
                    self.profile_paths[profile_name] = profile_path

                except RuntimeError as e:
                    # This exception occurs when there's a problem parsing the Profile file - display a message and continue
                    log.error("Failed to parse file '%s' as a profile: %s" %
                              (profile_path, e))

        # Sort list
        self.profile_names.sort()

        # Loop through sorted profiles
        box_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 get_app().project.get(['profile']) in profile_name:
                self.initial_index = box_index

            # increment item counter
            box_index += 1

        # Connect signals
        self.cboProfile.currentIndexChanged.connect(
            self.dropdown_index_changed)
        self.cboProfile.activated.connect(self.dropdown_activated)

        # Set current item (from project)
        self.cboProfile.setCurrentIndex(self.initial_index)
Exemplo n.º 14
0
# Try to get the security-patched XML functions from defusedxml
try:
    from defusedxml import minidom as xml
except ImportError:
    from xml.dom import minidom as xml

all_fps = []
all_rates = [
    8000.0, 11025.0, 16000.0, 22050.0, 44100.0, 48000.0, 88200.0, 96000.0,
    176400.0, 192000.0, 3528000.0, 384000.0
]

# Loop through all profiles (include any FPS used in OpenShot)
for file in os.listdir(info.PROFILES_PATH):
    filepath = os.path.join(info.PROFILES_PATH, file)
    profile = openshot.Profile(filepath)
    fps_num = profile.info.fps.num
    fps_den = profile.info.fps.den
    fps = float(fps_num) / float(fps_den)
    if fps not in all_fps:
        all_fps.append(fps)

# Loop through all export presets (include any sample rates used in OpenShot)
for file in os.listdir(info.EXPORT_PRESETS_PATH):
    filepath = os.path.join(info.EXPORT_PRESETS_PATH, file)
    xmldoc = xml.parse(filepath)
    sampleRate = float(
        xmldoc.getElementsByTagName("samplerate")[0].childNodes[0].nodeValue)
    if sampleRate not in all_rates:
        all_rates.append(sampleRate)
Exemplo n.º 15
0
    def Populate(self, filter=""):
        """Populate all preferences and tabs"""

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

        # Delete all tabs and widgets
        self.DeleteAllTabs()

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

        # 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)
                    scroll_area.setMinimumSize(675, 100)

                    # 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 dict(self.category_tabs).keys():
            tabWidget = self.category_tabs[category]
            filterFound = False

            # 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:
                # Is filter found?
                if filter and (filter.lower() in _(param["title"]).lower()
                               or filter.lower() in _(category).lower()):
                    filterFound = True
                elif not filter:
                    filterFound = True
                else:
                    filterFound = False

                # Visible Category
                if filterFound:
                    self.visible_category_names[category] = tabWidget

                # 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" or param["type"] == "browse":
                    # create QLineEdit
                    widget = QLineEdit()
                    widget.setText(_(param["value"]))
                    widget.textChanged.connect(
                        functools.partial(self.text_value_changed, widget,
                                          param))

                    if param["type"] == "browse":
                        # Add filesystem browser button
                        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 audio device list dropdown)
                    if param["setting"] == "playback-audio-device":
                        value_list = []
                        # Loop through audio devices
                        value_list.append({"name": "Default", "value": ""})
                        for audio_device in get_app(
                        ).window.preview_thread.player.GetAudioDeviceNames():
                            value_list.append({
                                "name":
                                "%s: %s" %
                                (audio_device.type, audio_device.name),
                                "value":
                                audio_device.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"
                        })

                    # Overwrite value list (for hardware acceleration modes)
                    os_platform = platform.system()
                    if param["setting"] == "hw-decoder":
                        for value_item in list(value_list):
                            v = value_item["value"]
                            # Remove items that are operating system specific
                            if os_platform == "Darwin" and v not in ("0", "5",
                                                                     "7", "2"):
                                value_list.remove(value_item)
                            elif os_platform == "Windows" and v not in (
                                    "0", "3", "4", "7"):
                                value_list.remove(value_item)
                            elif os_platform == "Linux" and v not in ("0", "1",
                                                                      "2", "6",
                                                                      "7"):
                                value_list.remove(value_item)

                        # Remove hardware mode items which cannot decode the example video
                        for value_item in list(value_list):
                            v = value_item["value"]
                            if not self.testHardwareDecode(v, 0) and \
                                not self.testHardwareDecode(v, 1):
                                value_list.remove(value_item)

                    # Replace %s dropdown values for hardware acceleration
                    if param["setting"] in ("graca_number_en",
                                            "graca_number_de"):
                        for card_index in range(0, 3):
                            # Test each graphics card, and only include valid ones
                            if card_index in self.hardware_tests_cards and self.hardware_tests_cards.get(
                                    card_index):
                                # Loop through valid modes supported by this card
                                for mode in self.hardware_tests_cards.get(
                                        card_index):
                                    # Add supported graphics card for each mode (duplicates are okay)
                                    if mode == 0:
                                        # cpu only
                                        value_list.append({
                                            "value":
                                            card_index,
                                            "name":
                                            _("No acceleration"),
                                            "icon":
                                            mode
                                        })
                                    else:
                                        # hardware accelerated
                                        value_list.append({
                                            "value":
                                            card_index,
                                            "name":
                                            _("Graphics Card %s") %
                                            (card_index + 1),
                                            "icon":
                                            mode
                                        })

                        if os_platform in ["Darwin", "Windows"]:
                            # Disable graphics card selection for Mac and Windows (since libopenshot
                            # only supports device selection on Linux)
                            widget.setEnabled(False)
                            widget.setToolTip(
                                _("Graphics card selection not supported in %s"
                                  ) % os_platform)

                    # Add normal values
                    box_index = 0
                    for value_item in value_list:
                        k = value_item["name"]
                        v = value_item["value"]
                        i = value_item.get("icon", None)

                        # Override icons for certain values
                        # TODO: Find a more elegant way to do this
                        icon = None
                        if k == "Linux VA-API" or i == 1:
                            icon = QIcon(":/hw/hw-accel-vaapi.svg")
                        elif k == "Nvidia NVDEC" or i == 2:
                            icon = QIcon(":/hw/hw-accel-nvdec.svg")
                        elif k == "Linux VDPAU" or i == 6:
                            icon = QIcon(":/hw/hw-accel-vdpau.svg")
                        elif k == "Windows D3D9" or i == 3:
                            icon = QIcon(":/hw/hw-accel-dx.svg")
                        elif k == "Windows D3D11" or i == 4:
                            icon = QIcon(":/hw/hw-accel-dx.svg")
                        elif k == "MacOS" or i == 5:
                            icon = QIcon(":/hw/hw-accel-vtb.svg")
                        elif k == "Intel QSV" or i == 7:
                            icon = QIcon(":/hw/hw-accel-qsv.svg")
                        elif k == "No acceleration" or i == 0:
                            icon = QIcon(":/hw/hw-accel-none.svg")

                        # add dropdown item
                        if icon:
                            widget.setIconSize(QSize(60, 18))
                            widget.addItem(icon, _(k), v)
                        else:
                            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 and filterFound):
                    # 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 and filterFound):
                    # Add widget to layout
                    tabWidget.layout().addWidget(label)

            # Add stretch to bottom of layout
            tabWidget.layout().addStretch()

        # Delete all tabs and widgets
        self.DeleteAllTabs(onlyInVisible=True)
Exemplo n.º 16
0
    def __init__(self, cuts):

        # 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()
        self.cuts = cuts

        # 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

        # Update FPS / Profile timer
        # Timer to use a delay before applying new profile/fps data (so we don't spam libopenshot)
        self.delayed_fps_timer = None
        self.delayed_fps_timer = QTimer()
        self.delayed_fps_timer.setInterval(200)
        self.delayed_fps_timer.timeout.connect(self.delayed_fps_callback)
        self.delayed_fps_timer.stop()

        # Pause playback (to prevent crash since we are fixing to change the timeline's max size)
        get_app().window.actionPlay_trigger(None, force="pause")

        # Clear timeline preview cache (to get more available memory)
        get_app().window.timeline_sync.timeline.ClearAllCache()

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

        # Set OMP thread disabled flag (for stability)
        openshot.Settings.Instance().WAIT_FOR_VIDEO_PROCESSING_TASK = True
        openshot.Settings.Instance().HIGH_QUALITY_SCALING = True

        # 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

        # No keyframe rescaling has happened yet (due to differences in FPS)
        self.keyframes_rescaled = False

        # 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)
        json_str = json_timeline
        json_object = json.loads(json_str)
        json_object.pop("cuts")
        #json_object["clips"] = []
        self.timeline.SetJson(json.dumps(json_object))

        #print("======deded===", json.dumps(json_object))
        '''
        self.clips, self.video_length = CutsToClips(cuts)
        for clip in self.clips:
            # Show waveform for audio files
            if not clip.Reader().info.has_video and clip.Reader().info.has_audio:
                clip.Waveform(True)
            self.timeline.AddClip(clip)

        self.video_length = self.video_length * fps.num / fps.den
        '''

        # 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("-%05d.png")

        # Loop through Export To options
        export_options = [
            _("Video & Audio"),
            _("Video Only"),
            _("Audio Only"),
            _("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)

        # ********* Advanced 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
                profile_name = "%s (%sx%s)" % (profile.info.description,
                                               profile.info.width,
                                               profile.info.height)
                self.profile_names.append(profile_name)
                self.profile_paths[profile_name] = 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(
                self.getProfileName(self.getProfilePath(profile_name)),
                self.getProfilePath(profile_name))

            # Set default (if it matches the project)
            if app.project.get(['profile']) in 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 preset_path in [info.EXPORT_PRESETS_PATH, info.USER_PRESETS_PATH]:
            for file in os.listdir(preset_path):
                xmldoc = xml.parse(os.path.join(preset_path, 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()