Esempio n. 1
0
class PreferencesDialogBase(QDialog):
    def __init__(self, parent, app, **kwargs):
        flags = Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowSystemMenuHint
        super().__init__(parent, flags, **kwargs)
        self.app = app
        all_languages = get_langnames()
        self.supportedLanguages = sorted(SUPPORTED_LANGUAGES,
                                         key=lambda lang: all_languages[lang])
        self._setupUi()

        self.filterHardnessSlider.valueChanged["int"].connect(
            self.filterHardnessLabel.setNum)
        self.buttonBox.clicked.connect(self.buttonClicked)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)

    def _setupFilterHardnessBox(self):
        self.filterHardnessHLayout = QHBoxLayout()
        self.filterHardnessLabel = QLabel(self)
        self.filterHardnessLabel.setText(tr("Filter Hardness:"))
        self.filterHardnessLabel.setMinimumSize(QSize(0, 0))
        self.filterHardnessHLayout.addWidget(self.filterHardnessLabel)
        self.filterHardnessVLayout = QVBoxLayout()
        self.filterHardnessVLayout.setSpacing(0)
        self.filterHardnessHLayoutSub1 = QHBoxLayout()
        self.filterHardnessHLayoutSub1.setSpacing(12)
        self.filterHardnessSlider = QSlider(self)
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.filterHardnessSlider.sizePolicy().hasHeightForWidth())
        self.filterHardnessSlider.setSizePolicy(sizePolicy)
        self.filterHardnessSlider.setMinimum(1)
        self.filterHardnessSlider.setMaximum(100)
        self.filterHardnessSlider.setTracking(True)
        self.filterHardnessSlider.setOrientation(Qt.Horizontal)
        self.filterHardnessHLayoutSub1.addWidget(self.filterHardnessSlider)
        self.filterHardnessLabel = QLabel(self)
        self.filterHardnessLabel.setText("100")
        self.filterHardnessLabel.setMinimumSize(QSize(21, 0))
        self.filterHardnessHLayoutSub1.addWidget(self.filterHardnessLabel)
        self.filterHardnessVLayout.addLayout(self.filterHardnessHLayoutSub1)
        self.filterHardnessHLayoutSub2 = QHBoxLayout()
        self.filterHardnessHLayoutSub2.setContentsMargins(-1, 0, -1, -1)
        self.moreResultsLabel = QLabel(self)
        self.moreResultsLabel.setText(tr("More Results"))
        self.filterHardnessHLayoutSub2.addWidget(self.moreResultsLabel)
        spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                 QSizePolicy.Minimum)
        self.filterHardnessHLayoutSub2.addItem(spacerItem)
        self.fewerResultsLabel = QLabel(self)
        self.fewerResultsLabel.setText(tr("Fewer Results"))
        self.filterHardnessHLayoutSub2.addWidget(self.fewerResultsLabel)
        self.filterHardnessVLayout.addLayout(self.filterHardnessHLayoutSub2)
        self.filterHardnessHLayout.addLayout(self.filterHardnessVLayout)

    def _setupBottomPart(self):
        # The bottom part of the pref panel is always the same in all editions.
        self.copyMoveLabel = QLabel(self)
        self.copyMoveLabel.setText(tr("Copy and Move:"))
        self.widgetsVLayout.addWidget(self.copyMoveLabel)
        self.copyMoveDestinationComboBox = QComboBox(self)
        self.copyMoveDestinationComboBox.addItem(tr("Right in destination"))
        self.copyMoveDestinationComboBox.addItem(tr("Recreate relative path"))
        self.copyMoveDestinationComboBox.addItem(tr("Recreate absolute path"))
        self.widgetsVLayout.addWidget(self.copyMoveDestinationComboBox)
        self.customCommandLabel = QLabel(self)
        self.customCommandLabel.setText(
            tr("Custom Command (arguments: %d for dupe, %r for ref):"))
        self.widgetsVLayout.addWidget(self.customCommandLabel)
        self.customCommandEdit = QLineEdit(self)
        self.widgetsVLayout.addWidget(self.customCommandEdit)

    def _setupDisplayPage(self):
        self.ui_groupbox = QGroupBox("&General Interface")
        layout = QVBoxLayout()
        self.languageLabel = QLabel(tr("Language:"), self)
        self.languageComboBox = QComboBox(self)
        for lang in self.supportedLanguages:
            self.languageComboBox.addItem(get_langnames()[lang])
        layout.addLayout(
            horizontalWrap([self.languageLabel, self.languageComboBox, None]))
        self._setupAddCheckbox(
            "tabs_default_pos",
            tr("Use default position for tab bar (requires restart)"))
        self.tabs_default_pos.setToolTip(
            tr("Place the tab bar below the main menu instead of next to it\n\
On MacOS, the tab bar will fill up the window's width instead."))
        layout.addWidget(self.tabs_default_pos)
        self.ui_groupbox.setLayout(layout)
        self.displayVLayout.addWidget(self.ui_groupbox)

        gridlayout = QFormLayout()
        result_groupbox = QGroupBox("&Result Table")
        self.fontSizeSpinBox = QSpinBox()
        self.fontSizeSpinBox.setMinimum(5)
        gridlayout.addRow(tr("Font size:"), self.fontSizeSpinBox)
        self._setupAddCheckbox("reference_bold_font",
                               tr("Use bold font for references"))
        gridlayout.addRow(self.reference_bold_font)

        self.result_table_ref_foreground_color = ColorPickerButton(self)
        gridlayout.addRow(tr("Reference foreground color:"),
                          self.result_table_ref_foreground_color)
        self.result_table_ref_background_color = ColorPickerButton(self)
        gridlayout.addRow(tr("Reference background color:"),
                          self.result_table_ref_background_color)
        self.result_table_delta_foreground_color = ColorPickerButton(self)
        gridlayout.addRow(tr("Delta foreground color:"),
                          self.result_table_delta_foreground_color)
        gridlayout.setLabelAlignment(Qt.AlignLeft)

        # Keep same vertical spacing as parent layout for consistency
        gridlayout.setVerticalSpacing(self.displayVLayout.spacing())
        result_groupbox.setLayout(gridlayout)
        self.displayVLayout.addWidget(result_groupbox)

        details_groupbox = QGroupBox("&Details Window")
        self.details_groupbox_layout = QVBoxLayout()
        self._setupAddCheckbox("details_dialog_titlebar_enabled",
                               tr("Show the title bar and can be docked"))
        self.details_dialog_titlebar_enabled.setToolTip(
            tr("While the title bar is hidden, \
use the modifier key to drag the floating window around") if ISLINUX else
            tr("The title bar can only be disabled while the window is docked"
               ))
        self.details_groupbox_layout.addWidget(
            self.details_dialog_titlebar_enabled)
        self._setupAddCheckbox("details_dialog_vertical_titlebar",
                               tr("Vertical title bar"))
        self.details_dialog_vertical_titlebar.setToolTip(
            tr("Change the title bar from horizontal on top, to vertical on the left side"
               ))
        self.details_groupbox_layout.addWidget(
            self.details_dialog_vertical_titlebar)
        self.details_dialog_vertical_titlebar.setEnabled(
            self.details_dialog_titlebar_enabled.isChecked())
        self.details_dialog_titlebar_enabled.stateChanged.connect(
            self.details_dialog_vertical_titlebar.setEnabled)
        gridlayout = QGridLayout()
        self.details_table_delta_foreground_color_label = QLabel(
            tr("Delta foreground color:"))
        gridlayout.addWidget(self.details_table_delta_foreground_color_label,
                             4, 0)
        self.details_table_delta_foreground_color = ColorPickerButton(self)
        gridlayout.addWidget(self.details_table_delta_foreground_color, 4, 2,
                             1, 1, Qt.AlignLeft)
        gridlayout.setColumnStretch(1, 1)
        gridlayout.setColumnStretch(3, 4)
        self.details_groupbox_layout.addLayout(gridlayout)
        details_groupbox.setLayout(self.details_groupbox_layout)
        self.displayVLayout.addWidget(details_groupbox)

    def _setupAddCheckbox(self, name, label, parent=None):
        if parent is None:
            parent = self
        cb = QCheckBox(parent)
        cb.setText(label)
        setattr(self, name, cb)

    def _setupPreferenceWidgets(self):
        # Edition-specific
        pass

    def _setupUi(self):
        self.setWindowTitle(tr("Options"))
        self.setSizeGripEnabled(False)
        self.setModal(True)
        self.mainVLayout = QVBoxLayout(self)
        self.tabwidget = QTabWidget()
        self.page_general = QWidget()
        self.page_display = QWidget()
        self.widgetsVLayout = QVBoxLayout()
        self.page_general.setLayout(self.widgetsVLayout)
        self.displayVLayout = QVBoxLayout()
        self.displayVLayout.setSpacing(
            5)  # arbitrary value, might conflict with style
        self.page_display.setLayout(self.displayVLayout)
        self._setupPreferenceWidgets()
        self._setupDisplayPage()
        # self.mainVLayout.addLayout(self.widgetsVLayout)
        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel
                                          | QDialogButtonBox.Ok
                                          | QDialogButtonBox.RestoreDefaults)
        self.mainVLayout.addWidget(self.tabwidget)
        self.mainVLayout.addWidget(self.buttonBox)
        self.layout().setSizeConstraint(QLayout.SetFixedSize)
        self.tabwidget.addTab(self.page_general, "General")
        self.tabwidget.addTab(self.page_display, "Display")
        self.displayVLayout.addStretch(0)
        self.widgetsVLayout.addStretch(0)

    def _load(self, prefs, setchecked, section):
        # Edition-specific
        pass

    def _save(self, prefs, ischecked):
        # Edition-specific
        pass

    def load(self, prefs=None, section=Sections.ALL):
        if prefs is None:
            prefs = self.app.prefs
        setchecked = lambda cb, b: cb.setCheckState(Qt.Checked
                                                    if b else Qt.Unchecked)
        if section & Sections.GENERAL:
            self.filterHardnessSlider.setValue(prefs.filter_hardness)
            self.filterHardnessLabel.setNum(prefs.filter_hardness)
            setchecked(self.mixFileKindBox, prefs.mix_file_kind)
            setchecked(self.useRegexpBox, prefs.use_regexp)
            setchecked(self.removeEmptyFoldersBox, prefs.remove_empty_folders)
            setchecked(self.ignoreHardlinkMatches,
                       prefs.ignore_hardlink_matches)
            setchecked(self.debugModeBox, prefs.debug_mode)
            self.copyMoveDestinationComboBox.setCurrentIndex(
                prefs.destination_type)
            self.customCommandEdit.setText(prefs.custom_command)
        if section & Sections.DISPLAY:
            setchecked(self.reference_bold_font, prefs.reference_bold_font)
            setchecked(self.tabs_default_pos, prefs.tabs_default_pos)
            setchecked(self.details_dialog_titlebar_enabled,
                       prefs.details_dialog_titlebar_enabled)
            setchecked(self.details_dialog_vertical_titlebar,
                       prefs.details_dialog_vertical_titlebar)
            self.fontSizeSpinBox.setValue(prefs.tableFontSize)
            self.details_table_delta_foreground_color.setColor(
                prefs.details_table_delta_foreground_color)
            self.result_table_ref_foreground_color.setColor(
                prefs.result_table_ref_foreground_color)
            self.result_table_ref_background_color.setColor(
                prefs.result_table_ref_background_color)
            self.result_table_delta_foreground_color.setColor(
                prefs.result_table_delta_foreground_color)
            try:
                langindex = self.supportedLanguages.index(
                    self.app.prefs.language)
            except ValueError:
                langindex = 0
            self.languageComboBox.setCurrentIndex(langindex)
        self._load(prefs, setchecked, section)

    def save(self):
        prefs = self.app.prefs
        prefs.filter_hardness = self.filterHardnessSlider.value()
        ischecked = lambda cb: cb.checkState() == Qt.Checked
        prefs.mix_file_kind = ischecked(self.mixFileKindBox)
        prefs.use_regexp = ischecked(self.useRegexpBox)
        prefs.remove_empty_folders = ischecked(self.removeEmptyFoldersBox)
        prefs.ignore_hardlink_matches = ischecked(self.ignoreHardlinkMatches)
        prefs.debug_mode = ischecked(self.debugModeBox)
        prefs.reference_bold_font = ischecked(self.reference_bold_font)
        prefs.details_dialog_titlebar_enabled = ischecked(
            self.details_dialog_titlebar_enabled)
        prefs.details_dialog_vertical_titlebar = ischecked(
            self.details_dialog_vertical_titlebar)
        prefs.details_table_delta_foreground_color = self.details_table_delta_foreground_color.color
        prefs.result_table_ref_foreground_color = self.result_table_ref_foreground_color.color
        prefs.result_table_ref_background_color = self.result_table_ref_background_color.color
        prefs.result_table_delta_foreground_color = self.result_table_delta_foreground_color.color
        prefs.destination_type = self.copyMoveDestinationComboBox.currentIndex(
        )
        prefs.custom_command = str(self.customCommandEdit.text())
        prefs.tableFontSize = self.fontSizeSpinBox.value()
        prefs.tabs_default_pos = ischecked(self.tabs_default_pos)
        lang = self.supportedLanguages[self.languageComboBox.currentIndex()]
        oldlang = self.app.prefs.language
        if oldlang not in self.supportedLanguages:
            oldlang = "en"
        if lang != oldlang:
            QMessageBox.information(
                self,
                "",
                tr("dupeGuru has to restart for language changes to take effect."
                   ),
            )
        self.app.prefs.language = lang
        self._save(prefs, ischecked)

    def resetToDefaults(self, section_to_update):
        self.load(Preferences(), section_to_update)

    # --- Events
    def buttonClicked(self, button):
        role = self.buttonBox.buttonRole(button)
        if role == QDialogButtonBox.ResetRole:
            current_tab = self.tabwidget.currentWidget()
            section_to_update = Sections.ALL
            if current_tab is self.page_general:
                section_to_update = Sections.GENERAL
            if current_tab is self.page_display:
                section_to_update = Sections.DISPLAY
            self.resetToDefaults(section_to_update)
