示例#1
0
class Integration(Page):
    """
    The integration page.
    """

    NAME = 'OS Integration'

    def __init__(self, parent=None):
        super().__init__(parent)

        self._url_scheme_chk = None  # type:QCheckBox
        self._url_scheme_text = None  # type:QLineEdit

        self._init_widgets()
        self._load_config()

    def _init_widgets(self):

        # os integration
        os_integration = QGroupBox("OS integration")
        self._url_scheme_chk = QCheckBox("Register angr URL scheme (angr://).")
        self._url_scheme_text = QLineEdit()
        self._url_scheme_text.setReadOnly(True)
        url_scheme_lbl = QLabel("Currently registered to:")

        os_layout = QVBoxLayout()
        os_layout.addWidget(self._url_scheme_chk)
        os_layout.addWidget(url_scheme_lbl)
        os_layout.addWidget(self._url_scheme_text)

        os_integration.setLayout(os_layout)

        layout = QVBoxLayout()
        layout.addWidget(os_integration)
        layout.addStretch()
        self.setLayout(layout)

    def _load_config(self):
        scheme = AngrUrlScheme()
        try:
            registered, register_as = scheme.is_url_scheme_registered()
            self._url_scheme_chk.setChecked(registered)
            self._url_scheme_text.setText(register_as)
        except NotImplementedError:
            # the current OS is not supported
            self._url_scheme_chk.setDisabled(True)

    def save_config(self):
        scheme = AngrUrlScheme()
        try:
            registered, _ = scheme.is_url_scheme_registered()
            if registered != self._url_scheme_chk.isChecked():
                # we need to do something
                if self._url_scheme_chk.isChecked():
                    scheme.register_url_scheme()
                else:
                    scheme.unregister_url_scheme()
        except NotImplementedError:
            # the current OS is not supported
            pass
示例#2
0
class GaussianFuzzierSetting(QFrame):
    def __init__(self):
        super().__init__()
        layout = QHBoxLayout()

        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)
        self.mean = QDoubleSpinBox()
        self.mean.setRange(-100, 100)
        self.mean.setStatusTip("The mean (mu) value for Gaussian function.")

        self.sd = QDoubleSpinBox()
        self.sd.setDecimals(3)
        self.sd.setValue(5)
        self.sd.setMinimum(0.1)
        self.sd.setStatusTip("The standard deviation (sigma) value for "
                             "Gaussian function.")

        self.ascending = QCheckBox()
        self.ascending.setIcon(QIcon(':/icons/ascending_icon.png'))
        self.ascending.setStatusTip("Make the fuzzier strictly ascending.")
        self.descending = QCheckBox()
        self.descending.setIcon(QIcon(':/icons/descending_icon.png'))
        self.descending.setStatusTip("Make the fuzzier strictly descending.")

        layout.addWidget(QLabel("Mean"))
        layout.addWidget(self.mean, 1)
        layout.addWidget(QLabel("Standard Deviation"))
        layout.addWidget(self.sd, 1)
        layout.addWidget(self.ascending)
        layout.addWidget(self.descending)

    def get_values(self):
        return (self.mean.value(), self.sd.value(), self.ascending.isChecked(),
                self.descending.isChecked())