Esempio n. 2
0
class PreferencesDialogBase(QDialog):
    def __init__(self, parent, app, **kwargs):
        flags = Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowSystemMenuHint
        super().__init__(parent, flags, **kwargs)
        self.app = app
        self._setupUi()

        self.filterHardnessSlider.valueChanged['int'].connect(self.filterHardnessLabel.setNum)
        self.buttonBox.clicked.connect(self.buttonClicked)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)

    def _setupScanTypeBox(self, labels):
        self.scanTypeHLayout = QHBoxLayout()
        self.scanTypeLabel = QLabel(self)
        self.scanTypeLabel.setText(tr("Scan Type:"))
        self.scanTypeLabel.setMinimumSize(QSize(100, 0))
        self.scanTypeLabel.setMaximumSize(QSize(100, 16777215))
        self.scanTypeHLayout.addWidget(self.scanTypeLabel)
        self.scanTypeComboBox = QComboBox(self)
        for label in labels:
            self.scanTypeComboBox.addItem(label)
        self.scanTypeHLayout.addWidget(self.scanTypeComboBox)
        self.widgetsVLayout.addLayout(self.scanTypeHLayout)

    def _setupFilterHardnessBox(self):
        self.filterHardnessHLayout = QHBoxLayout()
        self.filterHardnessLabel = QLabel(self)
        self.filterHardnessLabel.setText(tr("Filter Hardness:"))
        self.filterHardnessLabel.setMinimumSize(QSize(0, 0))
        self.filterHardnessHLayout.addWidget(self.filterHardnessLabel)
        self.filterHardnessVLayout = QVBoxLayout()
        self.filterHardnessVLayout.setSpacing(0)
        self.filterHardnessHLayoutSub1 = QHBoxLayout()
        self.filterHardnessHLayoutSub1.setSpacing(12)
        self.filterHardnessSlider = QSlider(self)
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.filterHardnessSlider.sizePolicy().hasHeightForWidth())
        self.filterHardnessSlider.setSizePolicy(sizePolicy)
        self.filterHardnessSlider.setMinimum(1)
        self.filterHardnessSlider.setMaximum(100)
        self.filterHardnessSlider.setTracking(True)
        self.filterHardnessSlider.setOrientation(Qt.Horizontal)
        self.filterHardnessHLayoutSub1.addWidget(self.filterHardnessSlider)
        self.filterHardnessLabel = QLabel(self)
        self.filterHardnessLabel.setText("100")
        self.filterHardnessLabel.setMinimumSize(QSize(21, 0))
        self.filterHardnessHLayoutSub1.addWidget(self.filterHardnessLabel)
        self.filterHardnessVLayout.addLayout(self.filterHardnessHLayoutSub1)
        self.filterHardnessHLayoutSub2 = QHBoxLayout()
        self.filterHardnessHLayoutSub2.setContentsMargins(-1, 0, -1, -1)
        self.moreResultsLabel = QLabel(self)
        self.moreResultsLabel.setText(tr("More Results"))
        self.filterHardnessHLayoutSub2.addWidget(self.moreResultsLabel)
        spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.filterHardnessHLayoutSub2.addItem(spacerItem)
        self.fewerResultsLabel = QLabel(self)
        self.fewerResultsLabel.setText(tr("Fewer Results"))
        self.filterHardnessHLayoutSub2.addWidget(self.fewerResultsLabel)
        self.filterHardnessVLayout.addLayout(self.filterHardnessHLayoutSub2)
        self.filterHardnessHLayout.addLayout(self.filterHardnessVLayout)

    def _setupBottomPart(self):
        # The bottom part of the pref panel is always the same in all editions.
        self.fontSizeLabel = QLabel(tr("Font size:"))
        self.fontSizeSpinBox = QSpinBox()
        self.fontSizeSpinBox.setMinimum(5)
        self.widgetsVLayout.addLayout(horizontalWrap([self.fontSizeLabel, self.fontSizeSpinBox, None]))
        self.languageLabel = QLabel(tr("Language:"), self)
        self.languageComboBox = QComboBox(self)
        for lang in SUPPORTED_LANGUAGES:
            self.languageComboBox.addItem(LANGNAMES[lang])
        self.widgetsVLayout.addLayout(horizontalWrap([self.languageLabel, self.languageComboBox, None]))
        self.copyMoveLabel = QLabel(self)
        self.copyMoveLabel.setText(tr("Copy and Move:"))
        self.widgetsVLayout.addWidget(self.copyMoveLabel)
        self.copyMoveDestinationComboBox = QComboBox(self)
        self.copyMoveDestinationComboBox.addItem(tr("Right in destination"))
        self.copyMoveDestinationComboBox.addItem(tr("Recreate relative path"))
        self.copyMoveDestinationComboBox.addItem(tr("Recreate absolute path"))
        self.widgetsVLayout.addWidget(self.copyMoveDestinationComboBox)
        self.customCommandLabel = QLabel(self)
        self.customCommandLabel.setText(tr("Custom Command (arguments: %d for dupe, %r for ref):"))
        self.widgetsVLayout.addWidget(self.customCommandLabel)
        self.customCommandEdit = QLineEdit(self)
        self.widgetsVLayout.addWidget(self.customCommandEdit)

    def _setupAddCheckbox(self, name, label, parent=None):
        if parent is None:
            parent = self
        cb = QCheckBox(parent)
        cb.setText(label)
        setattr(self, name, cb)

    def _setupPreferenceWidgets(self):
        # Edition-specific
        pass

    def _setupUi(self):
        self.setWindowTitle(tr("Preferences"))
        self.resize(304, 263)
        self.setSizeGripEnabled(False)
        self.setModal(True)
        self.mainVLayout = QVBoxLayout(self)
        self.widgetsVLayout = QVBoxLayout()
        self._setupPreferenceWidgets()
        self.mainVLayout.addLayout(self.widgetsVLayout)
        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok|QDialogButtonBox.RestoreDefaults)
        self.mainVLayout.addWidget(self.buttonBox)
        if (not ISOSX) and (not ISLINUX):
            self.mainVLayout.removeWidget(self.ignoreHardlinkMatches)
            self.ignoreHardlinkMatches.setHidden(True)

    def _load(self, prefs, setchecked):
        # Edition-specific
        pass

    def _save(self, prefs, ischecked):
        # Edition-specific
        pass

    def load(self, prefs=None):
        if prefs is None:
            prefs = self.app.prefs
        self.filterHardnessSlider.setValue(prefs.filter_hardness)
        self.filterHardnessLabel.setNum(prefs.filter_hardness)
        setchecked = lambda cb, b: cb.setCheckState(Qt.Checked if b else Qt.Unchecked)
        setchecked(self.mixFileKindBox, prefs.mix_file_kind)
        setchecked(self.useRegexpBox, prefs.use_regexp)
        setchecked(self.removeEmptyFoldersBox, prefs.remove_empty_folders)
        setchecked(self.ignoreHardlinkMatches, prefs.ignore_hardlink_matches)
        setchecked(self.debugModeBox, prefs.debug_mode)
        self.copyMoveDestinationComboBox.setCurrentIndex(prefs.destination_type)
        self.customCommandEdit.setText(prefs.custom_command)
        self.fontSizeSpinBox.setValue(prefs.tableFontSize)
        try:
            langindex = SUPPORTED_LANGUAGES.index(self.app.prefs.language)
        except ValueError:
            langindex = 0
        self.languageComboBox.setCurrentIndex(langindex)
        self._load(prefs, setchecked)

    def save(self):
        prefs = self.app.prefs
        prefs.filter_hardness = self.filterHardnessSlider.value()
        ischecked = lambda cb: cb.checkState() == Qt.Checked
        prefs.mix_file_kind = ischecked(self.mixFileKindBox)
        prefs.use_regexp = ischecked(self.useRegexpBox)
        prefs.remove_empty_folders = ischecked(self.removeEmptyFoldersBox)
        prefs.ignore_hardlink_matches = ischecked(self.ignoreHardlinkMatches)
        prefs.debug_mode = ischecked(self.debugModeBox)
        prefs.destination_type = self.copyMoveDestinationComboBox.currentIndex()
        prefs.custom_command = str(self.customCommandEdit.text())
        prefs.tableFontSize = self.fontSizeSpinBox.value()
        lang = SUPPORTED_LANGUAGES[self.languageComboBox.currentIndex()]
        oldlang = self.app.prefs.language
        if oldlang not in SUPPORTED_LANGUAGES:
            oldlang = 'en'
        if lang != oldlang:
            QMessageBox.information(self, "", tr("dupeGuru has to restart for language changes to take effect."))
        self.app.prefs.language = lang
        self._save(prefs, ischecked)

    #--- Events
    def buttonClicked(self, button):
        role = self.buttonBox.buttonRole(button)
        if role == QDialogButtonBox.ResetRole:
            self.resetToDefaults()