class FindDialog(qtw.QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.label = QLabel("Find &what : ")
        self.lineEdit = QLineEdit()
        self.label.setBuddy(self.lineEdit)

        self.caseCheckBox = QCheckBox("&Match & case")
        self.backwardCheckBox = QCheckBox("Search &backward")

        self.findButton = QPushButton("&find")
        self.findButton.setDefault(True)
        self.findButton.setEnabled(False)

        self.closeButton = QPushButton("&close")

        self.lineEdit.textChanged.connect(self.enableFindButton)
        self.findButton.clicked.connect(self.findClicked)
        self.closeButton.clicked.connect(self.close)

        self.topLeftLayout = QHBoxLayout()
        self.topLeftLayout.addWidget(self.label)
        self.topLeftLayout.addWidget(self.lineEdit)

        self.leftLayout = QVBoxLayout()
        self.leftLayout.addLayout(self.topLeftLayout)
        self.leftLayout.addWidget(self.caseCheckBox)
        self.leftLayout.addWidget(self.backwardCheckBox)

        self.rightLayout = QVBoxLayout()
        self.rightLayout.addWidget(self.findButton)
        self.rightLayout.addWidget(self.closeButton)
        self.rightLayout.addStretch()

        self.mainLayout = QHBoxLayout()
        self.mainLayout.addLayout(self.leftLayout)
        self.mainLayout.addLayout(self.rightLayout)
        self.setLayout(self.mainLayout)

        self.setWindowTitle("Find")
        #self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)

    def findClicked(self):
        self.cs = Qt.CaseSensitivity()
        if self.cs == self.caseCheckBox.isChecked():
            self.cs = Qt.CaseSensitivity
        else:
            self.cs = Qt.CaseInsensitive

        if self.backwardCheckBox.isChecked():
            self.findPrevious(self.text, self.cs)
        else:
            self.findNext(self.text, self.cs)

    def enableFindButton(self):
        self.text = self.lineEdit.text()
        print(self.text)
        self.findButton.setEnabled(not self.text == "")
示例#4
0
class FindDialog(QDialog):
    findNext = Signal(str, Qt.CaseSensitivity)
    findPrevious = Signal(str, Qt.CaseSensitivity)

    def __init__(self, parent=None):
        super().__init__(parent)
        label = QLabel("Find &what:")
        self.lineEdit = QLineEdit()
        label.setBuddy(self.lineEdit)

        self.caseCheckBox = QCheckBox("Match &case")
        self.backwardCheckBox = QCheckBox("Search &backward")
        self.findButton = QPushButton("&Find")
        self.findButton.setDefault(True)
        self.findButton.setEnabled(False)
        closeButton = QPushButton("Close")

        self.lineEdit.textChanged.connect(self.enableFindButton)
        self.findButton.clicked.connect(self.findClicked)
        closeButton.clicked.connect(self.close)

        topLeftLayout = QHBoxLayout()
        topLeftLayout.addWidget(label)
        topLeftLayout.addWidget(self.lineEdit)
        leftLayout = QVBoxLayout()
        leftLayout.addLayout(topLeftLayout)
        leftLayout.addWidget(self.caseCheckBox)
        leftLayout.addWidget(self.backwardCheckBox)
        rightLayout = QVBoxLayout()
        rightLayout.addWidget(self.findButton)
        rightLayout.addWidget(closeButton)
        rightLayout.addStretch()
        mainLayout = QHBoxLayout()
        mainLayout.addLayout(leftLayout)
        mainLayout.addLayout(rightLayout)
        self.setLayout(mainLayout)

        self.setWindowTitle("Find")
        self.setFixedHeight(self.sizeHint().height())

    def enableFindButton(self, text):
        self.findButton.setEnabled(bool(text))

    @Slot()
    def findClicked(self):
        text = self.lineEdit.text()
        if self.caseCheckBox.isChecked():
            cs = Qt.CaseSensitive
        else:
            cs = Qt.CaseInsensitive

        if self.backwardCheckBox.isChecked():
            self.findPrevious.emit(text, cs)
        else:
            self.findNext.emit(text, cs)
示例#5
0
class ReportEntryWidget(QGroupBox):
    def __init__(self, header, statement, skipRowsAfter, skipColumnNames,
                 printResultInBold, panel, index, hasError):
        super().__init__()

        self.panel = panel
        self.index = index

        self.headerEdit = QLineEdit(header)
        self.statementEdit = QPlainTextEdit(statement)
        self.skipRowsAfterEdit = QCheckBox('Skip Empty Rows After Statement')
        self.skipColumnNamesEdit = QCheckBox('Skip Column Names')
        self.printResultInBoldEdit = QCheckBox('Print Result in bold')
        self.removeButton = QPushButton('Remove')

        self.skipRowsAfterEdit.setChecked(skipRowsAfter)
        self.skipColumnNamesEdit.setChecked(skipColumnNames)
        self.printResultInBoldEdit.setChecked(printResultInBold)

        self.removeButton.clicked.connect(self.remove)

        if hasError:
            self.statementEdit.setStyleSheet('background-color: #f5dbd9;')

        self.initUi()

    def initUi(self):
        self.layout = QFormLayout()

        self.layout.addRow('Header', self.headerEdit)
        self.layout.addRow('Statement', self.statementEdit)
        self.layout.addRow(' ', self.skipColumnNamesEdit)
        self.layout.addRow(' ', self.skipRowsAfterEdit)
        self.layout.addRow(' ', self.printResultInBoldEdit)
        self.layout.addRow(' ', self.removeButton)

        self.setLayout(self.layout)

    def getHeader(self):
        return self.headerEdit.text()

    def getPlainTextStatement(self):
        return self.statementEdit.toPlainText()

    def shouldSkipColumnNames(self):
        return self.skipColumnNamesEdit.isChecked()

    def shouldSkipRowsAfter(self):
        return self.skipRowsAfterEdit.isChecked()

    def shouldPrintResultInBold(self):
        return self.printResultInBoldEdit.isChecked()

    def remove(self):
        self.panel.removeRow(self)
示例#6
0
class MainTab(Tab):
    def __init__(self, parent):
        self.widget = QWidget()
        self.layout = QFormLayout(parent)

        self.label_lang = QLabel(_('Languages'))
        self.item_lang = AdvComboBox()
        self.item_lang.addItems(get_languages())
        self.item_lang.setCurrentText(Config().configuration.get(
            'current_locale', 'ru_RU'))
        self.layout.addRow(self.label_lang, self.item_lang)

        self.item_auto_save = QSpinBox()
        self.item_auto_save.setMaximum(3600 * 24)
        self.item_auto_save.setValue(
            Config().configuration.get('autosave_interval'))
        self.layout.addRow(_('Auto save') + ' (sec)', self.item_auto_save)

        self.item_show_toolbar = QCheckBox(_('Show toolbar'))
        self.item_show_toolbar.setChecked(
            Config().configuration.get('show_toolbar'))
        self.layout.addRow(self.item_show_toolbar)

        self.item_open_recent_file = QCheckBox(_('Open recent file'))
        self.item_open_recent_file.setChecked(
            Config().configuration.get('open_recent_file'))
        self.layout.addRow(self.item_open_recent_file)

        self.item_use_birthday = QCheckBox(_('Use birthday'))
        self.item_use_birthday.setChecked(
            Config().configuration.get('use_birthday'))
        self.layout.addRow(self.item_use_birthday)

        self.item_check_updates = QCheckBox(_('Check updates'))
        self.item_check_updates.setChecked(
            Config().configuration.get('check_updates'))
        # self.layout.addRow(self.item_check_updates)

        self.widget.setLayout(self.layout)

    def save(self):
        Config().configuration.set('current_locale',
                                   self.item_lang.currentText())
        Config().configuration.set('autosave_interval',
                                   self.item_auto_save.value())
        Config().configuration.set('show_toolbar',
                                   self.item_show_toolbar.isChecked())
        Config().configuration.set('open_recent_file',
                                   self.item_open_recent_file.isChecked())
        Config().configuration.set('use_birthday',
                                   self.item_use_birthday.isChecked())
        Config().configuration.set('check_updates',
                                   self.item_check_updates.isChecked())
示例#7
0
class SettingsEditor(QDialog):
    def __init__(self, tooltipManager: TooltipManager):
        super(SettingsEditor, self).__init__()
        self.tooltipManager = tooltipManager
        self.setWindowFlag(Qt.WindowContextHelpButtonHint, False)
        self.setWindowTitle("Edit IDE settings")
        self.setStyleSheet("background-color: #2D2D30; color: white;")
        self.setFixedSize(500, 150)
        self.setWindowIcon(QIcon(main.resource_path("resources/app_icon")))
        self.vbox = QVBoxLayout()
        self.hbox = QHBoxLayout()
        self.saveButton = QPushButton("Save settings")
        self.cancelButton = QPushButton("Cancel")
        self.resetButton = QPushButton("Reset to defaults")
        self.tooltipLabel = QLabel("<center>Tooltip configuration</centr>")
        self.instructionsTooltopCheckBox = QCheckBox(
            "Show instructions tooltips")
        self.instructionsTooltopCheckBox.setChecked(
            self.tooltipManager.showInstructionTooltips)
        self.numbersTooltipCheckBox = QCheckBox("Show converted numbers")
        self.numbersTooltipCheckBox.setChecked(
            self.tooltipManager.showNumberConversion)
        self.vbox.addWidget(self.tooltipLabel)
        self.vbox.addWidget(self.instructionsTooltopCheckBox)
        self.vbox.addWidget(self.numbersTooltipCheckBox)
        self.hbox.addWidget(self.cancelButton)
        self.hbox.addWidget(self.resetButton)
        self.hbox.addWidget(self.saveButton)
        self.vbox.addLayout(self.hbox)
        self.setLayout(self.vbox)

        self.saveButton.clicked.connect(self.saveButtonClicked)
        self.resetButton.clicked.connect(self.resetButtonClicked)
        self.cancelButton.clicked.connect(self.cancelButtonClicked)

    def saveButtonClicked(self):
        self.tooltipManager.showInstructionTooltips = self.instructionsTooltopCheckBox.isChecked(
        )
        self.tooltipManager.showNumberConversion = self.numbersTooltipCheckBox.isChecked(
        )
        self.accept()

    def resetButtonClicked(self):
        self.instructionsTooltopCheckBox.setChecked(
            TooltipManager.DEFAULT_VALUE_INSTUCTIONS)
        self.numbersTooltipCheckBox.setChecked(
            TooltipManager.DEFAULT_VALUE_NUMBERS)

    def cancelButtonClicked(self):
        self.reject()

    def closeEvent(self, arg__1):
        self.reject()
def _test_check_box(check_box: QCheckBox, level: Level, level_attr: str,
                    expected_value):
    old_checked_status = check_box.isChecked()
    old_attr_value = getattr(level, level_attr)

    check_box.click()

    new_attr_value = getattr(level, level_attr)

    assert check_box.isChecked() != old_checked_status
    assert old_attr_value != new_attr_value
    assert new_attr_value == expected_value
示例#9
0
class ProcessOutputTabWidget(QWidget):
    STARTED_OUTPUT_LINE = "\n" + "-" * 19 + " OUTPUT STARTED " + "-" * 19 + "\n\n"
    ENDED_OUTPUT_LINE = "\n" + "-" * 20 + " OUTPUT ENDED " + "-" * 20 + "\n"

    def __init__(self, *args, **kwargs) -> None:
        super().__init__(*args, **kwargs)

        self.tab_id = -1
        self.layout = QVBoxLayout(self)
        self.txt_output = QTextEdit(self)

        policy = self.txt_output.sizePolicy()
        policy.setHorizontalPolicy(QSizePolicy.MinimumExpanding)
        policy.setHorizontalStretch(1)
        policy.setVerticalPolicy(QSizePolicy.MinimumExpanding)
        policy.setVerticalStretch(1)
        self.txt_output.setSizePolicy(policy)
        self.txt_output.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        # self.layout.setStretch(0,True)
        self.layout.addWidget(self.txt_output)

        sub_layout = QHBoxLayout(self)
        self.chb_clear_on_start = QCheckBox(self, text="Clear on start")
        self.chb_clear_on_start.setChecked(True)
        self.btn_clear = QPushButton(self, text="Clear output")
        sub_layout.addWidget(self.chb_clear_on_start)
        sub_layout.addStretch()
        sub_layout.addWidget(self.btn_clear)

        self.layout.addLayout(sub_layout)
        self.setLayout(self.layout)
        self.txt_output.setReadOnly(True)

        self.btn_clear.clicked.connect(self.clear)

    def clear(self) -> None:
        self.txt_output.clear()

    def append(self, output: str):
        self.txt_output.moveCursor(QTextCursor.End)
        self.txt_output.insertPlainText(output)

    def process_state_changed(self, state: str) -> None:
        if state == ProcessData.STARTED:
            if self.chb_clear_on_start.isChecked():
                self.clear()
            else:
                self.append(self.STARTED_OUTPUT_LINE)

        elif state == ProcessData.ENDED:
            if not self.chb_clear_on_start.isChecked():
                self.append(self.ENDED_OUTPUT_LINE)
示例#10
0
class SoundTab(Tab):
    def __init__(self, parent):
        self.widget = QWidget()
        self.layout = QFormLayout(parent)

        self.sounds = get_sounds()

        self.item_enabled = QCheckBox(_('Enabled'))
        self.item_enabled.setChecked(Config().sound.get('enabled'))
        self.layout.addRow(self.item_enabled)

        self.label_successful = QLabel(_('Successful result'))
        self.item_successful = AdvComboBox()
        self.item_successful.addItems(self.sounds)
        self.item_successful.setCurrentText(Config().sound.get('successful')
                                            or config.sound_dir('ok.wav'))
        self.layout.addRow(self.label_successful, self.item_successful)

        self.label_unsuccessful = QLabel(_('Unsuccessful result'))
        self.item_unsuccessful = AdvComboBox()
        self.item_unsuccessful.addItems(self.sounds)
        self.item_unsuccessful.setCurrentText(
            Config().sound.get('unsuccessful')
            or config.sound_dir('failure.wav'))
        self.layout.addRow(self.label_unsuccessful, self.item_unsuccessful)

        self.item_enabled_rented_card = QCheckBox(
            _('Enable rented card sound'))
        self.item_enabled_rented_card.setChecked(Config().sound.get(
            'enabled_rented_card',
            Config().sound.get('enabled')))
        self.layout.addRow(self.item_enabled_rented_card)

        self.label_rented_card = QLabel(_('Rented card sound'))
        self.item_rented_card = AdvComboBox()
        self.item_rented_card.addItems(self.sounds)
        self.item_rented_card.setCurrentText(
            Config().sound.get('rented_card')
            or config.sound_dir('rented_card.wav'))
        self.layout.addRow(self.label_rented_card, self.item_rented_card)

        self.widget.setLayout(self.layout)

    def save(self):
        Config().sound.set('enabled', self.item_enabled.isChecked())
        Config().sound.set('successful', self.item_successful.currentText())
        Config().sound.set('unsuccessful',
                           self.item_unsuccessful.currentText())
        Config().sound.set('enabled_rented_card',
                           self.item_enabled_rented_card.isChecked())
        Config().sound.set('rented_card', self.item_rented_card.currentText())
class CheckBoxAction(QWidget):
    def __init__(self,
                 parent=None,
                 text: str = "",
                 checked: bool = False,
                 onState: str = "Enabled",
                 offState: str = "Disabled"):
        super().__init__(parent=parent)
        self.onState = onState
        self.offState = offState
        self.setLayout(QtWidgets.QHBoxLayout(self))
        self.avoidInternalChecking = False
        self.label = QLabel(text)
        self.layout().addWidget(self.label)
        self.layout().setMargin(1)
        self.check = QCheckBox(self)
        self.layout().addWidget(self.check)
        self.check.setChecked(checked)
        self.check.setObjectName("QCheckBoxAction")
        self.check.stateChanged.connect(self.changeText)
        self.changeText()

    def winIsLight(self) -> bool:
        mode = darkdetect.isLight()
        if (mode != None):
            return mode
        else:
            return True

    def setText(self, text: str) -> None:
        self.label.setText(text)

    def setEnabled(self, enabled: bool) -> None:
        self.check.setEnabled(enabled)
        self.changeText()

    def isChecked(self) -> bool:
        return self.check.isChecked()

    def setCheckedWithoutInternalChecking(self, value: bool) -> None:
        self.avoidInternalChecking = True
        return self.check.setChecked(value)

    def setChecked(self, value: bool) -> None:
        return self.check.setChecked(value)

    def changeText(self) -> None:
        if (self.check.isChecked()):
            self.check.setText(self.onState)
        else:
            self.check.setText(self.offState)
示例#12
0
class FontLayout(QGridLayout):
    """Font selection"""
    def __init__(self, value, parent=None):
        QGridLayout.__init__(self)
        if not font_is_installed(value[0]):
            print(f"Warning: Font `{value[0]}` is not installed", file=sys.stderr)
        font = tuple_to_qfont(value)
        assert font is not None
        
        # Font family
        self.family = QFontComboBox(parent)
        self.family.setCurrentFont(font)
        self.addWidget(self.family, 0, 0, 1, -1)
        
        # Font size
        self.size = QComboBox(parent)
        self.size.setEditable(True)
        sizelist = list(range(6, 12)) + list(range(12, 30, 2)) + [36, 48, 72]
        size = font.pointSize()
        if size not in sizelist:
            sizelist.append(size)
            sizelist.sort()
        self.size.addItems([str(s) for s in sizelist])
        self.size.setCurrentIndex(sizelist.index(size))
        self.addWidget(self.size, 1, 0)
        
        # Italic or not
        self.italic = QCheckBox(self.tr("Italic"), parent)
        self.italic.setChecked(font.italic())
        self.addWidget(self.italic, 1, 1)
        
        # Bold or not
        self.bold = QCheckBox(self.tr("Bold"), parent)
        self.bold.setChecked(font.bold())
        self.addWidget(self.bold, 1, 2)
        
    def get_font(self):
        font = self.family.currentFont()
        font.setItalic(self.italic.isChecked())
        font.setBold(self.bold.isChecked())
        font.setPointSize(int(self.size.currentText()))
        return qfont_to_tuple(font)

    def setStyleSheet(self, style):
        self.family.setStyleSheet(style)
        self.size.setStyleSheet(style)
        self.italic.setStyleSheet(style)
        self.bold.setStyleSheet(style)
class App(QWidget):
    """The primary class"""
    def __init__(self, parent=None):
        super(App, self).__init__(parent)

        self.layout = QVBoxLayout()

        self.top_layout = QHBoxLayout()
        self.open_button = QPushButton("Open")
        self.open_button.clicked.connect(self.getfile)
        self.top_layout.addWidget(self.open_button)
        self.file_path = QLineEdit()
        self.top_layout.addWidget(self.file_path)
        self.dry_run_checkbox = QCheckBox("Dryrun")
        self.dry_run_checkbox.setChecked(False)
        self.dry_run_checkbox.toggled.connect(lambda: self.set_dry_run())
        self.is_dryrun = False
        self.top_layout.addWidget(self.dry_run_checkbox)

        self.layout.addLayout(self.top_layout)

        self.contents = QTextEdit()
        self.layout.addWidget(self.contents)

        self.help = "help"
        self.bottom_layout = QHBoxLayout()
        self.help_button = QPushButton("Help")
        self.help_button.clicked.connect(lambda: self.set_info(self.help))
        self.bottom_layout.addWidget(self.help_button)
        self.bottom_layout.addStretch(1)
        self.run_button = QPushButton("Run")
        self.run_button.clicked.connect(self.fix_and_clean)
        self.bottom_layout.addWidget(self.run_button)

        self.layout.addLayout(self.bottom_layout)

        self.setLayout(self.layout)
        self.setWindowTitle("OpenMW NIF Converter")

        self.processor = Processor(self.contents.append)

    def getfile(self):
        """function to retrieve the directory to act on"""
        acting_directory = QFileDialog.getExistingDirectory(
            self, 'Open directory')
        self.acting_directory = str(acting_directory)
        self.file_path.setText(self.acting_directory)

    def set_info(self, info):
        """Sets the contents of the notification TextEdit"""
        self.contents.setText(info)

    def fix_and_clean(self):
        """Runs the main processing script"""
        self.processor.process_dir(self.directory, self.is_dryrun)

    def set_dry_run(self):
        """Checks if the run will actually be attempted"""
        if self.dry_run_checkbox.isChecked():
            self.is_dryrun = True
示例#14
0
class SelectFolderDialog(QFileDialog):
    """
    Create a custom Folder Dialog with an option to import files as nodes
    """
    def __init__(self, *args, **kwargs):
        super(SelectFolderDialog, self).__init__(*args, **kwargs)
        self.setOption(QFileDialog.DontUseNativeDialog)
        self.setFileMode(QFileDialog.Directory)

        #QFileDialog.getExistingDirectory(self, 'Select Download Folder', datadir)) #, QFileDialog.ShowDirsOnly
        #self.mainWindow = self.parent()

        self.optionNodes = QCheckBox("Add selected files as nodes", self)
        self.optionNodes.clicked.connect(self.optionNodesClick)
        #self.optionNodes.setCheckState(Qt.CheckState.Checked)

        layout = self.layout()
        row = layout.rowCount()
        layout.addWidget(QLabel('Options'), row, 0)

        options = QHBoxLayout()
        options.addWidget(self.optionNodes)
        options.addStretch(1)
        layout.addLayout(options, row, 1, 1, 2)
        self.setLayout(layout)

        #if self.exec_():
        #if os.path.isfile(self.selectedFiles()[0]):

    def optionNodesClick(self):
        if self.optionNodes.isChecked():
            self.setFileMode(QFileDialog.ExistingFiles)
        else:
            self.setFileMode(QFileDialog.Directory)
示例#15
0
class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        self.lbl = QLabel()
        self.chx = QCheckBox('Do you like dogs?')
        self.btn = QPushButton('Push me!')

        layout = QVBoxLayout()
        layout.addWidget(self.lbl)
        layout.addWidget(self.chx)
        layout.addWidget(self.btn)

        self.setLayout(layout)

        self.btn.clicked.connect(
            lambda: self.btn_click(self.chx.isChecked(), self.lbl))

        self.show()

    def btn_click(self, chk, lbl):
        if chk:
            lbl.setText('I guess you like dogs')
        else:
            lbl.setText("Dog hater then")
示例#16
0
class ChangeChannel(QDialog):
    change_channel = Signal(int, bool)
    """Allows the user to change the channel."""
    def __init__(self):
        super(ChangeChannel, self).__init__()

        self.setModal(True)

        self.stop_recording = QCheckBox(self)
        self.channel = QSpinBox(self)

        self.channel.setRange(0, 9999)

        self.button_boxes = QDialogButtonBox(QDialogButtonBox.Ok
                                             | QDialogButtonBox.Cancel)

        self.button_boxes.accepted.connect(self.accepted)
        self.button_boxes.rejected.connect(lambda: self.close())

        self.layout = QFormLayout(self)
        self.layout.addRow("Channel:", self.channel)
        self.layout.addRow("Stop recording if in progress:",
                           self.stop_recording)
        self.layout.addRow(self.button_boxes)

        self.setWindowTitle("Change TiVo channel")
        self.resize(320, 100)

    @Slot()
    def accepted(self):
        self.change_channel.emit(self.channel.value(),
                                 self.stop_recording.isChecked())
        self.close()
示例#17
0
class ElaWidget(ToolWidget):
    def __init__(self, image, parent=None):
        super(ElaWidget, self).__init__(parent)

        params_layout = QHBoxLayout()
        params_layout.addWidget(QLabel(self.tr('Quality:')))
        self.quality_spin = QSpinBox()
        self.quality_spin.setRange(0, 100)
        self.quality_spin.setSuffix(self.tr(' %'))
        self.quality_spin.valueChanged.connect(self.process)
        params_layout.addWidget(self.quality_spin)

        params_layout.addWidget(QLabel(self.tr('Scale:')))
        self.scale_spin = QSpinBox()
        self.scale_spin.setRange(1, 100)
        self.scale_spin.valueChanged.connect(self.process)
        params_layout.addWidget(self.scale_spin)

        self.equalize_check = QCheckBox(self.tr('Equalized'))
        self.equalize_check.stateChanged.connect(self.process)
        params_layout.addWidget(self.equalize_check)

        params_layout.addStretch()
        default_button = QPushButton(self.tr('Default'))
        default_button.clicked.connect(self.default)
        params_layout.addWidget(default_button)

        self.image = image
        self.viewer = ImageViewer(self.image, self.image)
        self.default()
        self.process()

        main_layout = QVBoxLayout()
        main_layout.addLayout(params_layout)
        main_layout.addWidget(self.viewer)
        self.setLayout(main_layout)

    def process(self):
        equalize = self.equalize_check.isChecked()
        self.scale_spin.setEnabled(not equalize)
        start = time()
        quality = self.quality_spin.value()
        scale = self.scale_spin.value()
        compressed = compress_jpeg(self.image, quality)
        if not equalize:
            ela = cv.convertScaleAbs(cv.subtract(compressed, self.image), None,
                                     scale)
        else:
            ela = cv.merge([
                cv.equalizeHist(c)
                for c in cv.split(cv.absdiff(compressed, self.image))
            ])
        self.viewer.update_processed(ela)
        self.info_message.emit(
            self.tr('Error Level Analysis = {}'.format(elapsed_time(start))))

    def default(self):
        self.quality_spin.setValue(75)
        self.scale_spin.setValue(20)
示例#18
0
class DocumentFilterView(object):
    def __init__(self, documentFilter : DocumentFilter):
        self.documentFilter = documentFilter

        self.activeCheckBox = QCheckBox()
        self.activeCheckBox.setChecked(documentFilter.active)
        self.activeCheckBox.stateChanged.connect(self.onActiveCheckBoxChanged)
        self.activeCheckBox.setText(self.documentFilter.uniqueFilterLabel)

        self.negateCheckBox = QCheckBox()
        self.negateCheckBox.setChecked(documentFilter.negate)
        self.negateCheckBox.stateChanged.connect(self.onNegateCheckBoxChanged)
        self.negateCheckBox.setText('Negate')

        self.container = QWidget()
        layout = QHBoxLayout()
        self.container.setLayout(layout)
        self.container.layout().addWidget(self.activeCheckBox)
        self.container.layout().addWidget(self.negateCheckBox)

        if documentFilter.hasStringArg:
            self.container.layout().addWidget(QtWidgets.QLabel("Input:"))
            self.textEdit = QLineEdit()
            self.textEdit.setText(documentFilter.args)
            self.textEdit.textChanged.connect(self.onTextEditChanged)
            self.container.layout().addWidget(self.textEdit)

        self.container.layout().setAlignment(QtCore.Qt.AlignLeft)
        self.container.adjustSize()

        self.container.setContentsMargins(0,0,0,0)
        layout.setContentsMargins(0,0,0,0)
        self.container.setFixedHeight(20)
    
    def isFilterActive(self):
        return self.activeCheckBox.isChecked() if not self.negateCheckBox.isChecked() else not self.activeCheckBox.isChecked()

    def onActiveCheckBoxChanged(self, _):
        self.documentFilter.setActive(self.activeCheckBox.isChecked())
    
    def onNegateCheckBoxChanged(self, _):
        self.documentFilter.setNegateFilter(self.negateCheckBox.isChecked())

    def onTextEditChanged(self, text):
        self.documentFilter.setArgs(text)
示例#19
0
class EchoWidget(ToolWidget):
    def __init__(self, image, parent=None):
        super(EchoWidget, self).__init__(parent)

        self.radius_spin = QSpinBox()
        self.radius_spin.setRange(1, 15)
        self.radius_spin.setSuffix(self.tr(' px'))
        self.radius_spin.setValue(2)
        self.radius_spin.setToolTip(self.tr('Laplacian filter radius'))

        self.contrast_spin = QSpinBox()
        self.contrast_spin.setRange(0, 100)
        self.contrast_spin.setSuffix(self.tr(' %'))
        self.contrast_spin.setValue(85)
        self.contrast_spin.setToolTip(self.tr('Output tonality compression'))

        self.gray_check = QCheckBox(self.tr('Grayscale'))
        self.gray_check.setToolTip(self.tr('Desaturated output mode'))

        self.image = image
        self.viewer = ImageViewer(self.image, self.image, None)
        self.process()

        self.radius_spin.valueChanged.connect(self.process)
        self.contrast_spin.valueChanged.connect(self.process)
        self.gray_check.stateChanged.connect(self.process)

        params_layout = QHBoxLayout()
        params_layout.addWidget(QLabel(self.tr('Radius:')))
        params_layout.addWidget(self.radius_spin)
        params_layout.addWidget(QLabel(self.tr('Contrast:')))
        params_layout.addWidget(self.contrast_spin)
        params_layout.addWidget(self.gray_check)
        params_layout.addStretch()

        main_layout = QVBoxLayout()
        main_layout.addLayout(params_layout)
        main_layout.addWidget(self.viewer)
        self.setLayout(main_layout)

    def process(self):
        start = time()
        kernel = 2 * self.radius_spin.value() + 1
        contrast = int(self.contrast_spin.value() / 100 * 255)
        lut = create_lut(0, contrast)
        laplace = []
        for channel in cv.split(self.image):
            deriv = np.fabs(cv.Laplacian(channel, cv.CV_64F, None, kernel))
            deriv = cv.normalize(deriv, None, 0, 255, cv.NORM_MINMAX,
                                 cv.CV_8UC1)
            laplace.append(cv.LUT(deriv, lut))
        result = cv.merge(laplace)
        if self.gray_check.isChecked():
            result = bgr_to_gray3(result)
        self.viewer.update_processed(result)
        self.info_message.emit('Echo Edge Filter = {}'.format(
            elapsed_time(start)))
class OperationGroup(QGroupBox):
    operation_changed = Signal()

    def __init__(self, title: str, parent: "QWidget" = None):
        super().__init__(title, parent)

        self._enabled_status_checkbox = QCheckBox("Enabled")
        self._enabled_status_checkbox.setChecked(False)

        self._main_layout = QVBoxLayout()

        self._central_widget = QWidget()
        self._central_widget.setEnabled(
            self._enabled_status_checkbox.isChecked())

        self._central_layout = QVBoxLayout()
        self._central_widget.setLayout(self._central_layout)

        self._main_layout.addWidget(self._enabled_status_checkbox)
        self._main_layout.addWidget(self._central_widget)

        self.setLayout(self._main_layout)

        self._enabled_status_checkbox.stateChanged.connect(self._changeEnabled)

    def get_operation(self) -> Callable:
        raise NotImplementedError()

    def fill_values_from_dataset(self, dataset: "Dataset"):
        pass

    def is_checked(self) -> bool:
        return self._enabled_status_checkbox.isChecked()

    def addWidget(self, widget: "QWidget"):
        self._central_layout.addWidget(widget)

    def _changeEnabled(self, state: int):
        LOGGER.debug("%s state changed to: %s", self, self.is_checked())

        self._enabled_status_checkbox.setChecked(state)
        self._central_widget.setEnabled(state)

        self.operation_changed.emit()
示例#21
0
class Preferences(QMainWindow):
    def __init__(self, app, default, qmp, tt):

        QMainWindow.__init__(self)

        self.app = app

        self.default = default

        self.qmp = qmp

        self.init_ui()
        self.show()

    def init_ui(self):

        self.setWindowTitle('Preferences')
        self.setGeometry(100, 100, 400, 200)

        grid = QVBoxLayout()
        grid.setSpacing(15)

        self.darkmode = QCheckBox('Dark Mode', self)

        self.app.setStyle("Fusion")

        if QGuiApplication.palette() != self.default:
            self.darkmode.setChecked(True)

        palette = QPalette()
        palette.setColor(QPalette.Window, QColor(25, 25, 25))  # 53 53 53
        palette.setColor(QPalette.WindowText, Qt.white)
        palette.setColor(QPalette.Base, QColor(53, 53, 53))  # 25 25 25
        palette.setColor(QPalette.AlternateBase, QColor(53, 53, 53))
        palette.setColor(QPalette.ToolTipBase, Qt.white)
        palette.setColor(QPalette.ToolTipText, Qt.white)
        palette.setColor(QPalette.Text, Qt.white)
        palette.setColor(QPalette.Button, QColor(53, 53, 53))
        palette.setColor(QPalette.ButtonText, Qt.white)
        palette.setColor(QPalette.BrightText, Qt.red)
        palette.setColor(QPalette.Link, QColor(42, 130, 218))
        palette.setColor(QPalette.Highlight, QColor(42, 130, 218))
        palette.setColor(QPalette.HighlightedText, Qt.black)

        self.darkmode.toggled.connect(lambda: self.app.setPalette(palette)
                                      if self.darkmode.isChecked() else self.
                                      app.setPalette(self.default))

        grid.addWidget(self.darkmode, 1)

        center = QWidget()
        center.setLayout(grid)
        self.setCentralWidget(center)

        self.show()
示例#22
0
    def _askForFieldsDialog(self, options, fields_type="inputs"):
        #Display a dialog to ask the user to choose what inputs/outputs they want
        dialog = QDialog(self)

        dialog.setWindowTitle(f"Select the model {fields_type.upper()}")
        dialogButtons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        dialogButtons.button(QDialogButtonBox.Ok).setDisabled(0)
        dialogButtons.accepted.connect(dialog.accept)
        dialogButtons.rejected.connect(dialog.reject)
        
        mainLayout = QVBoxLayout(dialog)
        scroll = QScrollArea(dialog)
        scroll.setWidgetResizable(True)
        layoutWidget = QWidget()
        layout = QVBoxLayout(layoutWidget)
        scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        scroll.setWidget(layoutWidget)

        chosenFields=[]
        checkboxes=[]

        def handleCheckboxClicked():
            dialogButtons.button(QDialogButtonBox.Ok).setDisabled(1)
            count = 0
            for checkbox in checkboxes:
                if checkbox.isChecked():
                    count += 1
            if fields_type.lower() == "output":
                setDisabled = True if count > 1 else False
            else:
                setDisabled = True if count == 0 else False
            dialogButtons.button(QDialogButtonBox.Ok).setDisabled(setDisabled)

        for input in options:
            checkbox = QCheckBox(text=input)
            checkbox.clicked.connect(handleCheckboxClicked)
            checkbox.setChecked(True)
            checkboxes.append(checkbox)
            layout.addWidget(checkbox)

        mainLayout.addWidget(QLabel(text=f"Please select the {fields_type.lower()} from the following:"))
        mainLayout.addWidget(scroll)
        mainLayout.addWidget(dialogButtons)
        dialog.setLayout(mainLayout)

        handleCheckboxClicked()

        if dialog.exec_() == QDialog.Accepted:
            for checkbox in checkboxes:
                if checkbox.isChecked():
                    chosenFields.append(checkbox.text())
            self.logger.log(f"The chosen {fields_type.lower()} are: "+ ', '.join(chosenFields), type ="INFO")
            return chosenFields
        else:
            return []
示例#23
0
class CheatSettingsBox(QGroupBox):
    def __init__(self, game: Game, apply_settings: Callable[[], None]) -> None:
        super().__init__("Cheat Settings")
        self.main_layout = QVBoxLayout()
        self.setLayout(self.main_layout)

        self.red_ato_checkbox = QCheckBox()
        self.red_ato_checkbox.setChecked(game.settings.show_red_ato)
        self.red_ato_checkbox.toggled.connect(apply_settings)

        self.frontline_cheat_checkbox = QCheckBox()
        self.frontline_cheat_checkbox.setChecked(game.settings.enable_frontline_cheats)
        self.frontline_cheat_checkbox.toggled.connect(apply_settings)

        self.base_capture_cheat_checkbox = QCheckBox()
        self.base_capture_cheat_checkbox.setChecked(
            game.settings.enable_base_capture_cheat
        )
        self.base_capture_cheat_checkbox.toggled.connect(apply_settings)

        self.red_ato = QLabeledWidget("Show Red ATO:", self.red_ato_checkbox)
        self.main_layout.addLayout(self.red_ato)
        self.frontline_cheat = QLabeledWidget(
            "Enable Frontline Cheats:", self.frontline_cheat_checkbox
        )
        self.main_layout.addLayout(self.frontline_cheat)
        self.base_capture_cheat = QLabeledWidget(
            "Enable Base Capture Cheat:", self.base_capture_cheat_checkbox
        )
        self.main_layout.addLayout(self.base_capture_cheat)

    @property
    def show_red_ato(self) -> bool:
        return self.red_ato_checkbox.isChecked()

    @property
    def show_frontline_cheat(self) -> bool:
        return self.frontline_cheat_checkbox.isChecked()

    @property
    def show_base_capture_cheat(self) -> bool:
        return self.base_capture_cheat_checkbox.isChecked()
示例#24
0
class Form(QDialog):
    settings_fp = "./salty_papers.config"
    def __init__(self, parent=None, settings_fp="./salty_papers.config"):
        self.settings_fp
        super(Form, self).__init__(parent)
        # Create widgets
        print(os.getcwd())
        with open(self.settings_fp, "r") as jsonFile:
            settings = json.load(jsonFile)
        print(settings["sub_reddits"])
        #self.sub_reddit_label = QLabel("Subreddits")
        self.sub_reddit_label = QLabel(os.getcwd())
        self.sub_reddit_input = QLineEdit(", ".join(settings["sub_reddits"]))
        self.interval_label = QLabel("Interval (seconds)")
        self.interval_input = QLineEdit(str(settings["interval"]))
        self.post_max_label = QLabel("Lowest Post Rank:")
        self.post_max_input = QLineEdit(str(settings["post_max"]))
        self.randomize_label = QLabel("Randomize")
        self.randomize_checkbox = QCheckBox()
        self.randomize_checkbox.setChecked(bool(settings["randomize"]))
        self.save_button = QPushButton("Save Settings")
        self.setWindowTitle("Salty Papers Settings")
        # Create layout and add widgets
        layout = QVBoxLayout()
        layout.addWidget(self.sub_reddit_label)
        layout.addWidget(self.sub_reddit_input)
        layout.addWidget(self.interval_label)
        layout.addWidget(self.interval_input)
        layout.addWidget(self.randomize_label)
        layout.addWidget(self.randomize_checkbox)
        layout.addWidget(self.post_max_label)
        layout.addWidget(self.post_max_input)
        layout.addWidget(self.save_button)
        # Set dialog layout
        self.setLayout(layout)
        # Add button signal to greetings slot
        self.save_button.clicked.connect(self.save_config)
        print("window built")
    def save_config(self):
        sub_reddits = list(self.sub_reddit_input.text().replace(" ", "").split(","))
        interval = int(self.interval_input.text())
        randomize = bool(self.randomize_checkbox.isChecked())
        post_max = int(self.post_max_input.text())
        with open(self.settings_fp, "r") as jsonFile:
            settings = json.load(jsonFile)

        settings["sub_reddits"] = sub_reddits
        settings["interval"] = interval
        settings["randomize"] = randomize
        settings["post_max"] = post_max
        with open(self.settings_fp, "w") as jsonFile:
            json.dump(settings, jsonFile)
        
        self.close()
def saveAndCloseSettings(modeSelector: QtWidgets.QComboBox,
                         plainAppearance: QtWidgets.QCheckBox,
                         algorithmSelector: QtWidgets.QComboBox,
                         settingsWindow, levelSelector: QtWidgets.QComboBox,
                         create_subfolder: QtWidgets.QCheckBox, parent,
                         autoUpdate: QtWidgets.QCheckBox):
    global settings, forceClose
    if (algorithmSelector.currentIndex() == 0):
        settings['default_algorithm'] = "Deflated"
    elif (algorithmSelector.currentIndex() == 1):
        settings['default_algorithm'] = "BZIP2"
    elif (algorithmSelector.currentIndex() == 2):
        settings['default_algorithm'] = "LZMA"
    else:
        settings['default_algorithm'] = "Without Compression"

    settings["create_subdir"] = create_subfolder.isChecked()

    if (modeSelector.currentIndex() == 0):
        settings['mode'] = 'light'
    elif (modeSelector.currentIndex() == 1):
        settings['mode'] = 'dark'
    else:
        settings['mode'] = 'auto'

    settings["plainAppearance"] = plainAppearance.isChecked()

    settings["autoCheckForUpdates"] = autoUpdate.isChecked()

    parent.loadStyleSheet()

    settings["default_level"] = levelSelector.currentIndex() + 1

    forceClose = True
    settingsWindow.close()
    saveSettings(silent=True,
                 create_subdir=settings['create_subdir'],
                 default_level=settings['default_level'],
                 default_algorithm=settings['default_algorithm'],
                 mode=settings['mode'],
                 autoCheckForUpdates=settings["autoCheckForUpdates"])
示例#26
0
class FindToolBar(QToolBar):

    find = QtCore.Signal(str, QWebEnginePage.FindFlags)

    def __init__(self):
        super(FindToolBar, self).__init__()
        self._line_edit = QLineEdit()
        self._line_edit.setClearButtonEnabled(True)
        self._line_edit.setPlaceholderText("Find...")
        self._line_edit.setMaximumWidth(300)
        self._line_edit.returnPressed.connect(self._find_next)
        self.addWidget(self._line_edit)

        self._previous_button = QToolButton()
        self._previous_button.setIcon(
            QIcon(':/qt-project.org/styles/commonstyle/images/up-32.png'))
        self._previous_button.clicked.connect(self._find_previous)
        self.addWidget(self._previous_button)

        self._next_button = QToolButton()
        self._next_button.setIcon(
            QIcon(':/qt-project.org/styles/commonstyle/images/down-32.png'))
        self._next_button.clicked.connect(self._find_next)
        self.addWidget(self._next_button)

        self._case_sensitive_checkbox = QCheckBox('Case Sensitive')
        self.addWidget(self._case_sensitive_checkbox)

        self._hideButton = QToolButton()
        self._hideButton.setShortcut(QKeySequence(Qt.Key_Escape))
        self._hideButton.setIcon(
            QIcon(':/qt-project.org/styles/macstyle/images/closedock-16.png'))
        self._hideButton.clicked.connect(self.hide)
        self.addWidget(self._hideButton)

    def focus_find(self):
        self._line_edit.setFocus()

    def _emit_find(self, backward):
        needle = self._line_edit.text().strip()
        if needle:
            flags = QWebEnginePage.FindFlags()
            if self._case_sensitive_checkbox.isChecked():
                flags |= QWebEnginePage.FindCaseSensitively
            if backward:
                flags |= QWebEnginePage.FindBackward
            self.find.emit(needle, flags)

    def _find_next(self):
        self._emit_find(False)

    def _find_previous(self):
        self._emit_find(True)
示例#27
0
    def closeEvent(self, event):
        if sys.platform != "darwin" and self.app.show_minimize_message:
            msg = QMessageBox(self)
            msg.setWindowTitle("App Minimized")
            msg.setText("The app will be minimized to your system tray.")
            msg.setIcon(QMessageBox.Icon.Information)
            check = QCheckBox("Don't show again.")
            msg.setCheckBox(check)
            msg.exec_()

            self.app.show_minimize_message = not check.isChecked()
            Settings.set_param("minimize", not self.app.show_minimize_message)
示例#28
0
class MyRow(QWidget):
    def __init__(self, text, parent=None):
        super(MyRow, self).__init__(parent)
        self.row = QHBoxLayout()
        self.cb = QCheckBox(text)
        self.row.addWidget(self.cb)
        self.setLayout(self.row)

    def isChecked(self):
        return self.cb.isChecked()

    def getText(self):
        return self.cb.text()
    def WidgetBlockOnCheck(Activation: QtWidgets.QCheckBox, activate: bool):
        # print(Activation.__class__.__name__)

        if Activation.__class__.__name__ == "QCheckBox":
            if Activation.isChecked() == activate:
                Activation.setChecked(activate)
                Activation.setEnabled(activate)
            else:
                Activation.setChecked(False)
                Activation.setEnabled(activate)

        elif Activation.__class__.__name__ == "QPushButton":
            Activation.setEnabled(activate)
class DetrendGroup(AbstractProcessGroup):
    def __init__(self, title, fs):
        AbstractProcessGroup.__init__(self, title, fs)
        self.setupLayout()

    def setupLayout(self):
        mainLayout = QFormLayout(self)

        self._toggle = True
        self.constCheck = QCheckBox('Constant')
        mainLayout.addRow(self.constCheck)
        self.constCheck.setChecked(True)
        self.lineCheck = QCheckBox('Linear')
        mainLayout.addRow(self.lineCheck)

        self.constCheck.clicked.connect(self.toggle)
        self.lineCheck.clicked.connect(self.toggle)

    def toggle(self):
        self._toggle = not self._toggle
        self.constCheck.setChecked(self._toggle)
        self.lineCheck.setChecked(not self._toggle)

    def process(self, inData):
        if self.constCheck.isChecked():
            dType = 'constant'
        elif self.lineCheck.isChecked():
            dType = 'linear'
        print(dType)
        outData = []
        progStep = 100.0 / len(inData)
        prog = 0
        for chData in inData:
            det = signal.detrend(chData, type=dType)
            outData.append(det)
            prog = prog + progStep
            self.progress.emit(int(prog))
        return outData
示例#31
0
class FindToolBar(QToolBar):

    find = QtCore.Signal(str, QWebEnginePage.FindFlags)

    def __init__(self):
        super(FindToolBar, self).__init__()
        self._line_edit = QLineEdit()
        self._line_edit.setClearButtonEnabled(True)
        self._line_edit.setPlaceholderText("Find...")
        self._line_edit.setMaximumWidth(300)
        self._line_edit.returnPressed.connect(self._find_next)
        self.addWidget(self._line_edit)

        self._previous_button = QToolButton()
        self._previous_button.setIcon(QIcon(':/qt-project.org/styles/commonstyle/images/up-32.png'))
        self._previous_button.clicked.connect(self._find_previous)
        self.addWidget(self._previous_button)

        self._next_button = QToolButton()
        self._next_button.setIcon(QIcon(':/qt-project.org/styles/commonstyle/images/down-32.png'))
        self._next_button.clicked.connect(self._find_next)
        self.addWidget(self._next_button)

        self._case_sensitive_checkbox = QCheckBox('Case Sensitive')
        self.addWidget(self._case_sensitive_checkbox)

        self._hideButton = QToolButton()
        self._hideButton.setShortcut(QKeySequence(Qt.Key_Escape))
        self._hideButton.setIcon(QIcon(':/qt-project.org/styles/macstyle/images/closedock-16.png'))
        self._hideButton.clicked.connect(self.hide)
        self.addWidget(self._hideButton)

    def focus_find(self):
        self._line_edit.setFocus()

    def _emit_find(self, backward):
        needle =  self._line_edit.text().strip()
        if needle:
            flags = QWebEnginePage.FindFlags()
            if self._case_sensitive_checkbox.isChecked():
                flags |= QWebEnginePage.FindCaseSensitively
            if backward:
                flags |= QWebEnginePage.FindBackward
            self.find.emit(needle, flags)

    def _find_next(self):
        self._emit_find(False)

    def _find_previous(self):
        self._emit_find(True)
示例#32
0
class SelectFolderDialog(QFileDialog):
    """
    Create a custom Folder Dialog with an option to import files as nodes
    """

    def __init__(self,*args,**kwargs):
        super(SelectFolderDialog,self).__init__(*args,**kwargs)
        self.setOption(QFileDialog.DontUseNativeDialog)
        self.setFileMode(QFileDialog.Directory)


        #QFileDialog.getExistingDirectory(self, 'Select Download Folder', datadir)) #, QFileDialog.ShowDirsOnly
        #self.mainWindow = self.parent()

        self.optionNodes = QCheckBox("Add selected files as nodes",self)
        self.optionNodes.clicked.connect(self.optionNodesClick)
        #self.optionNodes.setCheckState(Qt.CheckState.Checked)

        layout = self.layout()
        row = layout.rowCount()
        layout.addWidget(QLabel('Options'),row,0)

        options = QHBoxLayout()
        options.addWidget(self.optionNodes)
        options.addStretch(1)
        layout.addLayout(options,row,1,1,2)
        self.setLayout(layout)

        #if self.exec_():
            #if os.path.isfile(self.selectedFiles()[0]):
            
    def optionNodesClick(self):
        if self.optionNodes.isChecked():
            self.setFileMode(QFileDialog.ExistingFiles)
        else:
            self.setFileMode(QFileDialog.Directory)
示例#33
0
class ExportFileDialog(QFileDialog):
    """
    Create a custom Export-File Dialog with options like BOM etc.
    """

    def __init__(self,*args,**kwargs):
        super(ExportFileDialog,self).__init__(*args,**kwargs)

        self.mainWindow = self.parent()
        self.setWindowTitle("Export nodes to CSV")
        self.setAcceptMode(QFileDialog.AcceptSave)
        self.setOption(QFileDialog.DontUseNativeDialog)
        #self.setFilter("CSV Files (*.csv)")
        self.setDefaultSuffix("csv")

        self.optionBOM = QCheckBox("Use a BOM",self)
        self.optionBOM.setCheckState(Qt.CheckState.Checked)

        self.optionLinebreaks = QCheckBox("Remove line breaks",self)
        self.optionLinebreaks.setCheckState(Qt.CheckState.Checked)

        self.optionSeparator = QComboBox(self)
        self.optionSeparator.insertItems(0, [";","\\t",","])
        self.optionSeparator.setEditable(True)

        #self.optionLinebreaks.setCheckState(Qt.CheckState.Checked)

        self.optionWide = QCheckBox("Convert to wide format (experimental feature)",self)
        self.optionWide.setCheckState(Qt.CheckState.Unchecked)

        # if none or all are selected, export all
        # if one or more are selected, export selective
        self.optionAll = QComboBox(self)
        self.optionAll.insertItems(0, ['All nodes (faster for large datasets, ordered by internal ID)','Selected nodes (ordered like shown in nodes view)'])
        if self.mainWindow.tree.noneOrAllSelected():
            self.optionAll.setCurrentIndex(0)
        else:
            self.optionAll.setCurrentIndex(1)

        layout = self.layout()
        row = layout.rowCount()
        layout.addWidget(QLabel('Options'),row,0)

        options = QHBoxLayout()
        options.addWidget(self.optionBOM)
        options.addWidget(self.optionLinebreaks)
        options.addWidget(QLabel('Separator'))
        options.addWidget(self.optionSeparator)
        options.addStretch(1)

        layout.addLayout(options,row,1,1,2)

        layout.addWidget(QLabel('Post processing'),row+1,0)
        layout.addWidget(self.optionWide,row+1,1,1,2)

        layout.addWidget(QLabel('Export mode'),row+2,0)
        layout.addWidget(self.optionAll,row+2,1,1,2)
        self.setLayout(layout)

        if self.exec_():

            if os.path.isfile(self.selectedFiles()[0]):
                os.remove(self.selectedFiles()[0])
            output = open(self.selectedFiles()[0], 'w', newline='', encoding='utf8')
            if self.optionBOM.isChecked() and not self.optionWide.isChecked():
                output.write('\ufeff')

            try:
                if self.optionAll.currentIndex() == 0:
                    self.exportAllNodes(output)
                else:
                    self.exportSelectedNodes(output)
            finally:
                output.close()

            if self.optionWide.isChecked():
                self.convertToWideFormat(self.selectedFiles()[0])


    def exportSelectedNodes(self,output):
        progress = ProgressBar("Exporting data...", self.mainWindow)

        #indexes = self.mainWindow.tree.selectionModel().selectedRows()
        #if child nodes should be exported as well, uncomment this line an comment the previous one
        indexes = self.mainWindow.tree.selectedIndexesAndChildren()
        progress.setMaximum(len(indexes))

        try:
            delimiter = self.optionSeparator.currentText()
            delimiter = delimiter.encode('utf-8').decode('unicode_escape')
            writer = csv.writer(output, delimiter=delimiter, quotechar='"', quoting=csv.QUOTE_ALL, doublequote=True,
                                lineterminator='\r\n')


            #headers
            row = [str(val) for val in self.mainWindow.tree.treemodel.getRowHeader()]
            if self.optionLinebreaks.isChecked():
                row = [val.replace('\n', ' ').replace('\r',' ') for val in row]

            writer.writerow(row)

            #rows
            for no in range(len(indexes)):
                if progress.wasCanceled:
                    break

                row = [str(val) for val in self.mainWindow.tree.treemodel.getRowData(indexes[no])]
                if self.optionLinebreaks.isChecked():
                    row = [val.replace('\n', ' ').replace('\r',' ') for val in row]

                writer.writerow(row)

                progress.step()

        finally:
            progress.close()


    def exportAllNodes(self,output):
        progress = ProgressBar("Exporting data...", self.mainWindow)
        progress.setMaximum(Node.query.count())


        try:
            delimiter = self.optionSeparator.currentText()
            delimiter = delimiter.encode('utf-8').decode('unicode_escape')
            writer = csv.writer(output, delimiter=delimiter, quotechar='"', quoting=csv.QUOTE_ALL, doublequote=True,
                                lineterminator='\r\n')

            #headers
            row = ["level", "id", "parent_id", "object_id", "object_type", "query_status", "query_time",
                   "query_type"]
            for key in self.mainWindow.tree.treemodel.customcolumns:
                row.append(key)
            if self.optionLinebreaks.isChecked():
                row = [val.replace('\n', ' ').replace('\r',' ') for val in row]

            writer.writerow(row)

            #rows
            page = 0

            while True:
                allnodes = Node.query.offset(page * 5000).limit(5000)
                if allnodes.count() == 0:
                    break
                for node in allnodes:
                    if progress.wasCanceled:
                        break
                    row = [node.level, node.id, node.parent_id, node.objectid, node.objecttype,
                           node.querystatus, node.querytime, node.querytype]
                    for key in self.mainWindow.tree.treemodel.customcolumns:
                        row.append(node.getResponseValue(key))

                    if self.optionLinebreaks.isChecked():
                        row = [str(val).replace('\n', ' ').replace('\r',' ') for val in row]

                    writer.writerow(row)
                    # step the Bar
                    progress.step()
                if progress.wasCanceled:
                    break
                else:
                    page += 1

        finally:
            progress.close()

    def convertToWideFormat(self,filename):
        progress = ProgressBar("Converting data...", self.mainWindow)
        try:
            #Separate levels
            def flattenTable(fulltable,levelcol,idcol,parentidcol,countchildren,removeempty):
                fulltable[[levelcol]] = fulltable[[levelcol]].astype(int)

                levels = dict(list(fulltable.groupby(levelcol)))
                minlevel = fulltable.level.min()
                for level, data in sorted(levels.items()):
                    #First level is the starting point for the following merges
                    if level == minlevel:
                        #data = data[[idcol,'object_id','object_type']]
                        data = data.add_prefix('level_{}-'.format(level))
                        flattable = data
                    else:
                        #Aggregate object types and join them
                        for col_countchildren in countchildren:
                            children = data[parentidcol].groupby([data[parentidcol],data[col_countchildren]]).count()
                            children = children.unstack(col_countchildren)
                            children['total'] = children.sum(axis=1)
                            children = children.add_prefix('level_{}-children-{}-'.format(level-1,col_countchildren))

                            leftkey = 'level_{}-id'.format(level-1)
                            flattable = merge(flattable,children,how='left',left_on=leftkey,right_index=True)
                            flattable[children.columns.values.tolist()] = flattable[children.columns.values.tolist()].fillna(0).astype(int)

                        #Join data
                        data['childnumber'] = data.groupby(parentidcol).cumcount()
                        leftkey = 'level_{}-{}'.format(level-1,idcol)
                        rightkey = 'level_{}-{}'.format(level,parentidcol)
                        data = data.drop([levelcol],axis=1)
                        data = data.add_prefix('level_{}-'.format(level))
                        flattable = merge(flattable,data,how="outer",left_on=leftkey,right_on=rightkey)

                if removeempty:
                    flattable = flattable.dropna(axis=1,how='all')
                return flattable

            try:
                #delimiter
                delimiter = self.optionSeparator.currentText()
                delimiter = delimiter.encode('utf-8').decode('unicode_escape')

                #open
                data = read_csv(filename, sep=delimiter,encoding='utf-8',dtype=str)

                #convert
                newdata = flattenTable(data,'level','id','parent_id',['object_type','query_status','query_type'],False)


                #save
                outfile = open(filename, 'w',newline='',encoding='utf8')
                try:
                    if self.optionBOM.isChecked():
                        outfile.write('\ufeff') #UTF8 BOM
                    newdata.to_csv(outfile,sep=delimiter,index=False,encoding="utf-8")
                finally:
                    outfile.close()
            except Exception as e:
                self.mainWindow.logmessage(e)
        finally:
            progress.close()
class UserExportedAttributeWidget(mayaMixin.MayaQWidgetDockableMixin, QWidget):

    _currentInstance = None

    @classmethod
    def closeCurrentInstance(cls):
        if cls._currentInstance is not None:
            if cls._currentInstance._mayaSelectionChangedJob is not None:
                cmds.scriptJob(kill=cls._currentInstance._mayaSelectionChangedJob)
                cls._currentInstance._mayaSelectionChangedJob = None

            if cls._currentInstance._mayaUndoJob is not None:
                cmds.scriptJob(kill=cls._currentInstance._mayaUndoJob)
                cls._currentInstance._mayaUndoJob = None

            if cls._currentInstance._mayaRedoJob is not None:
                cmds.scriptJob(kill=cls._currentInstance._mayaRedoJob)
                cls._currentInstance._mayaRedoJob = None

            cls._currentInstance.close()
            cls._currentInstance = None

    def __init__(self, parent=None):
        UserExportedAttributeWidget.closeCurrentInstance()

        super(UserExportedAttributeWidget, self).__init__(parent=parent)
        self._setupUI()

        self._mayaSelectionChangedJob = cmds.scriptJob(event=["SelectionChanged", self._syncUI])
        self._mayaUndoJob = cmds.scriptJob(event=["Undo", self._syncUI])
        self._mayaRedoJob = cmds.scriptJob(event=["Redo", self._syncUI])

        UserExportedAttributeWidget._currentInstance = self

        # Force a sync on the first load.
        self._syncUI()

    def _setupUI(self):
        self.setWindowTitle("Export Attributes to USD")
        layout = QVBoxLayout()

        # This section contains the attributes tagged for export.
        label = QLabel()
        label.setText('Exported Attributes:')
        layout.addWidget(label)

        self.exportedAttrsModel = ExportedAttributesModel()
        self.exportedAttrsView = ExportedAttributesView()
        self.exportedAttrsView.verticalHeader().hide()
        self.exportedAttrsView.setModel(self.exportedAttrsModel)
        selectionModel = self.exportedAttrsView.selectionModel()
        selectionModel.selectionChanged.connect(self._onExportedAttrsSelectionChanged)
        self.exportedAttrsModel.dataChanged.connect(self._onModelDataChanged)
        layout.addWidget(self.exportedAttrsView)

        self.removeExportedAttrButton = QPushButton("Remove Exported Attribute")
        self.removeExportedAttrButton.clicked.connect(self._onRemoveExportedAttrPressed)
        self.removeExportedAttrButton.setEnabled(False)
        layout.addWidget(self.removeExportedAttrButton)

        # This section contains the attributes available for export.
        label = QLabel()
        label.setText('Available Attributes:')
        layout.addWidget(label)

        self.userDefinedCheckBox = QCheckBox('User Defined')
        self.userDefinedCheckBox.setToolTip('Show only user-defined (dynamic) attributes')
        self.userDefinedCheckBox.setChecked(True)
        self.userDefinedCheckBox.stateChanged.connect(self._syncUI)
        layout.addWidget(self.userDefinedCheckBox)

        self.addAttrsModel = AddAttributesModel()
        self.addAttrsView = AddAttributesView()
        self.addAttrsView.setModel(self.addAttrsModel)
        selectionModel = self.addAttrsView.selectionModel()
        selectionModel.selectionChanged.connect(self._onAddAttrsSelectionChanged)
        self.addAttrsModel.dataChanged.connect(self._onModelDataChanged)
        layout.addWidget(self.addAttrsView)

        self.addExportedAttrButton = QPushButton("Add Exported Attribute")
        self.addExportedAttrButton.clicked.connect(self._onAddExportedAttrPressed)
        self.addExportedAttrButton.setEnabled(False)
        layout.addWidget(self.addExportedAttrButton)

        self.setLayout(layout)

    def _onExportedAttrsSelectionChanged(self, selected, deselected):
        if selected.isEmpty():
            self.removeExportedAttrButton.setEnabled(False)
        else:
            self.removeExportedAttrButton.setEnabled(True)

    def _onAddAttrsSelectionChanged(self, selected, deselected):
        if selected.isEmpty():
            self.addExportedAttrButton.setEnabled(False)
        else:
            self.addExportedAttrButton.setEnabled(True)

    def _onRemoveExportedAttrPressed(self):
        selectedNodeNames = cmds.ls(selection=True, long=True)
        if not selectedNodeNames:
            return

        mayaAttrNames = [x.data() for x in self.exportedAttrsView.selectedIndexes()]
        if not mayaAttrNames:
            return

        for selectedNodeName in selectedNodeNames:
            ExportedAttribute.RemoveExportedAttributesForNode(selectedNodeName,
                mayaAttrNames)

        self._syncUI()

    def _onAddExportedAttrPressed(self):
        selectedNodeNames = cmds.ls(selection=True, long=True)
        if not selectedNodeNames:
            return

        exportedAttrs = [ExportedAttribute(x.data()) for x in self.addAttrsView.selectedIndexes()]
        if not exportedAttrs:
            return

        for selectedNodeName in selectedNodeNames:
            ExportedAttribute.UpdateExportedAttributesForNode(selectedNodeName,
                exportedAttrs)

        self._syncUI()

    def _onModelDataChanged(self, topLeft, bottomRight):
        self._syncUI()

    def _syncUI(self):
        # Since _syncUI is called in response to events that invalidate/clear
        # the selections in the views, disable the buttons until something is
        # selected again.
        self.removeExportedAttrButton.setEnabled(False)
        self.addExportedAttrButton.setEnabled(False)

        selectedNodeNames = cmds.ls(selection=True, long=True)
        if not selectedNodeNames:
            self.addAttrsModel.setStringList([])
            self.exportedAttrsModel.exportedAttributes = []
            self.exportedAttrsView.resizeColumnsToContents()
            return

        # Collect the export attributes common to all selected nodes. If the
        # same attribute is configured differently on multiple objects (e.g.
        # different usdAttrName), then do not include that attribute.
        allExportedAttributeNames = set()
        commonExportedAttributeNames = set()
        commonExportedAttrs = {}
        for exportedAttr in ExportedAttribute.GetExportedAttributesFromNode(selectedNodeNames[0]):
            mayaAttrName = exportedAttr.mayaAttrName
            allExportedAttributeNames.add(mayaAttrName)
            commonExportedAttributeNames.add(mayaAttrName)
            commonExportedAttrs[mayaAttrName] = exportedAttr

        for selectedNodeName in selectedNodeNames[1:]:
            exportedAttrNames = set()
            for exportedAttr in ExportedAttribute.GetExportedAttributesFromNode(selectedNodeName):
                mayaAttrName = exportedAttr.mayaAttrName
                allExportedAttributeNames.add(mayaAttrName)
                if (mayaAttrName in commonExportedAttrs and
                        commonExportedAttrs[mayaAttrName] == exportedAttr):
                    exportedAttrNames.add(mayaAttrName)
            commonExportedAttributeNames.intersection_update(exportedAttrNames)

        commonExportedAttrs = [commonExportedAttrs[x] for x in commonExportedAttributeNames]
        commonExportedAttrs.sort(key=lambda x: x.mayaAttrName)
        self.exportedAttrsModel.exportedAttributes = commonExportedAttrs

        # Normally, the combo boxes for selecting usdAttrType and
        # primvarInterpolation would only appear when the table cell is put into
        # edit mode. Instead, we want the combo boxes to always be visible, so
        # we tell the view to open them as persistent editors.
        for row in xrange(self.exportedAttrsModel.rowCount()):
            usdAttrTypeIndex = self.exportedAttrsModel.index(row,
                ExportedAttributesModel.USD_ATTR_TYPE_COLUMN)
            self.exportedAttrsView.openPersistentEditor(usdAttrTypeIndex)

            # Only open the interpolation editor if this is a primvar.
            if self.exportedAttrsModel.data(usdAttrTypeIndex) == USD_ATTR_TYPE_PRIMVAR:
                primvarInterpolationIndex = self.exportedAttrsModel.index(row,
                    ExportedAttributesModel.PRIMVAR_INTERPOLATION_COLUMN)
                self.exportedAttrsView.openPersistentEditor(primvarInterpolationIndex)

            # Only open the double-to-single precision editor if the Maya
            # attribute is double-based.
            mayaAttrNameIndex = self.exportedAttrsModel.index(row,
                ExportedAttributesModel.MAYA_ATTR_NAME_COLUMN)
            mayaAttrName = self.exportedAttrsModel.data(mayaAttrNameIndex)
            if _ShouldEnableDoublePrecisionEditor(mayaAttrName):
                doublePrecisionIndex = self.exportedAttrsModel.index(row,
                    ExportedAttributesModel.DOUBLE_PRECISION_COLUMN)
                self.exportedAttrsView.openPersistentEditor(doublePrecisionIndex)

        self.exportedAttrsView.resizeColumnsToContents()

        # Collect the attributes common to all selected nodes.
        cmdOptions = {'read': True}
        if self.userDefinedCheckBox.isChecked():
            cmdOptions['userDefined'] = True

        commonAttrNames = set(cmds.listAttr(selectedNodeNames[0], **cmdOptions) or [])
        for selectedNodeName in selectedNodeNames[1:]:
            attrNames = set(cmds.listAttr(selectedNodeName, **cmdOptions) or [])
            commonAttrNames.intersection_update(attrNames)

        # Subtract out reserved attribute names and attributes already being
        # exported by ANY node.
        commonAttrNames -= RESERVED_ATTRIBUTES
        commonAttrNames -= allExportedAttributeNames

        self.addAttrsModel.setStringList(sorted(list(commonAttrNames)))
示例#35
0
class MainWindow(QMainWindow):

    def __init__(self, app, parent=None):
        super(MainWindow, self).__init__(parent)
        self.imagesDir = app.dir + '/images/'
        self.setWindowIcon(QIcon(self.imagesDir + 'icon.png'))
        self.path = ''

        self.settings = QSettings()
        self.lastDir = self.settings.value('lastDir', '')

        self.setMinimumWidth(540)

        self.supportedFormats = []
        for f in QImageReader.supportedImageFormats():
            self.supportedFormats.append(str(f.data(), encoding="utf-8"))

        self.fileWatcher = QFileSystemWatcher()
        self.fileWatcher.fileChanged.connect(self.fileChanged)

        # widgets
        self.showPixmapWidget = None

        self.tileWidthSpinBox = QSpinBox()
        self.tileWidthSpinBox.setValue(16)
        self.tileWidthSpinBox.setFixedWidth(50)
        self.tileWidthSpinBox.setMinimum(1)

        self.tileHeightSpinBox = QSpinBox()
        self.tileHeightSpinBox.setValue(16)
        self.tileHeightSpinBox.setFixedWidth(50)
        self.tileHeightSpinBox.setMinimum(1)

        self.paddingSpinBox = QSpinBox()
        self.paddingSpinBox.setFixedWidth(50)
        self.paddingSpinBox.setMinimum(1)

        self.transparentCheckbox = QCheckBox("Transparent")
        self.transparentCheckbox.setChecked(True)
        self.transparentCheckbox.stateChanged.connect(self.transparentChanged)

        self.backgroundColorEdit = ColorEdit()
        self.backgroundColorEdit.setEnabled(False)
        self.backgroundColorLabel = QLabel("Background color:")
        self.backgroundColorLabel.setEnabled(False)

        self.forcePotCheckBox = QCheckBox("Force PoT")
        self.forcePotCheckBox.setChecked(True)
        self.forcePotCheckBox.stateChanged.connect(self.forcePotChanged)

        self.reorderTilesCheckBox = QCheckBox("Reorder tiles")

        self.generateAndExportButton = QPushButton("Generate and export")
        self.generateAndExportButton.setFixedHeight(32)
        self.generateAndExportButton.clicked.connect(self.generateAndExportClicked)
        self.generateAndExportButton.setEnabled(False)

        self.pixmapWidget = PixmapWidget()
        self.pixmapWidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.pixmapWidget.setPixmap(self.createDropTextPixmap())
        self.pixmapWidget.dropSignal.connect(self.fileDropped)
        self.pixmapWidget.setMinimumHeight(300)

        # load settings
        self.tileWidthSpinBox.setValue(int(self.settings.value('tileWidth', 16)))
        self.tileHeightSpinBox.setValue(int(self.settings.value('tileHeight', 16)))
        self.paddingSpinBox.setValue(int(self.settings.value('padding', 1)))
        self.forcePotCheckBox.setChecked(True if self.settings.value('forcePot', 'true') == 'true' else False)
        self.reorderTilesCheckBox.setChecked(True if self.settings.value('reorderTiles', 'false') == 'true' else False)
        self.transparentCheckbox.setChecked(True if self.settings.value('transparent', 'false') == 'true' else False)
        self.backgroundColorEdit.setColorText(str(self.settings.value('backgroundColor', '#FF00FF')))
        self.restoreGeometry(QByteArray(self.settings.value('MainWindow/geometry')))
        self.restoreState(QByteArray(self.settings.value('MainWindow/windowState')))

        # layout
        hl1 = QHBoxLayout()
        hl1.setContentsMargins(5, 5, 5, 5)
        hl1.addWidget(QLabel("Tile width:"))
        hl1.addSpacing(5)
        hl1.addWidget(self.tileWidthSpinBox)
        hl1.addSpacing(15)
        hl1.addWidget(QLabel("Tile height:"))
        hl1.addSpacing(5)
        hl1.addWidget(self.tileHeightSpinBox)
        hl1.addSpacing(15)
        hl1.addWidget(QLabel("Padding:"))
        hl1.addSpacing(5)
        hl1.addWidget(self.paddingSpinBox)
        hl1.addSpacing(15)
        hl1.addWidget(self.forcePotCheckBox)
        hl1.addSpacing(15)
        hl1.addWidget(self.reorderTilesCheckBox)
        hl1.addStretch()

        hl2 = QHBoxLayout()
        hl2.setContentsMargins(5, 5, 5, 5)
        hl2.addWidget(self.transparentCheckbox)
        hl2.addSpacing(15)
        hl2.addWidget(self.backgroundColorLabel)
        hl2.addSpacing(5)
        hl2.addWidget(self.backgroundColorEdit)
        hl2.addStretch()

        hl3 = QHBoxLayout()
        hl3.setContentsMargins(5, 5, 5, 5)
        hl3.addWidget(self.generateAndExportButton)

        vl = QVBoxLayout()
        vl.setContentsMargins(0, 0, 0, 0)
        vl.setSpacing(0)
        vl.addLayout(hl1)
        vl.addLayout(hl2)
        vl.addWidget(self.pixmapWidget)
        vl.addLayout(hl3)

        w = QWidget()
        w.setLayout(vl)
        self.setCentralWidget(w)

        self.setTitle()

    def setTitle(self):
        p = ' - ' + os.path.basename(self.path) if self.path else ''
        self.setWindowTitle(QCoreApplication.applicationName() + ' ' + QCoreApplication.applicationVersion() + p)

    def createDropTextPixmap(self):
        pixmap = QPixmap(481, 300)
        pixmap.fill(QColor("#333333"))
        painter = QPainter(pixmap)
        font = QFont("Arial")
        font.setPixelSize(28)
        font.setBold(True)
        fm = QFontMetrics(font)
        painter.setFont(font)
        painter.setPen(QPen(QColor("#888888"), 1))
        text = "Drop the tileset image here"
        x = (pixmap.width()-fm.width(text))/2
        y = (pixmap.height()+fm.height())/2
        painter.drawText(x, y, text)
        del painter
        return pixmap

    def fileDropped(self, path):
        path = str(path)
        name, ext = os.path.splitext(path)
        ext = ext[1:]
        if not ext in self.supportedFormats:
            QMessageBox.warning(self, "Warning", "The dropped file is not supported")
            return
        pixmap = QPixmap(path)
        if pixmap.isNull():
            QMessageBox.warning(self, "Warning", "Can't load the image")
            return
        if self.path:
            self.fileWatcher.removePath(self.path)
        self.path = path
        self.fileWatcher.addPath(self.path)
        self.pixmapWidget.setPixmap(pixmap)
        self.generateAndExportButton.setEnabled(True)
        self.setTitle()
        self.activateWindow()

    def fileChanged(self, path):
        #self.fileDropped(path)
        pass

    def transparentChanged(self):
        e = self.transparentCheckbox.isChecked()
        self.backgroundColorEdit.setEnabled(not e)
        self.backgroundColorLabel.setEnabled(not e)

    def forcePotChanged(self):
        e = self.forcePotCheckBox.isChecked()
        self.reorderTilesCheckBox.setEnabled(e)

    def generateAndExportClicked(self):

        g = Generator()
        g.tileWidth = self.tileWidthSpinBox.value()
        g.tileHeight = self.tileHeightSpinBox.value()
        g.forcePot = self.forcePotCheckBox.isChecked()
        g.isTransparent = self.transparentCheckbox.isChecked()
        g.bgColor = self.backgroundColorEdit.getColor()
        g.reorder = self.reorderTilesCheckBox.isChecked()
        g.padding = self.paddingSpinBox.value()

        target = g.create(self.pixmapWidget.pixmap);

        # export
        self.lastDir = os.path.dirname(self.path)
        targetPath = QFileDialog.getSaveFileName(self, 'Export', self.lastDir, 'PNG (*.png)')
        if targetPath:
            target.save(targetPath[0])
            showPixmap = QPixmap.fromImage(target)
            if self.showPixmapWidget:
                self.showPixmapWidget.deleteLater()
                del self.showPixmapWidget
            self.showPixmapWidget = PixmapWidget()
            self.showPixmapWidget.setWindowIcon(self.windowIcon())
            self.showPixmapWidget.setWindowTitle(os.path.basename(targetPath[0]))
            self.showPixmapWidget.resize(showPixmap.width(), showPixmap.height())
            self.showPixmapWidget.setPixmap(showPixmap)
            self.showPixmapWidget.show()

    def closeEvent(self, event):
        if self.showPixmapWidget:
            self.showPixmapWidget.close()

        # save settings
        self.settings.setValue('tileWidth', self.tileWidthSpinBox.value())
        self.settings.setValue('tileHeight', self.tileHeightSpinBox.value())
        self.settings.setValue('padding', self.paddingSpinBox.value())
        self.settings.setValue('forcePot', self.forcePotCheckBox.isChecked())
        self.settings.setValue('reorderTiles', self.reorderTilesCheckBox.isChecked())
        self.settings.setValue('transparent', self.transparentCheckbox.isChecked())
        self.settings.setValue('backgroundColor', self.backgroundColorEdit.getColor().name())
        self.settings.setValue('lastDir', self.lastDir)
        self.settings.setValue('MainWindow/geometry', self.saveGeometry())
        self.settings.setValue('MainWindow/windowState', self.saveState())

        super(MainWindow, self).closeEvent(event)