Esempio n. 3
0
class OptionsDialog(QDialog):
    def __init__(self, setting: Settings, have_dutils, parent=None):
        super(OptionsDialog, self).__init__(parent)

        self.settings = setting
        self.enabled_video = True  # temporary toggle to disable video features as they do not exist
        self.enabled_logging = True
        self.enabled_keybindings = True
        self.enabled_dutils = have_dutils
        self.setWindowTitle("Tcam-Capture Options")
        self.layout = QVBoxLayout(self)
        self.setLayout(self.layout)

        self.tabs = QTabWidget()

        self.general_widget = QWidget()
        self.keybindings_widget = QWidget()
        self.logging_widget = QWidget()
        self.saving_widget = QWidget()

        self._setup_general_ui()
        self.tabs.addTab(self.general_widget, "General")

        self._setup_saving_ui()
        self.tabs.addTab(self.saving_widget, "Image/Video")

        self.layout.addWidget(self.tabs)
        # OK and Cancel buttons
        self.buttons = QDialogButtonBox(
            QDialogButtonBox.Reset | QDialogButtonBox.Ok
            | QDialogButtonBox.Cancel, Qt.Horizontal, self)
        self.layout.addWidget(self.buttons)

        self.buttons.accepted.connect(self.accept)
        self.buttons.rejected.connect(self.reject)
        self.buttons.clicked.connect(self.clicked)

    def _setup_general_ui(self):
        """
        Create everything related to the general tab
        """

        layout = QFormLayout()
        layout.setSpacing(20)
        layout.setVerticalSpacing(20)

        self.device_dialog_checkbox = QCheckBox(self)
        device_dialog_label = QLabel("Open device dialog on start:")
        layout.addRow(device_dialog_label, self.device_dialog_checkbox)

        self.reopen_device_checkbox = QCheckBox(self)
        reopen_device_label = QLabel(
            "Reopen device on start(ignores device dialog):", self)
        layout.addRow(reopen_device_label, self.reopen_device_checkbox)

        self.use_dutils_checkbox = QCheckBox(self)
        self.use_dutils_label = QLabel("Use tiscamera dutils, if present:",
                                       self)
        layout.addRow(self.use_dutils_label, self.use_dutils_checkbox)

        if not self.enabled_dutils:
            self.use_dutils_label.setToolTip(
                "Enabled when tiscamera-dutils are installed")
            self.use_dutils_label.setEnabled(False)
            self.use_dutils_checkbox.setToolTip(
                "Enabled when tiscamera-dutils are installed")
            self.use_dutils_checkbox.setEnabled(False)

        self.general_widget.setLayout(layout)

    def _setup_saving_ui(self):
        """
        Create everything related to the image/video saving tab
        """
        encoder_dict = Encoder.get_encoder_dict()
        form_layout = QFormLayout()

        layout = QVBoxLayout()
        layout.addLayout(form_layout)

        location_layout = QHBoxLayout()
        location_label = QLabel("Where to save images/videos:", self)
        self.location_edit = QLineEdit(self)
        location_dialog_button = QPushButton("...", self)
        location_dialog_button.clicked.connect(self.open_file_dialog)
        location_layout.addWidget(self.location_edit)
        location_layout.addWidget(location_dialog_button)

        # maintain descriptions as own labels
        # pyqt seems to loose the descriptions somewhere
        # when simple strings are used or the qlabel does not have self as owner
        form_layout.addRow(location_label, location_layout)

        self.image_type_combobox = QComboBox(self)
        for key, value in encoder_dict.items():
            if value.encoder_type == Encoder.MediaType.image:
                self.image_type_combobox.addItem(key)
        image_type_label = QLabel("Save images as:")
        self.image_type_combobox.currentIndexChanged['QString'].connect(
            self.image_name_suffix_changed)

        form_layout.addRow(image_type_label, self.image_type_combobox)
        if self.enabled_video:
            self.video_type_combobox = QComboBox(self)
            for key, value in encoder_dict.items():
                if value.encoder_type == Encoder.MediaType.video:
                    self.video_type_combobox.addItem(key)
            self.video_type_combobox.currentIndexChanged['QString'].connect(
                self.video_name_suffix_changed)

            video_type_label = QLabel("Save videos as:", self)
            form_layout.addRow(video_type_label, self.video_type_combobox)

        image_name_groupbox = QGroupBox("Image File Names")
        groupbox_layout = QFormLayout()
        image_name_groupbox.setLayout(groupbox_layout)

        self.image_name_preview = QLabel(
            "<USER-PREFIX>-<SERIAL>-<FORMAT>-<TIMESTAMP>-<COUNTER>.png")
        self.image_name_preview_description = QLabel(
            "Images will be named like:")
        groupbox_layout.addRow(self.image_name_preview_description,
                               self.image_name_preview)

        self.image_name_prefix = QLineEdit()
        self.image_name_prefix.textChanged.connect(
            self.image_name_prefix_changed)
        self.image_name_prefix.setMaxLength(100)

        self.image_name_prefix_description = QLabel("User Prefix:", self)
        groupbox_layout.addRow(self.image_name_prefix_description,
                               self.image_name_prefix)

        self.image_name_serial = QCheckBox(self)
        self.image_name_serial.toggled.connect(
            self.image_name_properties_toggled)
        self.image_name_serial_description = QLabel("Include Serial:")
        groupbox_layout.addRow(self.image_name_serial_description,
                               self.image_name_serial)

        self.image_name_format = QCheckBox(self)
        self.image_name_format.toggled.connect(
            self.image_name_properties_toggled)

        self.image_name_format_description = QLabel("Include Format:")
        groupbox_layout.addRow(self.image_name_format_description,
                               self.image_name_format)

        self.image_name_counter = QCheckBox(self)
        self.image_name_counter.toggled.connect(
            self.image_name_properties_toggled)
        self.image_name_counter_description = QLabel("Include Counter:")
        groupbox_layout.addRow(self.image_name_counter_description,
                               self.image_name_counter)

        self.image_name_counter_box = QSpinBox(self)
        self.image_name_counter_box.setRange(1, 10)
        self.image_name_counter_box.valueChanged.connect(
            self.image_name_counter_changed)
        self.image_name_counter_box_description = QLabel("Counter Size:")
        groupbox_layout.addRow(self.image_name_counter_box_description,
                               self.image_name_counter_box)

        self.image_name_counter.toggled.connect(
            self.toggle_image_counter_box_availability)
        self.image_name_counter.toggled.connect(
            self.image_name_properties_toggled)

        self.image_name_timestamp = QCheckBox(self)
        self.image_name_timestamp.toggled.connect(
            self.image_name_properties_toggled)
        self.image_name_timestamp_description = QLabel("Include Timestamp:")
        groupbox_layout.addRow(self.image_name_timestamp_description,
                               self.image_name_timestamp)

        layout.addWidget(image_name_groupbox)

        video_groupbox = QGroupBox("Video File Names")

        video_layout = QFormLayout()
        video_groupbox.setLayout(video_layout)

        self.video_name_preview = QLabel(
            "<USER-PREFIX>-<SERIAL>-<FORMAT>-<TIMESTAMP>-<COUNTER>.png")
        self.video_name_preview_description = QLabel(
            "Videos will be named like:")
        video_layout.addRow(self.video_name_preview_description,
                            self.video_name_preview)

        self.video_name_prefix = QLineEdit()
        self.video_name_prefix.textChanged.connect(
            self.video_name_prefix_changed)
        self.video_name_prefix.setMaxLength(100)

        self.video_name_prefix_description = QLabel("User Prefix:", self)
        video_layout.addRow(self.video_name_prefix_description,
                            self.video_name_prefix)

        self.video_name_serial = QCheckBox(self)
        self.video_name_serial.toggled.connect(
            self.video_name_properties_toggled)
        self.video_name_serial_description = QLabel("Include Serial:")
        video_layout.addRow(self.video_name_serial_description,
                            self.video_name_serial)

        self.video_name_format = QCheckBox(self)
        self.video_name_format.toggled.connect(
            self.video_name_properties_toggled)

        self.video_name_format_description = QLabel("Include Format:")
        video_layout.addRow(self.video_name_format_description,
                            self.video_name_format)

        self.video_name_counter = QCheckBox(self)
        self.video_name_counter.toggled.connect(
            self.video_name_properties_toggled)
        self.video_name_counter_description = QLabel("Include Counter:")
        video_layout.addRow(self.video_name_counter_description,
                            self.video_name_counter)

        self.video_name_counter_box = QSpinBox(self)
        self.video_name_counter_box.setRange(1, 10)
        self.video_name_counter_box.valueChanged.connect(
            self.video_name_counter_changed)
        self.video_name_counter_box_description = QLabel("Counter Size:")
        video_layout.addRow(self.video_name_counter_box_description,
                            self.video_name_counter_box)

        self.video_name_counter.toggled.connect(
            self.toggle_video_counter_box_availability)
        self.video_name_counter.toggled.connect(
            self.video_name_properties_toggled)

        self.video_name_timestamp = QCheckBox(self)
        self.video_name_timestamp.toggled.connect(
            self.video_name_properties_toggled)
        self.video_name_timestamp_description = QLabel("Include Timestamp:")
        video_layout.addRow(self.video_name_timestamp_description,
                            self.video_name_timestamp)

        layout.addWidget(video_groupbox)

        self.saving_widget.setLayout(layout)

    def image_name_prefix_changed(self, name: str):
        """"""

        self.settings.image_name.user_prefix = self.image_name_prefix.text()
        self.update_image_name_preview()

    def image_name_suffix_changed(self, suffix: str):
        """"""

        self.update_image_name_preview()

    def image_name_counter_changed(self, name: str):
        """"""
        self.settings.image_name.counter_size = self.image_name_counter_box.value(
        )
        self.update_image_name_preview()

    def image_name_properties_toggled(self):
        """"""

        self.settings.image_name.include_timestamp = self.image_name_timestamp.isChecked(
        )
        self.settings.image_name.include_counter = self.image_name_counter.isChecked(
        )
        self.settings.image_name.include_format = self.image_name_format.isChecked(
        )
        self.settings.image_name.include_serial = self.image_name_serial.isChecked(
        )

        self.update_image_name_preview()

    def update_image_name_preview(self):

        preview_string = ""

        if self.settings.image_name.user_prefix != "":

            max_prefix_length = 15
            prefix = (
                self.settings.image_name.user_prefix[:max_prefix_length] +
                '..') if len(
                    self.settings.image_name.user_prefix
                ) > max_prefix_length else self.settings.image_name.user_prefix

            preview_string += prefix

        if self.settings.image_name.include_serial:
            if preview_string != "":
                preview_string += "-"
            preview_string += "00001234"

        if self.settings.image_name.include_format:
            if preview_string != "":
                preview_string += "-"
            preview_string += "gbrg_1920x1080_15_1"

        if self.settings.image_name.include_timestamp:
            if preview_string != "":
                preview_string += "-"
            preview_string += "19701230T125503"

        if self.settings.image_name.include_counter:
            if preview_string != "":
                preview_string += "-"
            preview_string += '{message:0>{fill}}'.format(
                message=1, fill=self.settings.image_name.counter_size)

        if preview_string == "":
            preview_string = "image"

        preview_string += "." + self.image_type_combobox.currentText()

        self.image_name_preview.setText(preview_string)

    def video_name_prefix_changed(self, name: str):
        """"""

        self.settings.video_name.user_prefix = self.video_name_prefix.text()
        self.update_video_name_preview()

    def video_name_suffix_changed(self, suffix: str):
        """"""

        self.update_video_name_preview()

    def video_name_counter_changed(self, name: str):
        """"""
        self.settings.video_name.counter_size = self.video_name_counter_box.value(
        )
        self.update_video_name_preview()

    def video_name_properties_toggled(self):
        """"""

        self.settings.video_name.include_timestamp = self.video_name_timestamp.isChecked(
        )
        self.settings.video_name.include_counter = self.video_name_counter.isChecked(
        )
        self.settings.video_name.include_format = self.video_name_format.isChecked(
        )
        self.settings.video_name.include_serial = self.video_name_serial.isChecked(
        )

        self.update_video_name_preview()

    def update_video_name_preview(self):

        preview_string = ""

        if self.settings.video_name.user_prefix != "":

            # This is a convenience change to the displayed string.
            # We only display an amount of max_prefix_length
            # chars to save screen space
            max_prefix_length = 15
            prefix = (
                self.settings.video_name.user_prefix[:max_prefix_length] +
                '..') if len(
                    self.settings.video_name.user_prefix
                ) > max_prefix_length else self.settings.video_name.user_prefix

            preview_string += prefix

        if self.settings.video_name.include_serial:
            if preview_string != "":
                preview_string += "-"
            preview_string += "00001234"

        if self.settings.video_name.include_format:
            if preview_string != "":
                preview_string += "-"
            preview_string += "gbrg_1920x1080_15_1"

        if self.settings.video_name.include_timestamp:
            if preview_string != "":
                preview_string += "-"
            preview_string += "19701230T125503"

        if self.settings.video_name.include_counter:
            if preview_string != "":
                preview_string += "-"
            preview_string += '{message:0>{fill}}'.format(
                message=1, fill=self.settings.video_name.counter_size)

        if preview_string == "":
            preview_string = "video"

        preview_string += "." + self.video_type_combobox.currentText()

        self.video_name_preview.setText(preview_string)

    def toggle_image_counter_box_availability(self):
        """"""
        if self.image_name_counter.isChecked():
            self.image_name_counter_box.setEnabled(True)
        else:
            self.image_name_counter_box.setEnabled(False)

    def toggle_video_counter_box_availability(self):
        """"""
        if self.video_name_counter.isChecked():
            self.video_name_counter_box.setEnabled(True)
        else:
            self.video_name_counter_box.setEnabled(False)

    def set_settings(self, settings: Settings):
        self.location_edit.setText(settings.get_save_location())
        self.image_type_combobox.setCurrentText(settings.get_image_type())
        if self.enabled_video:
            self.video_type_combobox.setCurrentText(settings.get_video_type())
        self.device_dialog_checkbox.setChecked(
            settings.show_device_dialog_on_startup)
        self.reopen_device_checkbox.setChecked(
            settings.reopen_device_on_startup)
        self.use_dutils_checkbox.setChecked(settings.use_dutils)

        if settings.image_name.include_timestamp:
            self.image_name_timestamp.blockSignals(True)
            self.image_name_timestamp.toggle()
            self.image_name_timestamp.blockSignals(False)
        if settings.image_name.include_counter:
            self.image_name_counter.blockSignals(True)
            self.image_name_counter.toggle()
            self.image_name_counter.blockSignals(False)

        self.image_name_counter_box.blockSignals(True)
        self.image_name_counter_box.setValue(settings.image_name.counter_size)
        self.image_name_counter_box.blockSignals(False)
        self.toggle_image_counter_box_availability()

        if settings.image_name.include_format:
            self.image_name_format.blockSignals(True)
            self.image_name_format.toggle()
            self.image_name_format.blockSignals(False)
        if settings.image_name.include_serial:
            self.image_name_serial.blockSignals(True)
            self.image_name_serial.toggle()
            self.image_name_serial.blockSignals(False)
        self.image_name_prefix.blockSignals(True)
        self.image_name_prefix.setText(settings.image_name.user_prefix)
        self.image_name_prefix.blockSignals(False)

        self.update_image_name_preview()

        if settings.video_name.include_timestamp:
            self.video_name_timestamp.blockSignals(True)
            self.video_name_timestamp.toggle()
            self.video_name_timestamp.blockSignals(False)
        if settings.video_name.include_counter:
            self.video_name_counter.blockSignals(True)
            self.video_name_counter.toggle()
            self.video_name_counter.blockSignals(False)

        self.video_name_counter_box.blockSignals(True)
        self.video_name_counter_box.setValue(settings.video_name.counter_size)
        self.video_name_counter_box.blockSignals(False)
        self.toggle_video_counter_box_availability()

        if settings.video_name.include_format:
            self.video_name_format.blockSignals(True)
            self.video_name_format.toggle()
            self.video_name_format.blockSignals(False)
        if settings.video_name.include_serial:
            self.video_name_serial.blockSignals(True)
            self.video_name_serial.toggle()
            self.video_name_serial.blockSignals(False)
        self.video_name_prefix.blockSignals(True)
        self.video_name_prefix.setText(settings.video_name.user_prefix)
        self.video_name_prefix.blockSignals(False)

        self.update_video_name_preview()

    def save_settings(self):
        self.settings.save_location = self.location_edit.text()
        self.settings.image_type = self.image_type_combobox.currentText()
        if self.enabled_video:
            self.settings.video_type = self.video_type_combobox.currentText()
        self.settings.show_device_dialog_on_startup = self.device_dialog_checkbox.isChecked(
        )
        self.settings.reopen_device_on_startup = self.reopen_device_checkbox.isChecked(
        )
        self.settings.use_dutils = self.use_dutils_checkbox.isChecked()

        self.settings.image_name.include_timestamp = self.image_name_timestamp.isChecked(
        )
        self.settings.image_name.include_counter = self.image_name_counter.isChecked(
        )
        if self.image_name_counter.isChecked():
            self.settings.image_name.counter_size = self.image_name_counter_box.value(
            )

        self.settings.image_name.include_format = self.image_name_format.isChecked(
        )
        self.settings.image_name.include_serial = self.image_name_serial.isChecked(
        )
        self.settings.image_name.user_prefix = self.image_name_prefix.text()

        self.settings.video_name.include_timestamp = self.video_name_timestamp.isChecked(
        )
        self.settings.video_name.include_counter = self.video_name_counter.isChecked(
        )
        if self.video_name_counter.isChecked():
            self.settings.video_name.counter_size = self.video_name_counter_box.value(
            )

        self.settings.video_name.include_format = self.video_name_format.isChecked(
        )
        self.settings.video_name.include_serial = self.video_name_serial.isChecked(
        )
        self.settings.video_name.user_prefix = self.video_name_prefix.text()

    def open_file_dialog(self):
        fdia = QFileDialog()
        fdia.setFileMode(QFileDialog.Directory)
        fdia.setWindowTitle("Select Directory for saving images and videos")
        if fdia.exec_():
            self.location_edit.setText(fdia.selectedFiles()[0])

    def get_location(self):
        return self.location_edit.text()

    def get_image_format(self):
        return self.image_type_combobox.currentText()

    def get_video_format(self):
        return self.video_type_combobox.currentText()

    def clicked(self, button):

        if self.buttons.buttonRole(button) == QDialogButtonBox.ResetRole:
            self.reset()

    def reset(self):
        """"""
        log.info("reset called")
        self.settings.reset()
        self.set_settings(self.settings)

    @staticmethod
    def get_options(settings, parent=None):
        dialog = OptionsDialog(settings, parent)

        if settings is not None:
            dialog.set_settings(settings)
        result = dialog.exec_()

        if result == QDialog.Accepted:
            dialog.save_settings()
            settings.save()

        return result == QDialog.Accepted
Esempio n. 4
0
class SettingsWindow(QDialog):
    apply_setting_signal = pyqtSignal()

    def __init__(self,
                 slave_cmb: QComboBox,
                 setting_obj: SettingWrapper,
                 parent: QObject = None):
        super().__init__(parent=parent)
        self.setting_obj = setting_obj

        init_idx = slave_cmb.currentIndex()

        top_left_side = QtWidgets.QHBoxLayout()

        new_file_icon = QIcon('designer_files/icon/plus-rectangle.svg')
        new_file = QtWidgets.QPushButton(new_file_icon, '')
        delete_file_icon = QIcon('designer_files/icon/trash.svg')
        delete_file = QtWidgets.QPushButton(delete_file_icon, '')
        save_file_icon = QIcon('designer_files/icon/save.svg')
        save_file = QtWidgets.QPushButton(save_file_icon, '')
        self.drop_down_list = QtWidgets.QComboBox()

        new_file.clicked.connect(self.create_new_setting)
        delete_file.clicked.connect(self.delete_setting)
        save_file.clicked.connect(self.save_setting)

        top_left_side.addWidget(new_file)
        top_left_side.addWidget(save_file)
        top_left_side.addWidget(delete_file)
        top_left_side.addWidget(self.drop_down_list)
        top_left_side.insertSpacing(-1, 20)
        ls_settings = setting_obj.setting

        self.stacked_widget = QtWidgets.QStackedWidget()
        self.drop_down_list.currentIndexChanged.connect(
            self.stacked_widget.setCurrentIndex)
        for name, setting_dict in ls_settings.items():
            self.drop_down_list.addItem(name)
            widget = self.init_tab(setting_dict)
            self.stacked_widget.addWidget(widget)
        self.drop_down_list.setCurrentIndex(init_idx)
        self.drop_down_list.currentIndexChanged.connect(
            slave_cmb.setCurrentIndex)
        layout = QtWidgets.QVBoxLayout()

        layout.addLayout(top_left_side)
        layout.addWidget(self.stacked_widget)

        self.button_dialog = QDialogButtonBox(Qt.Horizontal)
        self.button_dialog.addButton(QDialogButtonBox.Apply)
        self.button_dialog.addButton(QDialogButtonBox.Ok)
        self.button_dialog.addButton(QDialogButtonBox.Cancel)
        self.button_dialog.clicked.connect(self.button_clicked)
        layout.addWidget(self.button_dialog)

        self.setLayout(layout)

    @pyqtSlot()
    def create_new_setting(self) -> None:
        new_name, ok = QInputDialog.getText(self, 'New Setting',
                                            'Enter new name:')
        idx = self.drop_down_list.currentIndex()
        is_duplicate = self.drop_down_list.findText(new_name) != -1
        if len(new_name) != 0 and ok and not is_duplicate:
            setting_dict = self.setting_obj.clone(idx, new_name)
            self.drop_down_list.addItem(new_name)
            widget = self.init_tab(setting_dict)
            self.stacked_widget.addWidget(widget)
            self.drop_down_list.setCurrentIndex(self.drop_down_list.count() -
                                                1)
        elif len(new_name) == 0:
            msg_box = QMessageBox(self)
            msg_box.setText("Empty string, please specify name :")
            msg_box.exec()
        elif is_duplicate:
            msg_box = QMessageBox(self)
            msg_box.setText("Deplicate string, please specify another name :")
            msg_box.exec()

    @pyqtSlot()
    def save_setting(self) -> None:
        setting_idx = self.drop_down_list.currentIndex()
        self.setting_obj.save(setting_idx)

    @pyqtSlot()
    def delete_setting(self) -> None:
        setting_idx = self.drop_down_list.currentIndex()
        self.setting_obj.remove(setting_idx)
        self.drop_down_list.removeItem(setting_idx)
        widget = self.stacked_widget.widget(setting_idx)
        self.stacked_widget.removeWidget(widget)

    @pyqtSlot(QAbstractButton)
    def button_clicked(self, button: QAbstractButton) -> None:
        role = self.button_dialog.buttonRole(button)
        if role == QDialogButtonBox.ApplyRole:
            self.apply_setting_signal.emit()
        elif role == QDialogButtonBox.AcceptRole:
            self.apply_setting_signal.emit()
            self.accept()
        elif role == QDialogButtonBox.RejectRole:
            self.reject()

    def init_tab(self, setting_dict: PrintSetting) -> QtWidgets.QWidget:
        layout = QtWidgets.QHBoxLayout()
        menu_widget = QtWidgets.QListWidget()
        layout.addWidget(menu_widget)

        sub_stacked_page = QtWidgets.QStackedWidget()
        menu_widget.currentRowChanged.connect(sub_stacked_page.setCurrentIndex)
        layout.addWidget(sub_stacked_page)

        cat_frame = {}
        sec_frame = {}
        for entry in attr.asdict(setting_dict, recurse=False).values():
            if isinstance(entry, SingleEntry):
                cat = entry.ui['category']
                if not cat in cat_frame.keys():
                    single_frame = QtWidgets.QWidget()
                    single_frame.setLayout(QtWidgets.QVBoxLayout())
                    cat_frame[cat] = single_frame
                    menu_widget.addItem(cat)
                    sec_frame[cat] = {}
                    sub_stacked_page.addWidget(single_frame)

                sec = entry.ui['section']
                if not sec in sec_frame[cat].keys():
                    box_layout = QtWidgets.QVBoxLayout()
                    qbox = QtWidgets.QGroupBox(sec)
                    qbox.setLayout(box_layout)
                    sec_frame[cat][sec] = qbox
                    cat_frame[cat].layout().addWidget(qbox)

                q_entry = entry.create_ui_entry()
                self.apply_setting_signal.connect(entry.commit_value)
                sec_frame[cat][sec].layout().addWidget(q_entry)

        widget = QtWidgets.QWidget()
        widget.setLayout(layout)
        return widget
class OptionsDialog(QDialog):
    def __init__(self, setting: Settings, have_dutils, parent=None):
        super(OptionsDialog, self).__init__(parent)

        self.settings = setting
        self.enabled_video = True  # temporary toggle to disable video features as they do not exist
        self.enabled_logging = True
        self.enabled_keybindings = True
        self.enabled_dutils = have_dutils
        self.setWindowTitle("Tcam-Capture Options")
        self.layout = QVBoxLayout(self)
        self.setLayout(self.layout)

        self.tabs = QTabWidget()

        self.general_widget = QWidget()
        self.keybindings_widget = QWidget()
        self.logging_widget = QWidget()
        self.saving_widget = QWidget()

        self._setup_general_ui()
        self.tabs.addTab(self.general_widget, "General")

        if self.enabled_keybindings:
            self._setup_keybindings_ui()
            self.tabs.addTab(self.keybindings_widget, "Keybindings")
        self._setup_saving_ui()
        self.tabs.addTab(self.saving_widget, "Image/Video")

        self.layout.addWidget(self.tabs)
        # OK and Cancel buttons
        self.buttons = QDialogButtonBox(
            QDialogButtonBox.Reset | QDialogButtonBox.Ok | QDialogButtonBox.Cancel,
            Qt.Horizontal, self)
        self.layout.addWidget(self.buttons)

        self.buttons.accepted.connect(self.accept)
        self.buttons.rejected.connect(self.reject)
        self.buttons.clicked.connect(self.clicked)

    def _setup_general_ui(self):
        """
        Create everything related to the general tab
        """

        layout = QFormLayout()
        layout.setSpacing(20)
        layout.setVerticalSpacing(20)

        self.device_dialog_checkbox = QCheckBox(self)
        device_dialog_label = QLabel("Open device dialog on start:")
        layout.addRow(device_dialog_label,
                      self.device_dialog_checkbox)

        self.reopen_device_checkbox = QCheckBox(self)
        reopen_device_label = QLabel("Reopen device on start(ignores device dialog):", self)
        layout.addRow(reopen_device_label,
                      self.reopen_device_checkbox)

        self.use_dutils_checkbox = QCheckBox(self)
        self.use_dutils_label = QLabel("Use tiscamera dutils, if present:", self)
        layout.addRow(self.use_dutils_label,
                      self.use_dutils_checkbox)

        if not self.enabled_dutils:
            self.use_dutils_label.setToolTip("Enabled when tiscamera-dutils are installed")
            self.use_dutils_label.setEnabled(False)
            self.use_dutils_checkbox.setToolTip("Enabled when tiscamera-dutils are installed")
            self.use_dutils_checkbox.setEnabled(False)

        self.general_widget.setLayout(layout)

    def _setup_saving_ui(self):
        """
        Create everything related to the image/video saving tab
        """
        encoder_dict = Encoder.get_encoder_dict()
        form_layout = QFormLayout()

        layout = QVBoxLayout()
        layout.addLayout(form_layout)

        location_layout = QHBoxLayout()
        location_label = QLabel("Where to save images/videos:", self)
        self.location_edit = QLineEdit(self)
        location_dialog_button = QPushButton("...", self)
        location_dialog_button.clicked.connect(self.open_file_dialog)
        location_layout.addWidget(self.location_edit)
        location_layout.addWidget(location_dialog_button)

        # maintain descriptions as own labels
        # pyqt seems to loose the descriptions somewhere
        # when simple strings are used or the qlabel does not have self as owner
        form_layout.addRow(location_label,
                           location_layout)

        self.image_type_combobox = QComboBox(self)
        for key, value in encoder_dict.items():
            if value.encoder_type == Encoder.MediaType.image:
                self.image_type_combobox.addItem(key)
        image_type_label = QLabel("Save images as:")
        self.image_type_combobox.currentIndexChanged['QString'].connect(self.image_name_suffix_changed)

        form_layout.addRow(image_type_label,
                           self.image_type_combobox)
        if self.enabled_video:
            self.video_type_combobox = QComboBox(self)
            for key, value in encoder_dict.items():
                if value.encoder_type == Encoder.MediaType.video:
                    self.video_type_combobox.addItem(key)
            self.video_type_combobox.currentIndexChanged['QString'].connect(self.video_name_suffix_changed)

            video_type_label = QLabel("Save videos as:", self)
            form_layout.addRow(video_type_label,
                               self.video_type_combobox)

        image_name_groupbox = QGroupBox("Image File Names")
        groupbox_layout = QFormLayout()
        image_name_groupbox.setLayout(groupbox_layout)

        self.image_name_preview = QLabel("<USER-PREFIX>-<SERIAL>-<FORMAT>-<TIMESTAMP>-<COUNTER>.png")
        self.image_name_preview_description = QLabel("Images will be named like:")
        groupbox_layout.addRow(self.image_name_preview_description,
                               self.image_name_preview)

        self.image_name_prefix = QLineEdit()
        self.image_name_prefix.textChanged.connect(self.image_name_prefix_changed)
        self.image_name_prefix.setMaxLength(100)

        self.image_name_prefix_description = QLabel("User Prefix:", self)
        groupbox_layout.addRow(self.image_name_prefix_description,
                               self.image_name_prefix)

        self.image_name_serial = QCheckBox(self)
        self.image_name_serial.toggled.connect(self.image_name_properties_toggled)
        self.image_name_serial_description = QLabel("Include Serial:")
        groupbox_layout.addRow(self.image_name_serial_description,
                               self.image_name_serial)

        self.image_name_format = QCheckBox(self)
        self.image_name_format.toggled.connect(self.image_name_properties_toggled)

        self.image_name_format_description = QLabel("Include Format:")
        groupbox_layout.addRow(self.image_name_format_description,
                               self.image_name_format)

        self.image_name_counter = QCheckBox(self)
        self.image_name_counter.toggled.connect(self.image_name_properties_toggled)
        self.image_name_counter_description = QLabel("Include Counter:")
        groupbox_layout.addRow(self.image_name_counter_description,
                               self.image_name_counter)

        self.image_name_counter_box = QSpinBox(self)
        self.image_name_counter_box.setRange(1, 10)
        self.image_name_counter_box.valueChanged.connect(self.image_name_counter_changed)
        self.image_name_counter_box_description = QLabel("Counter Size:")
        groupbox_layout.addRow(self.image_name_counter_box_description,
                               self.image_name_counter_box)

        self.image_name_counter.toggled.connect(self.toggle_image_counter_box_availability)
        self.image_name_counter.toggled.connect(self.image_name_properties_toggled)

        self.image_name_timestamp = QCheckBox(self)
        self.image_name_timestamp.toggled.connect(self.image_name_properties_toggled)
        self.image_name_timestamp_description = QLabel("Include Timestamp:")
        groupbox_layout.addRow(self.image_name_timestamp_description,
                               self.image_name_timestamp)

        layout.addWidget(image_name_groupbox)

        video_groupbox = QGroupBox("Video File Names")

        video_layout = QFormLayout()
        video_groupbox.setLayout(video_layout)

        self.video_name_preview = QLabel("<USER-PREFIX>-<SERIAL>-<FORMAT>-<TIMESTAMP>-<COUNTER>.png")
        self.video_name_preview_description = QLabel("Videos will be named like:")
        video_layout.addRow(self.video_name_preview_description,
                            self.video_name_preview)

        self.video_name_prefix = QLineEdit()
        self.video_name_prefix.textChanged.connect(self.video_name_prefix_changed)
        self.video_name_prefix.setMaxLength(100)

        self.video_name_prefix_description = QLabel("User Prefix:", self)
        video_layout.addRow(self.video_name_prefix_description,
                            self.video_name_prefix)

        self.video_name_serial = QCheckBox(self)
        self.video_name_serial.toggled.connect(self.video_name_properties_toggled)
        self.video_name_serial_description = QLabel("Include Serial:")
        video_layout.addRow(self.video_name_serial_description,
                            self.video_name_serial)

        self.video_name_format = QCheckBox(self)
        self.video_name_format.toggled.connect(self.video_name_properties_toggled)

        self.video_name_format_description = QLabel("Include Format:")
        video_layout.addRow(self.video_name_format_description,
                            self.video_name_format)

        self.video_name_counter = QCheckBox(self)
        self.video_name_counter.toggled.connect(self.video_name_properties_toggled)
        self.video_name_counter_description = QLabel("Include Counter:")
        video_layout.addRow(self.video_name_counter_description,
                            self.video_name_counter)

        self.video_name_counter_box = QSpinBox(self)
        self.video_name_counter_box.setRange(1, 10)
        self.video_name_counter_box.valueChanged.connect(self.video_name_counter_changed)
        self.video_name_counter_box_description = QLabel("Counter Size:")
        video_layout.addRow(self.video_name_counter_box_description,
                            self.video_name_counter_box)

        self.video_name_counter.toggled.connect(self.toggle_video_counter_box_availability)
        self.video_name_counter.toggled.connect(self.video_name_properties_toggled)

        self.video_name_timestamp = QCheckBox(self)
        self.video_name_timestamp.toggled.connect(self.video_name_properties_toggled)
        self.video_name_timestamp_description = QLabel("Include Timestamp:")
        video_layout.addRow(self.video_name_timestamp_description,
                            self.video_name_timestamp)

        layout.addWidget(video_groupbox)

        self.saving_widget.setLayout(layout)

    def image_name_prefix_changed(self, name: str):
        """"""

        self.settings.image_name.user_prefix = self.image_name_prefix.text()
        self.update_image_name_preview()

    def image_name_suffix_changed(self, suffix: str):
        """"""

        self.update_image_name_preview()

    def image_name_counter_changed(self, name: str):
        """"""
        self.settings.image_name.counter_size = self.image_name_counter_box.value()
        self.update_image_name_preview()

    def image_name_properties_toggled(self):
        """"""

        self.settings.image_name.include_timestamp = self.image_name_timestamp.isChecked()
        self.settings.image_name.include_counter = self.image_name_counter.isChecked()
        self.settings.image_name.include_format = self.image_name_format.isChecked()
        self.settings.image_name.include_serial = self.image_name_serial.isChecked()

        self.update_image_name_preview()

    def update_image_name_preview(self):

        preview_string = ""

        if self.settings.image_name.user_prefix != "":

            max_prefix_length = 15
            prefix = (self.settings.image_name.user_prefix[:max_prefix_length] + '..') if len(self.settings.image_name.user_prefix) > max_prefix_length else self.settings.image_name.user_prefix

            preview_string += prefix

        if self.settings.image_name.include_serial:
            if preview_string != "":
                preview_string += "-"
            preview_string += "00001234"

        if self.settings.image_name.include_format:
            if preview_string != "":
                preview_string += "-"
            preview_string += "gbrg_1920x1080_15_1"

        if self.settings.image_name.include_timestamp:
            if preview_string != "":
                preview_string += "-"
            preview_string += "19701230T125503"

        if self.settings.image_name.include_counter:
            if preview_string != "":
                preview_string += "-"
            preview_string += '{message:0>{fill}}'.format(message=1,
                                                          fill=self.settings.image_name.counter_size)

        if preview_string == "":
            preview_string = "image"

        preview_string += "." + self.image_type_combobox.currentText()

        self.image_name_preview.setText(preview_string)


    def video_name_prefix_changed(self, name: str):
        """"""

        self.settings.video_name.user_prefix = self.video_name_prefix.text()
        self.update_video_name_preview()

    def video_name_suffix_changed(self, suffix: str):
        """"""

        self.update_video_name_preview()

    def video_name_counter_changed(self, name: str):
        """"""
        self.settings.video_name.counter_size = self.video_name_counter_box.value()
        self.update_video_name_preview()

    def video_name_properties_toggled(self):
        """"""

        self.settings.video_name.include_timestamp = self.video_name_timestamp.isChecked()
        self.settings.video_name.include_counter = self.video_name_counter.isChecked()
        self.settings.video_name.include_format = self.video_name_format.isChecked()
        self.settings.video_name.include_serial = self.video_name_serial.isChecked()

        self.update_video_name_preview()

    def update_video_name_preview(self):

        preview_string = ""

        if self.settings.video_name.user_prefix != "":

            # This is a convenience change to the displayed string.
            # We only display an amount of max_prefix_length
            # chars to save screen space
            max_prefix_length = 15
            prefix = (self.settings.video_name.user_prefix[:max_prefix_length] + '..') if len(self.settings.video_name.user_prefix) > max_prefix_length else self.settings.video_name.user_prefix

            preview_string += prefix

        if self.settings.video_name.include_serial:
            if preview_string != "":
                preview_string += "-"
            preview_string += "00001234"

        if self.settings.video_name.include_format:
            if preview_string != "":
                preview_string += "-"
            preview_string += "gbrg_1920x1080_15_1"

        if self.settings.video_name.include_timestamp:
            if preview_string != "":
                preview_string += "-"
            preview_string += "19701230T125503"

        if self.settings.video_name.include_counter:
            if preview_string != "":
                preview_string += "-"
            preview_string += '{message:0>{fill}}'.format(message=1,
                                                          fill=self.settings.video_name.counter_size)

        if preview_string == "":
            preview_string = "video"

        preview_string += "." + self.video_type_combobox.currentText()

        self.video_name_preview.setText(preview_string)

    def toggle_image_counter_box_availability(self):
        """"""
        if self.image_name_counter.isChecked():
            self.image_name_counter_box.setEnabled(True)
        else:
            self.image_name_counter_box.setEnabled(False)

    def toggle_video_counter_box_availability(self):
        """"""
        if self.video_name_counter.isChecked():
            self.video_name_counter_box.setEnabled(True)
        else:
            self.video_name_counter_box.setEnabled(False)

    def _setup_keybindings_ui(self):
        """
        Create everything related to the keybindings tab
        """

        layout = QFormLayout()
        self.keybinding_fullscreen_label = QLabel("Toggle Fullscreen:")
        self.keybinding_fullscreen = QKeySequenceEdit()
        layout.addRow(self.keybinding_fullscreen_label,
                      self.keybinding_fullscreen)

        self.keybinding_save_image_label = QLabel("Save image:")
        self.keybinding_save_image = QKeySequenceEdit(QKeySequence(self.settings.keybinding_save_image))
        layout.addRow(self.keybinding_save_image_label,
                      self.keybinding_save_image)

        self.keybinding_trigger_image_label = QLabel("Trigger images via softwaretrigger:")
        self.keybinding_trigger_image = QKeySequenceEdit(QKeySequence(self.settings.keybinding_trigger_image))
        layout.addRow(self.keybinding_trigger_image_label,
                      self.keybinding_trigger_image)

        self.keybinding_open_dialog_label = QLabel("Open device dialog:")
        self.keybinding_open_dialog = QKeySequenceEdit(QKeySequence(self.settings.keybinding_open_dialog))
        layout.addRow(self.keybinding_open_dialog_label,
                      self.keybinding_open_dialog)

        self.keybindings_widget.setLayout(layout)

    def set_settings(self, settings: Settings):
        self.location_edit.setText(settings.get_save_location())
        self.image_type_combobox.setCurrentText(settings.get_image_type())
        if self.enabled_video:
            self.video_type_combobox.setCurrentText(settings.get_video_type())
        self.device_dialog_checkbox.setChecked(settings.show_device_dialog_on_startup)
        self.reopen_device_checkbox.setChecked(settings.reopen_device_on_startup)
        self.use_dutils_checkbox.setChecked(settings.use_dutils)

        #
        # keybindings
        #
        if self.enabled_keybindings:
            self.keybinding_fullscreen.setKeySequence(QKeySequence(self.settings.keybinding_fullscreen))
            self.keybinding_save_image.setKeySequence(QKeySequence(self.settings.keybinding_save_image))
            self.keybinding_trigger_image.setKeySequence(QKeySequence(self.settings.keybinding_trigger_image))
            self.keybinding_open_dialog.setKeySequence(QKeySequence(self.settings.keybinding_open_dialog))

        #
        # image saving
        #
        if settings.image_name.include_timestamp:
            self.image_name_timestamp.blockSignals(True)
            self.image_name_timestamp.toggle()
            self.image_name_timestamp.blockSignals(False)
        if settings.image_name.include_counter:
            self.image_name_counter.blockSignals(True)
            self.image_name_counter.toggle()
            self.image_name_counter.blockSignals(False)

        self.image_name_counter_box.blockSignals(True)
        self.image_name_counter_box.setValue(settings.image_name.counter_size)
        self.image_name_counter_box.blockSignals(False)
        self.toggle_image_counter_box_availability()

        if settings.image_name.include_format:
            self.image_name_format.blockSignals(True)
            self.image_name_format.toggle()
            self.image_name_format.blockSignals(False)
        if settings.image_name.include_serial:
            self.image_name_serial.blockSignals(True)
            self.image_name_serial.toggle()
            self.image_name_serial.blockSignals(False)
        self.image_name_prefix.blockSignals(True)
        self.image_name_prefix.setText(settings.image_name.user_prefix)
        self.image_name_prefix.blockSignals(False)

        self.update_image_name_preview()

        #
        # video saving
        #
        if settings.video_name.include_timestamp:
            self.video_name_timestamp.blockSignals(True)
            self.video_name_timestamp.toggle()
            self.video_name_timestamp.blockSignals(False)
        if settings.video_name.include_counter:
            self.video_name_counter.blockSignals(True)
            self.video_name_counter.toggle()
            self.video_name_counter.blockSignals(False)

        self.video_name_counter_box.blockSignals(True)
        self.video_name_counter_box.setValue(settings.video_name.counter_size)
        self.video_name_counter_box.blockSignals(False)
        self.toggle_video_counter_box_availability()

        if settings.video_name.include_format:
            self.video_name_format.blockSignals(True)
            self.video_name_format.toggle()
            self.video_name_format.blockSignals(False)
        if settings.video_name.include_serial:
            self.video_name_serial.blockSignals(True)
            self.video_name_serial.toggle()
            self.video_name_serial.blockSignals(False)
        self.video_name_prefix.blockSignals(True)
        self.video_name_prefix.setText(settings.video_name.user_prefix)
        self.video_name_prefix.blockSignals(False)

        self.update_video_name_preview()

    def save_settings(self):
        self.settings.save_location = self.location_edit.text()
        self.settings.image_type = self.image_type_combobox.currentText()
        if self.enabled_video:
            self.settings.video_type = self.video_type_combobox.currentText()
        self.settings.show_device_dialog_on_startup = self.device_dialog_checkbox.isChecked()
        self.settings.reopen_device_on_startup = self.reopen_device_checkbox.isChecked()
        self.settings.use_dutils = self.use_dutils_checkbox.isChecked()

        #
        # keybindings
        #
        if self.enabled_keybindings:
            self.settings.keybinding_fullscreen = self.keybinding_fullscreen.keySequence().toString()
            self.settings.keybinding_save_image = self.keybinding_save_image.keySequence().toString()
            self.settings.keybinding_trigger_image = self.keybinding_trigger_image.keySequence().toString()
            self.settings.keybinding_open_dialog = self.keybinding_open_dialog.keySequence().toString()

        #
        # image saving
        #
        self.settings.image_name.include_timestamp = self.image_name_timestamp.isChecked()
        self.settings.image_name.include_counter = self.image_name_counter.isChecked()
        if self.image_name_counter.isChecked():
            self.settings.image_name.counter_size = self.image_name_counter_box.value()

        self.settings.image_name.include_format = self.image_name_format.isChecked()
        self.settings.image_name.include_serial = self.image_name_serial.isChecked()
        self.settings.image_name.user_prefix = self.image_name_prefix.text()

        #
        # video saving
        #
        self.settings.video_name.include_timestamp = self.video_name_timestamp.isChecked()
        self.settings.video_name.include_counter = self.video_name_counter.isChecked()
        if self.video_name_counter.isChecked():
            self.settings.video_name.counter_size = self.video_name_counter_box.value()

        self.settings.video_name.include_format = self.video_name_format.isChecked()
        self.settings.video_name.include_serial = self.video_name_serial.isChecked()
        self.settings.video_name.user_prefix = self.video_name_prefix.text()

    def open_file_dialog(self):
        fdia = QFileDialog()
        fdia.setFileMode(QFileDialog.Directory)
        fdia.setWindowTitle("Select Directory for saving images and videos")
        if fdia.exec_():
            self.location_edit.setText(fdia.selectedFiles()[0])

    def get_location(self):
        return self.location_edit.text()

    def get_image_format(self):
        return self.image_type_combobox.currentText()

    def get_video_format(self):
        return self.video_type_combobox.currentText()

    def clicked(self, button):

        if self.buttons.buttonRole(button) == QDialogButtonBox.ResetRole:
            self.reset()

    def reset(self):
        """"""
        log.info("reset called")
        self.settings.reset()
        self.set_settings(self.settings)

    @staticmethod
    def get_options(settings, parent=None):
        dialog = OptionsDialog(settings, parent)

        if settings is not None:
            dialog.set_settings(settings)
        result = dialog.exec_()

        if result == QDialog.Accepted:
            dialog.save_settings()
            settings.save()

        return result == QDialog.Accepted
class Dialog(QWidget):
    ''' UI '''
    def __init__(self, upgrades, security_upgrades, reboot_required, upg_path):
        QWidget.__init__(self)
        self.upgrades = upgrades
        self.security_upgrades = security_upgrades
        self.upg_path = upg_path
        self.reboot_required = reboot_required

        apt_pkg.init()
        try:
            self.cache = apt_pkg.Cache()
        except SystemError as e:
            sys.stderr.write(_("Error: Opening the cache (%s)") % e)
            sys.exit(-1)
        self.depcache = apt_pkg.DepCache(self.cache)
        self.records = apt_pkg.PackageRecords(self.cache)

        self.initUI()
        self.buttonBox.rejected.connect(self.call_reject)
        self.buttonBox.clicked.connect(self.call_upgrade)

    def initUI(self):
        ''' UI initialization '''
        self.label = QLabel()
        self.label.setAlignment(Qt.AlignHCenter)

        self.tw = QTreeWidget()
        if self.security_upgrades > 0:
            self.tw.setColumnCount(2)
            self.tw.setHeaderLabels([_('Affected Packages'), _('Security')])
            self.tw.header().setSectionResizeMode(0, QHeaderView.Stretch)
            self.tw.header().setStretchLastSection(False)
        else:
            self.tw.setColumnCount(1)
            self.tw.setHeaderLabels([_('Affected Packages')])
            self.tw.setHeaderHidden(True)

        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Cancel
                                          | QDialogButtonBox.Apply)
        text = ""

        hbox = QHBoxLayout()
        hbox.addStretch(1)
        hbox.addWidget(self.buttonBox)
        hbox.addStretch(1)

        vbox = QVBoxLayout()
        vbox.addWidget(self.label)
        vbox.addWidget(self.tw)
        vbox.addLayout(hbox)

        self.tw.setVisible(False)

        if self.upg_path is None:
            self.buttonBox.button(QDialogButtonBox.Apply).setVisible(False)

        self.setLayout(vbox)
        self.setGeometry(300, 300, 500, 150)
        self.setWindowTitle("Update Notifier")
        self.center()

        if self.upgrades > 0:
            self.tw.setVisible(True)
            self.depcache.upgrade(True)  # True for non safe.
            pkg_install = list()
            pkg_upgrade = list()
            pkg_delete = list()
            for p in self.cache.packages:
                if self.depcache.marked_delete(p):
                    pkg_delete.append(p)
                elif self.depcache.marked_install(p):
                    pkg_install.append([p, self.depcache.get_candidate_ver(p)])
                elif self.depcache.marked_upgrade(p):
                    pkg_upgrade.append([p, self.depcache.get_candidate_ver(p)])
            text = _("There are upgrades available. Do you want to do a system"
                     " upgrade?")
            text += "\n"
            text += _("This will mean packages could be upgraded, installed or"
                      " removed.")
            if self.security_upgrades > 0:
                text += "\n" + str(self.security_upgrades)
                if self.security_upgrades == 1:
                    text += _(" is a security upgrade.")
                else:
                    text += _(" are security upgrades.")

            if len(pkg_delete) > 0:
                toDelete = QTreeWidgetItem([_('Remove')])
                for p in pkg_delete:
                    td_child = QTreeWidgetItem(p.name)
                    toDelete.addChild(td_child)
                toDelete.setIcon(0, QIcon.fromTheme("edit-delete"))
                self.tw.addTopLevelItem(toDelete)
            if len(pkg_install) > 0:
                toInstall = QTreeWidgetItem([_('Install')])
                for p in pkg_install:
                    td_child = QTreeWidgetItem(
                        [p[0].name + "  /  " + p[1].ver_str])
                    if apt_check.isSecurityUpgrade(p[1]):
                        td_child.setIcon(1, QIcon.fromTheme("security-high"))
                        toInstall.setIcon(1, QIcon.fromTheme("security-high"))
                    toInstall.addChild(td_child)
                    self.records.lookup(p[1].file_list[0])
                    short = QTreeWidgetItem([self.records.short_desc])
                    td_child.addChild(short)
                toInstall.setIcon(0,
                                  QIcon.fromTheme("system-software-install"))
                self.tw.addTopLevelItem(toInstall)
            if len(pkg_upgrade) > 0:
                toUpgrade = QTreeWidgetItem([_('Upgrade')])
                for p in pkg_upgrade:
                    td_child = QTreeWidgetItem([
                        p[0].name + "  /  " + p[0].current_ver.ver_str +
                        "  ->  " + p[1].ver_str
                    ])
                    if apt_check.isSecurityUpgrade(p[1]):
                        td_child.setIcon(1, QIcon.fromTheme("security-high"))
                        toUpgrade.setIcon(1, QIcon.fromTheme("security-high"))
                    toUpgrade.addChild(td_child)
                    self.records.lookup(p[1].file_list[0])
                    short = QTreeWidgetItem([self.records.short_desc])
                    td_child.addChild(short)
                toUpgrade.setIcon(0, QIcon.fromTheme("system-software-update"))
                self.tw.addTopLevelItem(toUpgrade)

        if self.reboot_required:
            if text == "":
                text = _("Reboot required")
                self.buttonBox.button(QDialogButtonBox.Apply).setVisible(False)
            else:
                text += "\n"
                text += _("Reboot required")

        self.label.setText(text)

    def center(self):
        ''' puts UI in center of screen '''
        frameGm = self.frameGeometry()
        screen = QApplication.desktop().screenNumber(
            QApplication.desktop().cursor().pos())
        centerPoint = QApplication.desktop().screenGeometry(screen).center()
        frameGm.moveCenter(centerPoint)
        self.move(frameGm.topLeft())

    def call_reject(self):
        ''' when close button is pressed, quit '''
        app.quit()

    def call_upgrade(self, btnClicked):
        if (self.buttonBox.buttonRole(btnClicked) == QDialogButtonBox.ApplyRole
            ):
            ''' starts upgrade process '''
            self.label.setText(_("Upgrading..."))
            # TODO maybe open another thread so notifier won't freeze
            cmd = ['lxqt-sudo', self.upg_path, '--full-upgrade']
            self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(False)
            self.buttonBox.button(QDialogButtonBox.Apply).setVisible(False)
            self.tw.setVisible(False)
            process = subprocess.Popen(cmd)
            process.wait()

            if self.upg_path == "terminal":
                text = _("Upgrade finished")

                reboot_required_path = Path("/var/run/reboot-required")
                if reboot_required_path.exists():
                    text += "\n" + _("Reboot required")
                self.label.setText(text)
                self.closeBtn.setVisible(True)
                self.closeBtn.setEnabled(True)

            else:
                app.quit()