예제 #1
0
    class SpinBoxPySignal(UsesQApplication):
        """Tests the connection of python signals to QSpinBox qt slots."""

        def setUp(self):
            super(SpinBoxPySignal, self).setUp()
            self.obj = Dummy()
            self.spin = QSpinBox()
            self.spin.setValue(0)

        def tearDown(self):
            super(SpinBoxPySignal, self).tearDown()
            del self.obj
            del self.spin

        def testValueChanged(self):
            """Emission of a python signal to QSpinBox setValue(int)"""
            QObject.connect(self.obj, SIGNAL('dummy(int)'), self.spin, SLOT('setValue(int)'))
            self.assertEqual(self.spin.value(), 0)

            self.obj.emit(SIGNAL('dummy(int)'), 4)
            self.assertEqual(self.spin.value(), 4)

        def testValueChangedMultiple(self):
            """Multiple emissions of a python signal to QSpinBox setValue(int)"""
            QObject.connect(self.obj, SIGNAL('dummy(int)'), self.spin, SLOT('setValue(int)'))
            self.assertEqual(self.spin.value(), 0)

            self.obj.emit(SIGNAL('dummy(int)'), 4)
            self.assertEqual(self.spin.value(), 4)

            self.obj.emit(SIGNAL('dummy(int)'), 77)
            self.assertEqual(self.spin.value(), 77)
예제 #2
0
        def testSetValueIndirect(self):
            """Indirect signal emission: QSpinBox using valueChanged(int)/setValue(int)"""
            spinSend = QSpinBox()
            spinRec = QSpinBox()

            spinRec.setValue(5)

            QObject.connect(spinSend, SIGNAL('valueChanged(int)'), spinRec, SLOT('setValue(int)'))
            self.assertEqual(spinRec.value(), 5)
            spinSend.setValue(3)
            self.assertEqual(spinRec.value(), 3)
            self.assertEqual(spinSend.value(), 3)
예제 #3
0
        def testSetValueIndirect(self):
            """Indirect signal emission: QSpinBox using valueChanged(int)/setValue(int)"""
            spinSend = QSpinBox()
            spinRec = QSpinBox()

            spinRec.setValue(5)

            QObject.connect(spinSend, SIGNAL('valueChanged(int)'), spinRec, SLOT('setValue(int)'))
            self.assertEqual(spinRec.value(), 5)
            spinSend.setValue(3)
            self.assertEqual(spinRec.value(), 3)
            self.assertEqual(spinSend.value(), 3)
예제 #4
0
class CreateSamplesRow():
	def __init__(self):
		self.plate			= QLineEdit()
		self.parents		= QSpinBox()
		self.samples		= QSpinBox()
		self.loadedBy		= QComboBox()
		self.parents.setMaximum(8)
		self.parents.setValue(2)
		self.samples.setMaximum(96)
		self.samples.setValue(94)
		self.loadedBy.addItems(['Column','Row'])
	def getPlate(self):			return self.plate.text()
	def getParents(self):		return self.parents.value()
	def getSamples(self):		return self.samples.value()
	def getLoadedBy(self):		return self.loadedBy.currentText()
class AddWindow(QDialog):
    def __init__(self, parent=None):
        super(AddWindow, self).__init__(parent)
        self.setGeometry(QtCore.QRect(110, 40, 171, 160))

    def initUi(self):
        self.grid = QGridLayout()
        self.grid.addWidget(QLabel("Connection name"), 0, 0)
        self.grid.addWidget(QLabel("Username"), 2, 0)
        self.grid.addWidget(QLabel("Password"), 4, 0)
        self.grid.addWidget(QLabel("Hostname"), 6, 0)
        self.grid.addWidget(QLabel("Port"), 8, 0)
        self.connectionNameInput =  QLineEdit(self)
        self.grid.addWidget(self.connectionNameInput, 1, 0)
        self.userNameInput =  QLineEdit(self)
        self.grid.addWidget(self.userNameInput, 3, 0)
        self.passwordInput =  QLineEdit(self)
        self.grid.addWidget(self.passwordInput, 5, 0)
        self.hostnameInput =  QLineEdit(self)
        self.grid.addWidget(self.hostnameInput, 7, 0)
        self.portSpinBox =  QSpinBox(self)
        self.portSpinBox.setMinimum(1)
        self.portSpinBox.setMaximum(65535)
        self.portSpinBox.setValue(22)
        self.grid.addWidget(self.portSpinBox, 9, 0)
        self.addButton = QPushButton("Accept")
        self.grid.addWidget(self.addButton, 10, 0)
        self.setLayout(self.grid)

        self.addButton.clicked.connect(self.clickedAddButton)

        self.show()

    @Slot()
    def clickedAddButton(self):
        dataRep = DataRepository()
        host = self.hostnameInput.text()
        port = self.portSpinBox.value()
        pwd = self.passwordInput.text()
        login = self.userNameInput.text()
        name = self.connectionNameInput.text()
        dataRep.addConnection({
            'host':host,
            'port':port,
            'pwd':pwd,
            'login':login,
            'name':name
        })
        self.accept()
        self.close()

    def closeEvent(self, event):
            event.accept()
예제 #6
0
class NewMarkerDialog(QDialog):
	def __init__(self):
		super(NewMarkerDialog, self).__init__()
		self.setWindowTitle('Add new marker...')
		newMarkerLabel		= QLabel('Marker:')
		self.newMarker		= QLineEdit()
		includeLabel		= QLabel('Include all samples:')
		self.includeAll		= QCheckBox()
		controlsLabel		= QLabel('Control wells:')
		self.controls		= QSpinBox()
		self.controls.setRange(0,8)
		self.controls.setValue(2)
		layout				= QGridLayout()
		layout.addWidget(newMarkerLabel,0,0)
		layout.addWidget(self.newMarker,0,1)
		layout.addWidget(includeLabel,1,0)
		layout.addWidget(self.includeAll,1,1)
		layout.addWidget(controlsLabel,2,0)
		layout.addWidget(self.controls,2,1)
		self.buttons		= QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)	
		self.buttons.accepted.connect(self.accept)
		self.buttons.rejected.connect(self.reject)
		layout.addWidget(self.buttons,100,0,1,2)
		self.setLayout(layout)
	def getMarker(self):		return self.newMarker.text()
	def getIncludeAll(self):	return self.includeAll.isChecked()
	def getControls(self):		return self.controls.value()
 
	@staticmethod
	def run(parent = None):
		dialog				= NewMarkerDialog()
		result				= dialog.exec_()
		newMarker			= dialog.getMarker()
		includeAll			= dialog.getIncludeAll()
		controls			= dialog.getControls()
		return (newMarker,includeAll,controls,result == QDialog.Accepted)
예제 #7
0
        def testSetValue(self):
            """Direct signal emission: QSpinBox using valueChanged(int)/setValue(int)"""
            spinSend = QSpinBox()
            spinRec = QSpinBox()

            spinRec.setValue(5)
            spinSend.setValue(42)

            QObject.connect(spinSend, SIGNAL('valueChanged(int)'), spinRec, SLOT('setValue(int)'))
            self.assertEqual(spinRec.value(), 5)
            self.assertEqual(spinSend.value(), 42)
            spinSend.emit(SIGNAL('valueChanged(int)'), 3)

            self.assertEqual(spinRec.value(), 3)
            #Direct emission shouldn't change the value of the emitter
            self.assertEqual(spinSend.value(), 42)

            spinSend.emit(SIGNAL('valueChanged(int)'), 66)
            self.assertEqual(spinRec.value(), 66)
            self.assertEqual(spinSend.value(), 42)
예제 #8
0
        def testSetValue(self):
            """Direct signal emission: QSpinBox using valueChanged(int)/setValue(int)"""
            spinSend = QSpinBox()
            spinRec = QSpinBox()

            spinRec.setValue(5)
            spinSend.setValue(42)

            QObject.connect(spinSend, SIGNAL('valueChanged(int)'), spinRec, SLOT('setValue(int)'))
            self.assertEqual(spinRec.value(), 5)
            self.assertEqual(spinSend.value(), 42)
            spinSend.emit(SIGNAL('valueChanged(int)'), 3)

            self.assertEqual(spinRec.value(), 3)
            #Direct emission shouldn't change the value of the emitter
            self.assertEqual(spinSend.value(), 42)

            spinSend.emit(SIGNAL('valueChanged(int)'), 66)
            self.assertEqual(spinRec.value(), 66)
            self.assertEqual(spinSend.value(), 42)
예제 #9
0
class Form(QDialog):
    def __init__(self, state, parent=None):
        super().__init__(parent)
        Lib.prepareModalDialog(self)
        self.state = state
        self.setWindowTitle("Renumber Pages — {}".format(
            QApplication.applicationName()))
        self.createWidgets()
        self.layoutWidgets()
        self.createConnections()
        self.romanStartSpinBox.setFocus()
        self.updateUi()
        settings = QSettings()
        self.updateToolTips(
            bool(
                int(
                    settings.value(Gopt.Key.ShowDialogToolTips,
                                   Gopt.Default.ShowDialogToolTips))))

    def createWidgets(self):
        self.romanStartLabel = QLabel("&Roman from")
        self.romanStartSpinBox = Widgets.RomanSpinBox.SpinBox()
        self.tooltips.append((self.romanStartSpinBox, """\
<p><b>Roman from</b></p>
<p>The first roman page number to change.</p>"""))
        self.romanStartLabel.setBuddy(self.romanStartSpinBox)
        self.romanEndLabel = QLabel("to")
        self.romanEndSpinBox = Widgets.RomanSpinBox.SpinBox()
        self.romanEndSpinBox.setValue(200)
        self.tooltips.append((self.romanEndSpinBox, """\
<p><b>Roman, to</b></p>
<p>The last roman page number to change.</p>"""))
        self.romanChangeLabel = QLabel("change")
        self.romanChangeSpinBox = Widgets.ChangeSpinBox.SpinBox()
        self.romanChangeSpinBox.setRange(-100, 100)
        self.romanChangeSpinBox.setValue(0)
        self.romanChangeSpinBox.setMinimumWidth(
            self.romanChangeSpinBox.fontMetrics().width("W(no change)W"))
        self.tooltips.append((self.romanChangeSpinBox, """\
<p><b>Roman, change</b></p>
<p>The amount to change the roman page numbers in the Roman from&ndash;to
range.</p>"""))
        self.decimalStartLabel = QLabel("&Decimal from")
        self.decimalStartSpinBox = QSpinBox()
        self.decimalStartSpinBox.setAlignment(Qt.AlignRight)
        self.decimalStartLabel.setBuddy(self.decimalStartSpinBox)
        self.decimalStartSpinBox.setRange(1, 10000)
        self.tooltips.append((self.decimalStartSpinBox, """\
<p><b>Decimal from</b></p>
<p>The first decimal page number to change.</p>"""))
        self.decimalEndLabel = QLabel("to")
        self.decimalEndSpinBox = QSpinBox()
        self.decimalEndSpinBox.setAlignment(Qt.AlignRight)
        self.decimalEndSpinBox.setRange(1, 10000)
        self.decimalEndSpinBox.setValue(2000)
        self.tooltips.append((self.decimalEndSpinBox, """\
<p><b>Decimal, to</b></p>
<p>The last decimal page number to change.</p>"""))
        self.decimalChangeLabel = QLabel("change")
        self.decimalChangeSpinBox = Widgets.ChangeSpinBox.SpinBox()
        self.decimalChangeSpinBox.setRange(-100, 100)
        self.decimalChangeSpinBox.setValue(0)
        self.tooltips.append((self.decimalChangeSpinBox, """\
<p><b>Decimal, change</b></p>
<p>The amount to change the decimal page numbers in the Decimal
from&ndash;to range.</p>"""))

        self.buttonBox = QDialogButtonBox()
        self.renumberButton = QPushButton(QIcon(":/renumberpages.svg"),
                                          "Re&number")
        self.tooltips.append((self.renumberButton, """\
<p><b>Renumber</b></p>
<p>Renumber roman and decimal page numbers within the given ranges by
the specified amounts of change throughout the entire index.</p>"""))
        self.buttonBox.addButton(self.renumberButton,
                                 QDialogButtonBox.ActionRole)
        self.closeButton = QPushButton(QIcon(":/dialog-close.svg"), "&Cancel")
        self.tooltips.append((self.closeButton, """<p><b>Cancel</b></p>
<p>Close the dialog without making any changes to the index.</p>"""))
        self.buttonBox.addButton(self.closeButton, QDialogButtonBox.RejectRole)
        self.helpButton = QPushButton(QIcon(":/help.svg"), "Help")
        self.tooltips.append(
            (self.helpButton, "Help on the Renumber Pages dialog"))
        self.buttonBox.addButton(self.helpButton, QDialogButtonBox.HelpRole)

    def layoutWidgets(self):
        grid = QGridLayout()
        grid.addWidget(self.romanStartLabel, 0, 0)
        grid.addWidget(self.romanStartSpinBox, 0, 1)
        grid.addWidget(self.romanEndLabel, 0, 2)
        grid.addWidget(self.romanEndSpinBox, 0, 3)
        grid.addWidget(self.romanChangeLabel, 0, 4)
        grid.addWidget(self.romanChangeSpinBox, 0, 5)
        grid.addWidget(self.decimalStartLabel, 1, 0)
        grid.addWidget(self.decimalStartSpinBox, 1, 1)
        grid.addWidget(self.decimalEndLabel, 1, 2)
        grid.addWidget(self.decimalEndSpinBox, 1, 3)
        grid.addWidget(self.decimalChangeLabel, 1, 4)
        grid.addWidget(self.decimalChangeSpinBox, 1, 5)
        hbox = QHBoxLayout()
        hbox.addLayout(grid)
        hbox.addStretch()
        layout = QVBoxLayout()
        layout.addLayout(hbox)
        layout.addStretch()
        layout.addWidget(self.buttonBox)
        self.setLayout(layout)

    def createConnections(self):
        self.buttonBox.rejected.connect(self.reject)
        self.renumberButton.clicked.connect(self.renumber)
        for spinbox in (self.romanStartSpinBox, self.romanEndSpinBox,
                        self.romanChangeSpinBox, self.decimalStartSpinBox,
                        self.decimalEndSpinBox, self.decimalChangeSpinBox):
            spinbox.valueChanged.connect(self.updateUi)
        self.helpButton.clicked.connect(self.help)

    def updateUi(self):
        self._synchronize(self.romanStartSpinBox, self.romanEndSpinBox)
        self._synchronize(self.decimalStartSpinBox, self.decimalEndSpinBox)
        changeRoman = (
            (self.romanStartSpinBox.value() != self.romanEndSpinBox.value())
            and self.romanChangeSpinBox.value() != 0)
        changeDecimal = ((self.decimalStartSpinBox.value() !=
                          self.decimalEndSpinBox.value())
                         and self.decimalChangeSpinBox.value() != 0)
        self.renumberButton.setEnabled(changeRoman or changeDecimal)
        self._setPrefix(self.romanChangeSpinBox)
        self._setPrefix(self.decimalChangeSpinBox)

    def _synchronize(self, startSpinBox, endSpinBox):
        value = startSpinBox.value()
        if endSpinBox.value() < value:
            endSpinBox.setValue(value)

    def _setPrefix(self, spinbox):
        spinbox.setPrefix("+" if spinbox.value() > 0 else "")

    def help(self):
        self.state.help("xix_ref_dlg_renumpages.html")

    def renumber(self):  # No need to restore focus widget
        options = RenumberOptions(self.romanStartSpinBox.value(),
                                  self.romanEndSpinBox.value(),
                                  self.romanChangeSpinBox.value(),
                                  self.decimalStartSpinBox.value(),
                                  self.decimalEndSpinBox.value(),
                                  self.decimalChangeSpinBox.value())
        with Lib.DisableUI(self):
            self.state.model.renumber(options,
                                      self.state.window.reportProgress)
        message = "Renumber pages"
        if self.state.model.canUndo:
            self.state.model.can_undo.emit(True, message)
        if self.state.model.canRedo:
            self.state.model.can_redo.emit(True, message)
        self.state.updateUi()
        say("Renumbered pages", SAY_TIMEOUT)
        self.accept()
예제 #10
0
class PushupForm(QDialog):
    '''
    classdocs
    '''
    pushupCreated = Signal(Pushup_Model)

    def __init__(self, athlete):
        '''
        Constructor
        '''
        QDialog.__init__(self)

        self.setWindowTitle("Pushup form")
        self.athlete = athlete
        self.pushupForm = QFormLayout()
        self.createGUI()

    def createGUI(self):
        self.series = QSpinBox()
        self.series.setMinimum(1)

        self.repetitions = QSpinBox()
        self.repetitions.setMaximum(512)

        self.avgHeartRateToggle = QCheckBox()
        self.avgHeartRateToggle.toggled.connect(self._toggleHeartRateSpinBox)

        self.avgHeartRate = QSpinBox()
        self.avgHeartRate.setMinimum(30)
        self.avgHeartRate.setMaximum(250)
        self.avgHeartRate.setValue(120)
        self.avgHeartRate.setDisabled(True)

        self.dateSelector_widget = QCalendarWidget()
        self.dateSelector_widget.setMaximumDate(QDate.currentDate())

        self.addButton = QPushButton("Add pushup")
        self.addButton.setMaximumWidth(90)
        self.addButton.clicked.connect(self._createPushup)

        self.cancelButton = QPushButton("Cancel")
        self.cancelButton.setMaximumWidth(90)
        self.cancelButton.clicked.connect(self.reject)

        self.pushupForm.addRow("Series", self.series)
        self.pushupForm.addRow("Repetitions", self.repetitions)
        self.pushupForm.addRow("Store average heart rate ? ",
                               self.avgHeartRateToggle)
        self.pushupForm.addRow("Average Heart Rate", self.avgHeartRate)
        self.pushupForm.addRow("Exercise Date", self.dateSelector_widget)

        btnsLayout = QVBoxLayout()
        btnsLayout.addWidget(self.addButton)
        btnsLayout.addWidget(self.cancelButton)
        btnsLayout.setAlignment(Qt.AlignRight)

        layoutWrapper = QVBoxLayout()
        layoutWrapper.addLayout(self.pushupForm)
        layoutWrapper.addLayout(btnsLayout)

        self.setLayout(layoutWrapper)

    def _createPushup(self):
        exerciseDate = self.dateSelector_widget.selectedDate()
        exerciseDate = self.qDate_to_date(exerciseDate)

        if self.avgHeartRateToggle.isChecked():
            heartRate = self.avgHeartRate.value()
        else:
            heartRate = None

        pushup = Pushup_Model(self.athlete._name, exerciseDate, heartRate,
                              self.series.value(), self.repetitions.value())

        self.pushupCreated.emit(pushup)
        self.accept()

    def _toggleHeartRateSpinBox(self):
        if self.avgHeartRateToggle.isChecked():
            self.avgHeartRate.setDisabled(False)
        else:
            self.avgHeartRate.setDisabled(True)

    def qDate_to_date(self, qDate):
        return date(qDate.year(), qDate.month(), qDate.day())
예제 #11
0
class Panel(QWidget):
    def __init__(self, state, config, parent):
        super().__init__(parent)
        self.state = state
        self.config = config
        self.form = parent
        self.createWidgets()
        self.layoutWidgets()
        self.createConnections()

    def createWidgets(self):
        settings = QSettings()
        self.sortRulesGroupBox = QGroupBox("Calculate &Sort As Rules")
        defaultSortAsRules = settings.value(Gconf.Key.SortAsRules,
                                            Gopt.Default.SortAsRules)
        self.thisSortAsRules = self.config.get(Gopt.Key.SortAsRules,
                                               defaultSortAsRules)
        self.defaultSortAsRulesBox = QComboBox()
        self.form.tooltips.append((self.defaultSortAsRulesBox, """\
<p><b>Calculate Sort As Rules, Default</b></p>
<p>The default setting for the <b>Calculate Sort As Rules, For This
Index</b> combobox for new indexes.</p>"""))
        self.thisSortAsRulesBox = QComboBox()
        self.form.tooltips.append((self.thisSortAsRulesBox, """\
<p><b>Calculate Sort As Rules, For This Index</b></p>
<p>The rules to use for calculating each entry's sort as text for this
index.</p>
<p>If the rules are changed, when the dialog is closed, the new rules
will be applied to every entry in the index.</p>"""))
        self.populateSortAsRulesBox(self.defaultSortAsRulesBox,
                                    defaultSortAsRules)
        self.populateSortAsRulesBox(self.thisSortAsRulesBox,
                                    self.thisSortAsRules)

        self.pageRangeRulesBox = QGroupBox("&Page Range Rules")
        defaultPageRangeRules = settings.value(Gconf.Key.PageRangeRules,
                                               Gopt.Default.PageRangeRules)
        self.thisPageRangeRules = self.config.get(Gopt.Key.PageRangeRules,
                                                  defaultPageRangeRules)
        self.defaultPageRangeRulesBox = QComboBox()
        self.form.tooltips.append((self.defaultPageRangeRulesBox, """\
<p><b>Page Range Rules, Default</b></p>
<p>The default setting for the <b>Page Range Rules, For This Index</b>
combobox for new indexes.</p>"""))
        self.thisPageRangeRulesBox = QComboBox()
        self.form.tooltips.append((self.thisPageRangeRulesBox, """\
<p><b>Page Range Rules, For This Index</b></p>
<p>The rules to use for handling page ranges, e.g., whether in full such
as 120&ndash;124, or somehow compressed, e.g., 120&ndash;4, for this
index.</p>
<p>If the rules are changed, when the dialog is closed, the new rules
will be applied to every entry in the index.</p>"""))
        self.populatePageRangeRulesBox(self.defaultPageRangeRulesBox,
                                       defaultPageRangeRules)
        self.populatePageRangeRulesBox(self.thisPageRangeRulesBox,
                                       self.thisPageRangeRules)
        self.padDigitsGroupBox = QGroupBox("Pad &Digits")
        defaultPadDigits = int(
            settings.value(Gconf.Key.PadDigits, Gopt.Default.PadDigits))
        self.thisPadDigits = int(
            self.config.get(Gopt.Key.PadDigits, defaultPadDigits))
        self.thisPadDigitsLabel = QLabel("For This Index")
        self.thisPadDigitsSpinBox = QSpinBox()
        self.thisPadDigitsSpinBox.setAlignment(Qt.AlignRight)
        self.thisPadDigitsSpinBox.setRange(0, 12)
        self.thisPadDigitsSpinBox.setValue(self.thisPadDigits)
        self.form.tooltips.append((self.thisPadDigitsSpinBox, """\
<p><b>Pad Digits, For This Index</b></p>
<p>Sort as texts are compared textually, so if a term contains a number
(or text which is converted to a number), the number must be padded by
leading zeros to ensure correct ordering. This is the number of digits
to pad for, for this index. For example, if set to 4, the numbers 1, 23,
and 400 would be set to 0001, 0023, and 0400, in the sort as text.</p>"""))
        self.defaultPadDigitsLabel = QLabel("Default")
        self.defaultPadDigitsSpinBox = QSpinBox()
        self.defaultPadDigitsSpinBox.setAlignment(Qt.AlignRight)
        self.defaultPadDigitsSpinBox.setRange(0, 12)
        self.defaultPadDigitsSpinBox.setValue(defaultPadDigits)
        self.form.tooltips.append((self.defaultPadDigitsSpinBox, """\
<p><b>Pad Digits, Default</b></p>
<p>The default setting for the <b>Pad Digits, For This Index</b> spinbox
for new indexes.</p>"""))
        self.ignoreSubFirstsGroupBox = QGroupBox(
            "&Ignore Subentry Function Words")
        defaultIgnoreSubFirsts = bool(
            int(
                settings.value(Gconf.Key.IgnoreSubFirsts,
                               Gopt.Default.IgnoreSubFirsts)))
        thisIgnoreSubFirsts = bool(
            int(
                self.config.get(Gopt.Key.IgnoreSubFirsts,
                                defaultIgnoreSubFirsts)))
        self.thisIgnoreSubFirstsCheckBox = QCheckBox("For This Index")
        self.thisIgnoreSubFirstsCheckBox.setChecked(thisIgnoreSubFirsts)
        self.form.tooltips.append((self.thisIgnoreSubFirstsCheckBox, """\
<p><b>Ignore Subentry Function Words, For This Index</b></p>
<p>This setting applies to this index.</p>
<p>If checked, words listed in the <b>Index→Ignore Subentry Function
Words</b> list are ignored for sorting purposes when the first word of a
subentry, i.e., ignored when the first word of an entry's sort as
text.</p> <p>This should normally be checked for Chicago Manual of Style
Sort As Rules, and unchecked for NISO Rules.</p>"""))
        self.defaultIgnoreSubFirstsCheckBox = QCheckBox("Default")
        self.defaultIgnoreSubFirstsCheckBox.setChecked(defaultIgnoreSubFirsts)
        self.form.tooltips.append((self.defaultIgnoreSubFirstsCheckBox, """\
<p><b>Ignore Subentry Function Words, Default</b></p>
<p>The default setting for the <b>Ignore Subentry Function Words, For
This Index</b> checkbox for new indexes</p>"""))
        self.suggestSpelledGroupBox = QGroupBox(
            "&Suggest Spelled Out Numbers when Appropriate")
        defaultSuggestSpelled = bool(
            int(
                settings.value(Gconf.Key.SuggestSpelled,
                               Gopt.Default.SuggestSpelled)))
        thisSuggestSpelled = bool(
            int(self.config.get(Gopt.Key.SuggestSpelled,
                                defaultSuggestSpelled)))
        self.thisSuggestSpelledCheckBox = QCheckBox("For This Index")
        self.thisSuggestSpelledCheckBox.setChecked(thisSuggestSpelled)
        self.form.tooltips.append((self.thisSuggestSpelledCheckBox, """\
<p><b>Suggest Spelled Out Numbers when Appropriate, For This Index</b></p>
<p>When checked (and providing the Sort As rules in force are not NISO
rules), when adding or editing a term when the <b>Automatically
Calculate Sort As</b> checkbox is checked, and when the term contains a
number, the choice of sort as texts will include the number spelled
out.</p>"""))
        self.defaultSuggestSpelledCheckBox = QCheckBox("Default")
        self.defaultSuggestSpelledCheckBox.setChecked(defaultSuggestSpelled)
        self.form.tooltips.append((self.defaultSuggestSpelledCheckBox, """\
<p><b>Suggest Spelled Out Numbers when Appropriate, Default</b></p>
<p>The default setting for the <b>Suggest Spelled Out Numbers when
Appropriate, For This Index</b> checkbox for new indexes.</p>"""))

    def layoutWidgets(self):
        layout = QVBoxLayout()

        form = QFormLayout()
        form.addRow("For This Index", self.thisSortAsRulesBox)
        form.addRow("Default", self.defaultSortAsRulesBox)
        self.sortRulesGroupBox.setLayout(form)
        layout.addWidget(self.sortRulesGroupBox)

        form = QFormLayout()
        form.addRow("For This Index", self.thisPageRangeRulesBox)
        form.addRow("Default", self.defaultPageRangeRulesBox)
        self.pageRangeRulesBox.setLayout(form)
        layout.addWidget(self.pageRangeRulesBox)

        hbox = QHBoxLayout()
        hbox.addWidget(self.thisPadDigitsLabel)
        hbox.addWidget(self.thisPadDigitsSpinBox)
        hbox.addStretch(1)
        hbox.addWidget(self.defaultPadDigitsLabel)
        hbox.addWidget(self.defaultPadDigitsSpinBox)
        hbox.addStretch(3)
        self.padDigitsGroupBox.setLayout(hbox)
        layout.addWidget(self.padDigitsGroupBox)

        hbox = QHBoxLayout()
        hbox.addWidget(self.thisIgnoreSubFirstsCheckBox)
        hbox.addWidget(self.defaultIgnoreSubFirstsCheckBox)
        hbox.addStretch()
        self.ignoreSubFirstsGroupBox.setLayout(hbox)
        layout.addWidget(self.ignoreSubFirstsGroupBox)

        hbox = QHBoxLayout()
        hbox.addWidget(self.thisSuggestSpelledCheckBox)
        hbox.addWidget(self.defaultSuggestSpelledCheckBox)
        hbox.addStretch()
        self.suggestSpelledGroupBox.setLayout(hbox)
        layout.addWidget(self.suggestSpelledGroupBox)

        layout.addStretch()
        self.setLayout(layout)

    def createConnections(self):
        self.defaultSortAsRulesBox.currentIndexChanged.connect(
            self.setDefaultSortAsRules)
        self.defaultPageRangeRulesBox.currentIndexChanged.connect(
            self.setDefaultPageRangeRules)
        self.defaultPadDigitsSpinBox.valueChanged.connect(
            self.setDefaultPadDigits)
        self.defaultIgnoreSubFirstsCheckBox.toggled.connect(
            self.setDefaultIgnoreSubFirsts)
        self.defaultSuggestSpelledCheckBox.toggled.connect(
            self.setDefaultSuggestSpelled)

    def populateSortAsRulesBox(self, combobox, rules):
        index = -1
        for i, name in enumerate(SortAs.RulesForName):
            displayName = SortAs.RulesForName[name].name
            combobox.addItem(displayName, name)
            if name == rules:
                index = i
        combobox.setCurrentIndex(index)

    def setDefaultSortAsRules(self, index):
        index = self.defaultSortAsRulesBox.currentIndex()
        name = self.defaultSortAsRulesBox.itemData(index)
        settings = QSettings()
        settings.setValue(Gopt.Key.SortAsRules, name)

    def populatePageRangeRulesBox(self, combobox, rules):
        index = -1
        for i, name in enumerate(Pages.RulesForName):
            displayName = Pages.RulesForName[name].name
            combobox.addItem(displayName, name)
            if name == rules:
                index = i
        combobox.setCurrentIndex(index)

    def setDefaultPageRangeRules(self, index):
        index = self.defaultPageRangeRulesBox.currentIndex()
        name = self.defaultPageRangeRulesBox.itemData(index)
        settings = QSettings()
        settings.setValue(Gopt.Key.PageRangeRules, name)

    def setDefaultPadDigits(self):
        value = self.defaultPadDigitsSpinBox.value()
        settings = QSettings()
        settings.setValue(Gopt.Key.PadDigits, value)

    def setDefaultIgnoreSubFirsts(self):
        value = int(self.defaultIgnoreSubFirstsCheckBox.isChecked())
        settings = QSettings()
        settings.setValue(Gopt.Key.IgnoreSubFirsts, value)

    def setDefaultSuggestSpelled(self):
        value = int(self.defaultSuggestSpelledCheckBox.isChecked())
        settings = QSettings()
        settings.setValue(Gopt.Key.SuggestSpelled, value)
예제 #12
0
class _PenepmaConfigurePanelWidget(_ConfigurePanelWidget):
    def _initUI(self):
        # Widgets
        self._brw_pendbase = DirBrowseWidget()

        self._brw_exe = FileBrowseWidget()
        if os.name == 'nt':
            self._brw_exe.setNameFilter('Application files (*.exe)')
        else:
            self._brw_exe.setNameFilter('Application files (*)')

        self._spn_dumpp = QSpinBox()
        self._spn_dumpp.setMinimum(30)
        self._spn_dumpp.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)

        # Layouts
        layout = _ConfigurePanelWidget._initUI(self)
        layout.addRow("Path to pendbase directory", self._brw_pendbase)
        layout.addRow('Path to PENEPMA executable', self._brw_exe)
        layout.addRow('Interval between dump (s)', self._spn_dumpp)

        # Signals
        self._brw_pendbase.pathChanged.connect(self._onPathChanged)
        self._brw_exe.pathChanged.connect(self._onPathChanged)

        return layout

    def _onPathChanged(self, path):
        if not path:
            return
        if not self._brw_pendbase.baseDir():
            self._brw_pendbase.setBaseDir(path)
        if not self._brw_exe.baseDir():
            self._brw_exe.setBaseDir(path)

    def hasAcceptableInput(self):
        if not self._brw_pendbase.path():
            return False
        if not self._brw_exe.path():
            return False
        if not os.access(self._brw_exe.path(), os.X_OK):
            return False
        return True

    def setSettings(self, settings):
        if 'penepma' in settings:
            path = getattr(settings.penepma, 'pendbase', None)
            try:
                self._brw_pendbase.setPath(path)
            except ValueError:
                pass

            path = getattr(settings.penepma, 'exe', None)
            try:
                self._brw_exe.setPath(path)
            except ValueError:
                pass

            try:
                dumpp = int(getattr(settings.penepma, 'dumpp', 30))
                self._spn_dumpp.setValue(dumpp)
            except (TypeError, ValueError):
                pass

    def updateSettings(self, settings):
        section = _ConfigurePanelWidget.updateSettings(self, settings)
        section.pendbase = self._brw_pendbase.path()
        section.exe = self._brw_exe.path()
        section.dumpp = int(self._spn_dumpp.value())
        return section
예제 #13
0
class OptionsContainer(QWidget):
    def __init__(self,main_window):
        QWidget.__init__(self)
        self.main_window = main_window
        self.layout = QGridLayout()
        self.setLayout(self.layout)
        
        self.lr = numpy.zeros(2)
        
        self.fps = QSpinBox()
        self.fps.setValue(25)
        self.fps.setMinimum(1)
        self.fps.setMaximum(1000)
        self.layout.addWidget(QLabel("FPS:"),10,10)
        self.layout.addWidget(self.fps,10,11)
        
        self.capture_area_group = QButtonGroup()
        self.capture_area_fs = QRadioButton("Full Screen")
        self.connect(self.capture_area_fs, SIGNAL("clicked()"),self.capture_area_change)
        self.capture_area_fs.setChecked(True)
        self.capture_area_sa = QRadioButton("Selected Area")
        self.connect(self.capture_area_sa, SIGNAL("clicked()"),self.capture_area_change)
        self.capture_area_group.addButton(self.capture_area_fs)
        self.capture_area_group.addButton(self.capture_area_sa)
        self.capture_area_group.setExclusive(True)
        
        self.layout.addWidget(self.capture_area_fs,12,10)
        self.layout.addWidget(self.capture_area_sa,12,11)
        
        self.sa_group = QGroupBox()
        self.sa_grid = QGridLayout()
        self.sa_group.setLayout(self.sa_grid)
        
        
        self.sa_ul_bt = QPushButton("Select Upper Left")
        self.connect(self.sa_ul_bt, SIGNAL("clicked()"), self.select_ul)
        self.sa_lr_bt = QPushButton("Select Lower Right")
        self.connect(self.sa_lr_bt, SIGNAL("clicked()"), self.select_lr)

        self.sa_x = QSpinBox()
        self.sa_y = QSpinBox()
        self.sa_w = QSpinBox()
        self.sa_h = QSpinBox()
        for sb in [self.sa_h,self.sa_w,self.sa_x,self.sa_y]:
            sb.setMaximum(999999)
            sb.setMinimum(0)
        
        self.sa_grid.addWidget(self.sa_ul_bt,14,10,1,1)
        self.sa_grid.addWidget(self.sa_lr_bt,15,10,1,1)
        self.sa_grid.addWidget(QLabel("x"),14,11,1,1)
        self.sa_grid.addWidget(self.sa_x,14,12,1,1)
        self.sa_grid.addWidget(QLabel("y"),15,11,1,1)
        self.sa_grid.addWidget(self.sa_y,15,12,1,1)
        self.sa_grid.addWidget(QLabel("w"),16,11,1,1)
        self.sa_grid.addWidget(self.sa_w,16,12,1,1)
        self.sa_grid.addWidget(QLabel("h"),17,11,1,1)
        self.sa_grid.addWidget(self.sa_h,17,12,1,1)
        
        self.sa_show_bt = QPushButton("Show Area")
        self.sa_show_bt.setCheckable(True)
        self.connect(self.sa_show_bt, SIGNAL("clicked()"), self.show_selected_area)

        
        self.sa_grid.addWidget(self.sa_show_bt,18,10,1,10)
        
        self.sa_group.hide()
        
        self.layout.addWidget(self.sa_group,14,10,1,10)
        
        self.capture_delay = QSpinBox()
        self.capture_delay.setMinimum(0)
        self.capture_delay.setMaximum(10000)
        
        self.layout.addWidget(QLabel("Capture Delay"),18,10,1,1)
        self.layout.addWidget(self.capture_delay,18,11,1,1)
        
        self.capture_bt = QPushButton("Capture")
        self.stop_capture_bt = QPushButton("Stop")
        self.stop_capture_bt.hide()
        self.layout.addWidget(self.capture_bt,20,10,1,10)
        self.layout.addWidget(self.stop_capture_bt,30,10,1,10)
        
        self.ffmpeg_flags = QLineEdit()
        self.ffmpeg_flags.setText("-qscale 0 -vcodec mpeg4")
        self.layout.addWidget(QLabel("FFMPEG Flags:"),40,10)
        self.layout.addWidget(self.ffmpeg_flags,50,10,1,10)
        
        self.encode_bt = QPushButton("Encode Video")
        self.layout.addWidget(self.encode_bt,60,10,1,10)
        
        self.open_dir_bt = QPushButton("Open Directory")
        self.layout.addWidget(self.open_dir_bt,80,10,1,10)
        
        self.connect(self.open_dir_bt, SIGNAL("clicked()"),self.open_cwd)
    
        self.selected_area = SelectedArea()
    
    def show_selected_area(self):
        x = self.sa_x.value()
        y = self.sa_y.value()
        w = self.sa_w.value()
        h = self.sa_h.value()
        
        self.selected_area.setGeometry(x,y,w,h)
        self.selected_area.activateWindow()
        self.selected_area.raise_()
        if(self.sa_show_bt.isChecked()):
            self.selected_area.show()
        else:self.selected_area.hide()
        
    def select_ul(self):
        print "select_ul"
        self.clicked  = False
        self.tw = TransWindow()
        self.tw.mouse_press = False
        self.tw.show()
        
        self.connect(self.tw, SIGNAL("mouse_press()"),self.set_ul)
        
    def select_lr(self):
        print "select_lr"
        self.clicked  = False
        self.tw = TransWindow()
        self.tw.mouse_press = False
        self.tw.show()
        
        self.connect(self.tw, SIGNAL("mouse_press()"),self.set_lr)
    
    def set_ul(self):
        self.sa_x.setValue( self.tw.pos[0])       
        self.sa_y.setValue( self.tw.pos[1])
        self.sa_w.setValue( self.lr[0] - self.sa_x.value())       
        self.sa_h.setValue( self.lr[1] - self.sa_y.value())
        self.show_selected_area()
        
    
    def set_lr(self):
        self.lr = numpy.array([self.tw.pos[0],self.tw.pos[1]])
        self.sa_w.setValue( self.tw.pos[0] - self.sa_x.value())       
        self.sa_h.setValue( self.tw.pos[1] - self.sa_y.value())     
        self.show_selected_area()
        
    
    def capture_area_change(self):
        print "capture_area_change"
        if(self.capture_area_fs.isChecked()):
            self.sa_group.hide()
        else:
            self.sa_group.show()
            
        self.adjustSize()
        self.main_window.adjustSize()
    
    def open_cwd(self):
        #will need to detect os and change accordingly
        os.system("open {}".format(os.getcwd()))
예제 #14
0
class PushupForm(QDialog):
    '''
    classdocs
    '''
    pushupCreated = Signal(Pushup_Model)
    
    def __init__(self, athlete):
        '''
        Constructor
        '''
        QDialog.__init__(self)
        
        self.setWindowTitle("Pushup form")
        self.athlete = athlete
        self.pushupForm = QFormLayout()
        self.createGUI()
        
    def createGUI(self):
        self.series = QSpinBox()
        self.series.setMinimum(1)
        
        self.repetitions = QSpinBox()
        self.repetitions.setMaximum(512)
        
        self.avgHeartRateToggle = QCheckBox()
        self.avgHeartRateToggle.toggled.connect(self._toggleHeartRateSpinBox)
        
        self.avgHeartRate = QSpinBox()
        self.avgHeartRate.setMinimum(30)
        self.avgHeartRate.setMaximum(250)
        self.avgHeartRate.setValue(120)
        self.avgHeartRate.setDisabled(True)
        
        self.dateSelector_widget = QCalendarWidget()
        self.dateSelector_widget.setMaximumDate(QDate.currentDate())
        
        self.addButton = QPushButton("Add pushup")
        self.addButton.setMaximumWidth(90)
        self.addButton.clicked.connect(self._createPushup)
        
        self.cancelButton = QPushButton("Cancel")
        self.cancelButton.setMaximumWidth(90)
        self.cancelButton.clicked.connect(self.reject)
        
        self.pushupForm.addRow("Series", self.series)
        self.pushupForm.addRow("Repetitions", self.repetitions)
        self.pushupForm.addRow("Store average heart rate ? ", self.avgHeartRateToggle)
        self.pushupForm.addRow("Average Heart Rate", self.avgHeartRate)
        self.pushupForm.addRow("Exercise Date", self.dateSelector_widget)
        
        btnsLayout = QVBoxLayout()
        btnsLayout.addWidget(self.addButton)
        btnsLayout.addWidget(self.cancelButton)        
        btnsLayout.setAlignment(Qt.AlignRight)
        
        layoutWrapper = QVBoxLayout()
        layoutWrapper.addLayout(self.pushupForm)
        layoutWrapper.addLayout(btnsLayout)
        
        self.setLayout(layoutWrapper)        
        
    def _createPushup(self):        
        exerciseDate = self.dateSelector_widget.selectedDate()
        exerciseDate = self.qDate_to_date(exerciseDate)
        
        if self.avgHeartRateToggle.isChecked():
            heartRate = self.avgHeartRate.value()
        else:
            heartRate = None
            
        pushup = Pushup_Model(self.athlete._name, 
                              exerciseDate, 
                              heartRate, 
                              self.series.value(),
                              self.repetitions.value())

        self.pushupCreated.emit(pushup)
        self.accept()       
    
    def _toggleHeartRateSpinBox(self):
        if self.avgHeartRateToggle.isChecked():
            self.avgHeartRate.setDisabled(False)
        else:
            self.avgHeartRate.setDisabled(True)
        
    def qDate_to_date(self, qDate):        
        return date(qDate.year(), qDate.month(),qDate.day())
        
예제 #15
0
class MainWindow(QWidget):
    def __init__(self, fixtures_folder, parent=None):
        QWidget.__init__(self, parent)
        self.current_fixture = None
        self.fixtures_folder = fixtures_folder
        self.setWindowTitle("Frangitron DMX program editor")

        self.text = QPlainTextEdit()
        font = QFont("Monospace")
        font.setStyleHint(QFont.TypeWriter)
        font.setPixelSize(16)
        self.text.setFont(font)
        self.text.setStyleSheet(
            "color: white; background-color: rgb(30, 30, 30)")

        self.combo_fixture = QComboBox()

        self.frame_programs = QWidget()
        self.checkboxes_programs = list()
        self.layout_programs = QGridLayout(self.frame_programs)

        self.spinner_offset = QSpinBox()
        self.spinner_offset.setMinimum(1)
        self.spinner_offset.setMaximum(512)
        self.spinner_offset.setValue(1)
        self.spinner_offset.valueChanged.connect(self.address_changed)

        self.doc = QPlainTextEdit()
        self.doc.setReadOnly(True)
        self.doc.setFont(font)

        self.status = QLabel()

        layout = QGridLayout(self)
        layout.addWidget(self.combo_fixture, 0, 1)
        layout.addWidget(self.spinner_offset, 0, 2)
        layout.addWidget(self.frame_programs, 1, 1)
        layout.addWidget(self.text, 0, 0, 3, 1)
        layout.addWidget(self.doc, 2, 1, 1, 2)
        layout.addWidget(self.status, 3, 0, 1, 3)
        layout.setColumnStretch(0, 60)
        layout.setColumnStretch(1, 40)

        self.resize(1280, 800)

        self.streamer = Streamer(self.fixtures_folder)

        self.combo_fixture.addItems(sorted(self.streamer.fixtures))
        self.combo_fixture.currentIndexChanged.connect(self.fixture_changed)

        self.timer = QTimer()
        self.timer.timeout.connect(self.tick)
        self.timer.start(500.0 / FRAMERATE)
        self.should_reload = True

        self.fixture_changed()

    def selected_programs(self):
        return [
            chk.text() for chk in self.checkboxes_programs if chk.isChecked()
        ]

    def update_programs(self):
        selected_programs = self.selected_programs()

        for checkbox_program in self.checkboxes_programs:
            self.layout_programs.removeWidget(checkbox_program)
            checkbox_program.deleteLater()
        self.checkboxes_programs = list()

        for i, program_name in enumerate(
                sorted(self.current_fixture.programs.keys())):
            column = i // 4
            row = i % 4

            new_checkbox = QCheckBox(program_name)
            new_checkbox.setChecked(program_name in selected_programs)

            self.layout_programs.addWidget(new_checkbox, row, column)
            self.checkboxes_programs.append(new_checkbox)

    def address_changed(self):
        self.current_fixture.address = self.spinner_offset.value()
        self.doc.setPlainText(self.current_fixture.doc())
        self.update_programs()

    def fixture_changed(self):
        self.current_fixture = self.streamer.fixtures[
            self.combo_fixture.currentText()]
        self.address_changed()
        self.streamer.reset_expressions()
        with open(self.current_fixture.programs_filepath, 'r') as f_programs:
            self.text.setPlainText(f_programs.read())

    def tick(self):
        if self.should_reload:
            self.current_fixture.reload_programs()
            self.update_programs()
            self.streamer.reset_state()
            program = PROGRAM.replace('__fixture__', self.current_fixture.name)
            program = program.replace('__address__',
                                      str(self.current_fixture.address))
            program = program.replace(
                '__programs__', ", ".join([
                    '"{}"'.format(prog) for prog in self.selected_programs()
                ]))
            self.streamer.load(programs_source=program)
            self.streamer.program_clicked("1")

        else:
            state = self.streamer.state

            if state:
                self.status.setStyleSheet(
                    "background-color: green; color: white; padding: 5px")
                self.status.setText(state.context)
            else:
                self.status.setStyleSheet(
                    "background-color: red; color: white; padding: 5px")
                self.status.setText("{} : {}".format(state.context,
                                                     state.exception))

            if self.current_fixture is None: return

            with open(self.current_fixture.programs_filepath,
                      'w') as f_programs:
                f_programs.write(self.text.toPlainText())

        self.should_reload = not self.should_reload

    def closeEvent(self, event):
        self.timer.stop()
        self.streamer.load(programs_source="")
        self.streamer.program_clicked("1")
        sleep(2.0 / float(FRAMERATE))
        self.streamer.stop()
        event.accept()
예제 #16
0
class RunnerDialog(QDialog):

    options_added = Signal(Options)
    options_running = Signal(Options)
    options_simulated = Signal(Options)
    options_error = Signal(Options, Exception)
    results_saved = Signal(Results, str)
    results_error = Signal(Results, Exception)

    def __init__(self, parent=None):
        QDialog.__init__(self, parent)
        self.setWindowTitle('Runner')
        self.setMinimumWidth(750)

        # Runner
        self._runner = None

        self._running_timer = QTimer()
        self._running_timer.setInterval(500)

        # Widgets
        self._dlg_progress = QProgressDialog()
        self._dlg_progress.setRange(0, 100)
        self._dlg_progress.setModal(True)
        self._dlg_progress.hide()

        lbl_outputdir = QLabel("Output directory")
        self._txt_outputdir = DirBrowseWidget()

        max_workers = cpu_count() #@UndefinedVariable
        lbl_workers = QLabel('Number of workers')
        self._spn_workers = QSpinBox()
        self._spn_workers.setRange(1, max_workers)
        self._spn_workers.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        lbl_max_workers = QLabel('(max: %i)' % max_workers)

        self._chk_overwrite = QCheckBox("Overwrite existing results in output directory")
        self._chk_overwrite.setChecked(True)

        self._lbl_available = QLabel('Available')
        self._lst_available = QListView()
        self._lst_available.setModel(_AvailableOptionsListModel())
        self._lst_available.setSelectionMode(QListView.SelectionMode.MultiSelection)

        tlb_available = QToolBar()
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        tlb_available.addWidget(spacer)
        act_open = tlb_available.addAction(getIcon("document-open"), "Open")
        act_open.setShortcut(QKeySequence.Open)
        tlb_available.addSeparator()
        act_remove = tlb_available.addAction(getIcon("list-remove"), "Remove")
        act_clear = tlb_available.addAction(getIcon("edit-clear"), "Clear")

        self._btn_addtoqueue = QPushButton(getIcon("go-next"), "")
        self._btn_addtoqueue.setToolTip("Add to queue")
        self._btn_addtoqueue.setEnabled(False)

        self._btn_addalltoqueue = QPushButton(getIcon("go-last"), "")
        self._btn_addalltoqueue.setToolTip("Add all to queue")
        self._btn_addalltoqueue.setEnabled(False)

        self._lbl_options = QLabel('Queued/Running/Completed')
        self._tbl_options = QTableView()
        self._tbl_options.setModel(_StateOptionsTableModel())
        self._tbl_options.setItemDelegate(_StateOptionsItemDelegate())
        self._tbl_options.setSelectionMode(QListView.SelectionMode.NoSelection)
        self._tbl_options.setColumnWidth(1, 60)
        self._tbl_options.setColumnWidth(2, 80)
        header = self._tbl_options.horizontalHeader()
        header.setResizeMode(0, QHeaderView.Interactive)
        header.setResizeMode(1, QHeaderView.Fixed)
        header.setResizeMode(2, QHeaderView.Fixed)
        header.setResizeMode(3, QHeaderView.Stretch)

        self._btn_start = QPushButton(getIcon("media-playback-start"), "Start")

        self._btn_cancel = QPushButton("Cancel")
        self._btn_cancel.setEnabled(False)

        self._btn_close = QPushButton("Close")

        self._btn_import = QPushButton("Import")
        self._btn_import.setEnabled(False)

        # Layouts
        layout = QVBoxLayout()

        sublayout = QGridLayout()
        sublayout.addWidget(lbl_outputdir, 0, 0)
        sublayout.addWidget(self._txt_outputdir, 0, 1)
        sublayout.addWidget(lbl_workers, 1, 0)

        subsublayout = QHBoxLayout()
        subsublayout.addWidget(self._spn_workers)
        subsublayout.addWidget(lbl_max_workers)
        sublayout.addLayout(subsublayout, 1, 1)
        layout.addLayout(sublayout)

        sublayout.addWidget(self._chk_overwrite, 2, 0, 1, 3)

        sublayout = QGridLayout()
        sublayout.setColumnStretch(0, 1)
        sublayout.setColumnStretch(2, 3)
        sublayout.addWidget(self._lbl_available, 0, 0)
        sublayout.addWidget(self._lst_available, 1, 0)
        sublayout.addWidget(tlb_available, 2, 0)

        subsublayout = QVBoxLayout()
        subsublayout.addStretch()
        subsublayout.addWidget(self._btn_addtoqueue)
        subsublayout.addWidget(self._btn_addalltoqueue)
        subsublayout.addStretch()
        sublayout.addLayout(subsublayout, 1, 1)

        sublayout.addWidget(self._lbl_options, 0, 2)
        sublayout.addWidget(self._tbl_options, 1, 2)
        layout.addLayout(sublayout)

        sublayout = QHBoxLayout()
        sublayout.addStretch()
        sublayout.addWidget(self._btn_import)
        sublayout.addWidget(self._btn_start)
        sublayout.addWidget(self._btn_cancel)
        sublayout.addWidget(self._btn_close)
        layout.addLayout(sublayout)

        self.setLayout(layout)

        # Signal
        self._running_timer.timeout.connect(self._onRunningTimer)

        act_open.triggered.connect(self._onOpen)
        act_remove.triggered.connect(self._onRemove)
        act_clear.triggered.connect(self._onClear)

        self._btn_addtoqueue.released.connect(self._onAddToQueue)
        self._btn_addalltoqueue.released.connect(self._onAddAllToQueue)
        self._btn_start.released.connect(self._onStart)
        self._btn_cancel.released.connect(self._onCancel)
        self._btn_close.released.connect(self._onClose)
        self._btn_import.released.connect(self._onImport)

        self.options_added.connect(self._onOptionsAdded)
        self.options_running.connect(self._onOptionsRunning)
        self.options_simulated.connect(self._onOptionsSimulated)
        self.options_error.connect(self._onOptionsError)
        self.results_error.connect(self._onResultsError)

        # Defaults
        settings = get_settings()
        section = settings.add_section('gui')
        if hasattr(section, 'outputdir'):
            self._txt_outputdir.setPath(section.outputdir)
        if hasattr(section, 'maxworkers'):
            self._spn_workers.setValue(int(section.maxworkers))
        if hasattr(section, 'overwrite'):
            state = True if section.overwrite.lower() == 'true' else False
            self._chk_overwrite.setChecked(state)

    def _onDialogProgressProgress(self, progress, status):
        self._dlg_progress.setValue(progress * 100)
        self._dlg_progress.setLabelText(status)

    def _onDialogProgressCancel(self):
        self._dlg_progress.hide()
        if self._options_reader_thread is None:
            return
        self._options_reader_thread.cancel()
        self._options_reader_thread.quit()
        self._options_reader_thread.wait()

    def _onDialogProgressException(self, ex):
        self._dlg_progress.hide()
        self._options_reader_thread.quit()
        self._options_reader_thread.wait()
        messagebox.exception(self, ex)

    def _onRunningTimer(self):
        self._tbl_options.model().reset()

    def _onOpen(self):
        settings = get_settings()
        curdir = getattr(settings.gui, 'opendir', os.getcwd())

        filepath, namefilter = \
            QFileDialog.getOpenFileName(self, "Open", curdir,
                                        'Options [*.xml] (*.xml)')

        if not filepath or not namefilter:
            return
        settings.gui.opendir = os.path.dirname(filepath)

        if not filepath.endswith('.xml'):
            filepath += '.xml'

        self._options_reader_thread = _OptionsReaderWrapperThread(filepath)
        self._dlg_progress.canceled.connect(self._onDialogProgressCancel)
        self._options_reader_thread.resultReady.connect(self._onOpened)
        self._options_reader_thread.progressUpdated.connect(self._onDialogProgressProgress)
        self._options_reader_thread.exceptionRaised.connect(self._onDialogProgressException)
        self._options_reader_thread.start()

        self._dlg_progress.reset()
        self._dlg_progress.show()

    def _onOpened(self, options):
        self._dlg_progress.hide()
        self._options_reader_thread.quit()
        self._options_reader_thread.wait()
        self._options_reader_thread = None

        try:
            self._lst_available.model().addOptions(options)
        except Exception as ex:
            messagebox.exception(self, ex)

    def _onRemove(self):
        selection = self._lst_available.selectionModel().selection().indexes()
        if len(selection) == 0:
            QMessageBox.warning(self, "Queue", "Select an options")
            return

        model = self._lst_available.model()
        for row in sorted(map(methodcaller('row'), selection), reverse=True):
            model.popOptions(row)

    def _onClear(self):
        self._lst_available.model().clearOptions()

    def _onAddToQueue(self):
        selection = self._lst_available.selectionModel().selection().indexes()
        if len(selection) == 0:
            QMessageBox.warning(self, "Queue", "Select an options")
            return

        model = self._lst_available.model()
        for row in sorted(map(methodcaller('row'), selection), reverse=True):
            options = model.options(row)
            try:
                self._runner.put(options)
            except Exception as ex:
                messagebox.exception(self, ex)
                return

    def _onAddAllToQueue(self):
        model = self._lst_available.model()
        for row in reversed(range(0, model.rowCount())):
            options = model.options(row)
            try:
                self._runner.put(options)
            except Exception as ex:
                messagebox.exception(self, ex)
                return

    def _onStart(self):
        outputdir = self._txt_outputdir.path()
        if not outputdir:
            QMessageBox.critical(self, 'Start', 'Missing output directory')
            return
        max_workers = self._spn_workers.value()
        overwrite = self._chk_overwrite.isChecked()
        self.start(outputdir, overwrite, max_workers)

    def _onCancel(self):
        self.cancel()

    def _onClose(self):
        if self._runner is not None:
            self._runner.close()
        self._running_timer.stop()
        self.close()

    def _onImport(self):
        list_options = self._lst_available.model().listOptions()
        if not list_options:
            return

        # Select options
        dialog = _OptionsSelector(list_options)
        if not dialog.exec_():
            return
        options = dialog.options()

        # Start importer
        outputdir = self._runner.outputdir
        max_workers = self._runner.max_workers
        importer = LocalImporter(outputdir, max_workers)

        importer.start()
        importer.put(options)

        self._dlg_progress.show()
        try:
            while importer.is_alive():
                if self._dlg_progress.wasCanceled():
                    importer.cancel()
                    break
                self._dlg_progress.setValue(importer.progress * 100)
        finally:
            self._dlg_progress.hide()

    def _onOptionsAdded(self, options):
        logging.debug('runner: optionsAdded')
        self._tbl_options.model().addOptions(options)

    def _onOptionsRunning(self, options):
        logging.debug('runner: optionsRunning')
        self._tbl_options.model().resetOptions(options)

    def _onOptionsSimulated(self, options):
        logging.debug('runner: optionsSimulated')
        self._tbl_options.model().resetOptions(options)

    def _onOptionsError(self, options, ex):
        logging.debug('runner: optionsError')
        self._tbl_options.model().resetOptions(options)

    def _onResultsError(self, results, ex):
        logging.debug('runner: resultsError')
        self._tbl_options.model().reset()

    def closeEvent(self, event):
        if self.is_running():
            message = 'Runner is running. Do you want to continue?'
            answer = QMessageBox.question(self, 'Runner', message,
                                          QMessageBox.Yes | QMessageBox.No)
            if answer == QMessageBox.No:
                event.ignore()
                return

        self.cancel()
        self._dlg_progress.close()

        settings = get_settings()
        section = settings.add_section('gui')

        path = self._txt_outputdir.path()
        if path:
            section.outputdir = path
        section.maxworkers = str(self._spn_workers.value())
        section.overwrite = str(self._chk_overwrite.isChecked())

        settings.write()

        event.accept()

    def addAvailableOptions(self, options):
        self._lst_available.model().addOptions(options)

    def removeAvailableOptions(self, options):
        self._lst_available.model().removeOptions(options)

    def clearAvailableOptions(self):
        self._lbl_available.model().clearOptions()

    def start(self, outputdir, overwrite, max_workers):
        self._runner = LocalRunner(outputdir=outputdir,
                                   overwrite=overwrite,
                                   max_workers=max_workers)

        self._tbl_options.setModel(_StateOptionsTableModel(self._runner))

        self._spn_workers.setEnabled(False)
        self._txt_outputdir.setEnabled(False)
        self._chk_overwrite.setEnabled(False)
        self._btn_addtoqueue.setEnabled(True)
        self._btn_addalltoqueue.setEnabled(True)
        self._btn_start.setEnabled(False)
        self._btn_cancel.setEnabled(True)
        self._btn_close.setEnabled(False)
        self._btn_import.setEnabled(True)

        self._runner.options_added.connect(self.options_added.emit)
        self._runner.options_running.connect(self.options_running.emit)
        self._runner.options_simulated.connect(self.options_simulated.emit)
        self._runner.options_error.connect(self.options_error.emit)
        self._runner.results_saved.connect(self.results_saved.emit)
        self._runner.results_error.connect(self.results_error.emit)

        self._running_timer.start()
        self._runner.start()

    def cancel(self):
        if self._runner is None:
            return
        self._runner.cancel()
        self._running_timer.stop()

        self._runner.options_added.disconnect(self.options_added.emit)
        self._runner.options_running.disconnect(self.options_running.emit)
        self._runner.options_simulated.disconnect(self.options_simulated.emit)
        self._runner.options_error.disconnect(self.options_error.emit)
        self._runner.results_saved.disconnect(self.results_saved.emit)
        self._runner.results_error.disconnect(self.results_error.emit)

        self._runner = None

        self._spn_workers.setEnabled(True)
        self._txt_outputdir.setEnabled(True)
        self._chk_overwrite.setEnabled(True)
        self._btn_addtoqueue.setEnabled(False)
        self._btn_addalltoqueue.setEnabled(False)
        self._btn_start.setEnabled(True)
        self._btn_cancel.setEnabled(False)
        self._btn_close.setEnabled(True)
        self._btn_import.setEnabled(False)

    def is_running(self):
        return self._runner is not None and self._runner.is_alive()
class DoFPParametersDialog(QDialog):
  
  AFTER_CONSTRUCTION_ALLFRAC = 1
  AFTER_CONSTRUCTION_RANGESTRING = 2
  AFTER_CONSTRUCTION_TOTOP = 3
  
  def __init__(self, rangeConstructor=1.0,  boardCombo=None, title="Enter first range arguments", parent=None):
    super(DoFPParametersDialog, self).__init__(parent)
    self._after_method = 2
    self._board_combo = boardCombo
    label_constructor = QLabel("Constructor argument <b>(initFrac)</b>")
    self._spinbox_constructor = QSpinBox()
    self._spinbox_constructor.setMaximum(9999)
    self._spinbox_constructor.setValue(rangeConstructor)
    label_after_construction = QLabel("After construction method")
    self._radiogroup_methods = HorizontalRadioGroup(["setRangeString()", "setAllFracs()", "setToTop()"])
    self._radiogroup_methods.radio_checked.connect(self._updateLayout)
    self._radiogroup_methods._radios[0].setChecked(True) # dunno why it's not checked by default
    label_method_args = QLabel("Method arguments")
    self._widget_method_args = SetRangeStringCompound()
    button_ok = QPushButton("Ok")
    button_ok.clicked.connect(self.accept)
    button_cancel = QPushButton("Cancel")
    button_cancel.clicked.connect(self.reject)
    layout = QGridLayout()
    row = 0; col = 0;
    layout.addWidget(label_constructor, row, col)
    col += 1
    layout.addWidget(self._spinbox_constructor, row, col)
    row += 1; col = 0;
    layout.addWidget(label_after_construction, row, col)
    col += 1
    layout.addWidget(self._radiogroup_methods)
    row += 1; col = 0;
    layout.addWidget(label_method_args, row, col)
    col += 1
    self._update_pos = (row, col)
    layout.addWidget(self._widget_method_args, row, col)
    row += 1; col = 0
    layout.addWidget(button_ok, row, col)
    col += 1
    layout.addWidget(button_cancel, row, col)
    self.setLayout(layout)
    self.setWindowTitle(title)
    
  def _updateLayout(self, radioString):
    self._widget_method_args.setParent(None)
    self.layout().removeWidget(self._widget_method_args)
    if radioString == "setRangeString()":
      self._after_method = self.AFTER_CONSTRUCTION_RANGESTRING
      self._widget_method_args = SetRangeStringCompound()
    elif radioString == "setAllFracs()":
      self._after_method = self.AFTER_CONSTRUCTION_ALLFRAC
      self._widget_method_args = SetAllFracsSpinBox()
    elif radioString == "setToTop()":
      self._after_method = self.AFTER_CONSTRUCTION_TOTOP
      self._widget_method_args = SetToTopCompound(self._board_combo)
    self.layout().update()
    self.layout().addWidget(self._widget_method_args, self._update_pos[0], self._update_pos[1])
    
  def getRange(self):
    # construct a range object and return it
    r = Range(self._spinbox_constructor.value())
    if self._after_method == self.AFTER_CONSTRUCTION_ALLFRAC:
      r.setAllFracs(self._widget_method_args.value())
    elif self._after_method == self.AFTER_CONSTRUCTION_RANGESTRING:
      r.setRangeString(self._widget_method_args.lineedit_string.text(), 
                       self._widget_method_args.spinbox_value.value())
    elif self._after_method == self.AFTER_CONSTRUCTION_TOTOP:
      r.setToTop(self._widget_method_args.spinbox_fraction.value(), 
                 self._board_combo.boards()[self._widget_method_args.combobox_board.currentIndex()])
    return r
예제 #18
0
class MainWindow(QMainWindow):  # Sets up the main window
    def resize_window(self):  # Function for resizing the window
        self.resize(self.minimumSizeHint())

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

        # Set window Icon
        self.setWindowTitle(__appname__)
        iconImage = QImage(iconByteArray)
        iconPixmap = QPixmap(iconImage)
        self.setWindowIcon(QIcon(iconPixmap))

        # Set up private key format widgets
        privateKeyFormatLayout = QHBoxLayout()
        privateKeyFormatLabel = QLabel('Select Key Format: ')
        self.privateKeyTypeCombobox = QComboBox()
        self.privateKeyTypeCombobox.addItems(privateKeyFormats)
        self.privateKeyLengthLabel = QLabel('0')
        privateKeyFormatLayout.addWidget(privateKeyFormatLabel)
        privateKeyFormatLayout.addWidget(self.privateKeyTypeCombobox)
        privateKeyFormatLayout.addWidget(self.privateKeyLengthLabel)

        # Set up private key text widgets
        privateKeyLayout = QVBoxLayout()
        privateKeyButtonsLayout = QHBoxLayout()
        generatePrivateKeyButton = QPushButton('Generate Key')
        generatePrivateKeyButton.clicked.connect(self.get_private_key)
        self.copyPrivateKeyButton = QPushButton('Copy Key')
        self.copyPrivateKeyButton.setDisabled(True)
        self.copyPrivateKeyButton.clicked.connect(self.copy_private_key)
        privateKeyButtonsLayout.addWidget(generatePrivateKeyButton)
        privateKeyButtonsLayout.addWidget(self.copyPrivateKeyButton)
        self.privateKeyEdit = GrowingTextEdit()
        self.privateKeyEdit.setFont(QFont('Courier'))
        self.privateKeyEdit.textChanged.connect(
            self.private_key_or_code_changed)
        privateKeyLayout.addLayout(privateKeyButtonsLayout)
        privateKeyLayout.addWidget(self.privateKeyEdit)

        # Set up cypher code widgets
        codeLayout = QHBoxLayout()
        codeLabel = QLabel('Select Cypher Code: ')
        self.codeSelect = QSpinBox()
        self.codeSelect.setValue(10)
        self.codeSelect.setMinimum(2)
        self.codeSelect.setDisabled(True)
        self.codeSelect.valueChanged.connect(self.private_key_or_code_changed)
        codeLayout.addWidget(codeLabel)
        codeLayout.addWidget(self.codeSelect)

        # Set up cypher text widgets
        cypherLayout = QVBoxLayout()
        cypherButtonsLayout = QHBoxLayout()
        cardButtonsLayout = QHBoxLayout()
        self.generateCypherButton = QPushButton('Generate Cypher')
        self.generateCypherButton.clicked.connect(self.get_cypher)
        self.generateCypherButton.setDisabled(True)
        self.copyCypherButton = QPushButton('Copy Cypher')
        self.copyCypherButton.setDisabled(True)
        self.copyCypherButton.clicked.connect(self.copy_cypher)
        cypherButtonsLayout.addWidget(self.generateCypherButton)
        cypherButtonsLayout.addWidget(self.copyCypherButton)
        self.cypherEdit = GrowingTextEdit()
        self.cypherEdit.setFont(QFont('Courier'))
        self.cypherEdit.setReadOnly(True)
        self.cypherEdit.setVisible(False)
        self.cypherEdit.textChanged.connect(self.resize_window)
        self.cypherPreviewLabel = QLabel('-CYPHER PREVIEW-')
        self.cypherPreviewLabel.setAlignment(Qt.AlignCenter)
        self.cypherPreviewLabel.setVisible(False)
        self.cypherPreview = GrowingTextEdit()
        self.cypherPreview.setFont(QFont('Courier'))
        self.cypherPreview.setAlignment(Qt.AlignHCenter)
        self.cypherPreview.setWordWrapMode(QTextOption.NoWrap)
        self.cypherPreview.setReadOnly(True)
        self.cypherPreview.setVisible(False)
        self.cypherCardsPrintButton = QPushButton('Print Cypher Cards')
        self.cypherCardsPrintButton.setVisible(False)
        self.cypherCardsPrintButton.clicked.connect(partial(self.cards, True))
        self.cypherCardsCopyButton = QPushButton('Copy Cypher Cards')
        self.cypherCardsCopyButton.setVisible(False)
        self.cypherCardsCopyButton.clicked.connect(partial(self.cards, False))
        cardButtonsLayout.addWidget(self.cypherCardsPrintButton)
        cardButtonsLayout.addWidget(self.cypherCardsCopyButton)
        cypherLayout.addLayout(cypherButtonsLayout)
        cypherLayout.addWidget(self.cypherEdit)
        cypherLayout.addWidget(self.cypherPreviewLabel)
        cypherLayout.addWidget(self.cypherPreview)
        cypherLayout.addLayout(cardButtonsLayout)

        # Set up donation widgets
        donationsLayout = QVBoxLayout()
        separater = QFrame()
        separater.setFrameShape(QFrame.HLine)
        self.donationButton = QPushButton('Donate')
        self.donationButton.setVisible(False)
        self.donationButton.clicked.connect(self.donate)
        self.copyEthAddressButton = QPushButton('ETH: Copy Address')
        self.copyEthAddressButton.clicked.connect(
            self.copy_eth_donation_address)
        self.copyEthAddressButton.setVisible(False)
        self.copyBtcAddressButton = QPushButton('BTC: Copy Address')
        self.copyBtcAddressButton.clicked.connect(
            self.copy_btc_donation_address)
        self.copyBtcAddressButton.setVisible(False)
        donationsLayout.addWidget(separater)
        donationsLayout.addWidget(self.donationButton)
        donationsLayout.addWidget(self.copyEthAddressButton)
        donationsLayout.addWidget(self.copyBtcAddressButton)

        # Add all widgets and sub-layouts to the master layout
        self.master_layout = QVBoxLayout()
        self.master_layout.addLayout(privateKeyFormatLayout)
        self.master_layout.addLayout(privateKeyLayout)
        self.master_layout.addLayout(codeLayout)
        self.master_layout.addLayout(cypherLayout)
        self.master_layout.addLayout(donationsLayout)
        self.master_widget = QWidget()
        self.master_widget.setLayout(self.master_layout)
        self.setCentralWidget(self.master_widget)

        # Start and connect the window resizing thread
        self.worker = Worker()
        self.worker.updateWindowSize.connect(self.resize_window)

    def copy_private_key(
            self):  # Copies the private key text to the system clipboard
        clip.setText(self.privateKeyEdit.toPlainText())
        self.copyPrivateKeyButton.setText('Key Copied')
        app.processEvents()
        sleep(2)
        self.copyPrivateKeyButton.setText('Copy Key')

    def copy_cypher(self):  # Copies the cypher text to the system clipboard
        clip.setText(self.cypherEdit.toPlainText())
        self.copyCypherButton.setText('Cypher Copied')
        app.processEvents()
        sleep(2)
        self.copyCypherButton.setText('Copy Cypher')

    def copy_eth_donation_address(
            self):  # Copies the ETH donation address to the system clipboard
        clip.setText(ethDonationAddress)
        self.copyEthAddressButton.setText('ETH: Address Copied\nThanks!')
        app.processEvents()
        sleep(2)
        self.copyEthAddressButton.setText('ETH: Copy Address')

    def copy_btc_donation_address(
            self):  # Copies the BTC donation address to the system clipboard
        clip.setText(btcDonationAddress)
        self.copyBtcAddressButton.setText('BTC: Address Copied\nThanks!')
        app.processEvents()
        sleep(2)
        self.copyBtcAddressButton.setText('BTC: Copy Address')

    def get_private_key(
        self
    ):  # Generates a key of the desired format using two instances of the SystemRandom function
        privateKey = generate_private_key.start(
            self.privateKeyTypeCombobox.currentText())
        self.privateKeyEdit.setText(privateKey)
        self.private_key_or_code_changed()
        self.copyPrivateKeyButton.setDisabled(False)

    def private_key_or_code_changed(
        self
    ):  # Changes visibility and ability of some widgets based on user input
        self.privateKeyLengthLabel.setText(
            str(len(self.privateKeyEdit.toPlainText())))
        self.copyCypherButton.setDisabled(True)
        self.cypherEdit.setText('')
        self.cypherPreview.setText('')
        self.cypherEdit.setVisible(False)
        self.cypherPreviewLabel.setVisible(False)
        self.cypherPreview.setVisible(False)
        if len(self.privateKeyEdit.toPlainText()) <= 2:
            self.copyPrivateKeyButton.setDisabled(True)
            self.generateCypherButton.setDisabled(True)
            self.codeSelect.setDisabled(True)
        else:
            self.codeSelect.setMaximum(
                len(self.privateKeyEdit.toPlainText()) - 1)
            self.copyPrivateKeyButton.setDisabled(False)
            self.generateCypherButton.setDisabled(False)
            self.codeSelect.setDisabled(False)
        self.cypherCardsPrintButton.setDisabled(True)
        self.cypherCardsPrintButton.setVisible(False)
        self.cypherCardsCopyButton.setDisabled(True)
        self.cypherCardsCopyButton.setVisible(False)
        self.worker.start()

    def get_cypher(
        self
    ):  # Converts the raw key into a cypher based on the codeSelect value
        if not 1 >= len(self.privateKeyEdit.toPlainText()) >= int(
                self.privateKeyLengthLabel.text()):
            self.generateCypherButton.setDisabled(False)
            cypherRows, cypherSeed = create_cypher.start(
                self.privateKeyEdit.toPlainText(), self.codeSelect.value())
            self.copyCypherButton.setDisabled(False)
            self.cypherEdit.setVisible(True)
            self.cypherEdit.setText(cypherSeed)
            self.cypherPreviewLabel.setVisible(True)
            self.cypherPreview.setVisible(True)
            previewText = ''
            for i in cypherRows:
                previewText += i + '\n'
            self.cypherPreview.setText(previewText)
            self.worker.start()
            self.cypherCardsPrintButton.setDisabled(False)
            self.cypherCardsPrintButton.setVisible(True)
            self.cypherCardsCopyButton.setDisabled(False)
            self.cypherCardsCopyButton.setVisible(True)
            self.donationButton.setVisible(True)
        else:
            self.generateCypherButton.setDisabled(True)

    def cards(self, print):  # Creates and prints the output.txt file
        cardList = split_cypher_into_pairs.start(self.cypherEdit.toPlainText())
        printString = format_cards.start(cardList)
        if print:
            self.cypherCardsPrintButton.setText('Printing')
            app.processEvents()
            cards_output.start(printString)
            self.cypherCardsPrintButton.setText('Print Cypher Cards')
        else:
            clip.setText(printString)
            self.cypherCardsCopyButton.setText('Cards Copied')
            app.processEvents()
            sleep(2)
            self.cypherCardsCopyButton.setText('Copy Cypher Cards')

    def donate(self):  # Adjusts the visibility of the donation buttons
        if self.donationButton.text() == 'Donate':
            self.copyEthAddressButton.setVisible(True)
            self.copyBtcAddressButton.setVisible(True)
            self.donationButton.setText('Hide')
        elif self.donationButton.text() == 'Hide':
            self.copyEthAddressButton.setVisible(False)
            self.copyBtcAddressButton.setVisible(False)
            self.donationButton.setText('Donate')
        self.worker.start()

    def cleanup(self):  # Clears the clipboard of any copied text
        clip.setText('')
예제 #19
0
class MainWindow(QMainWindow):
	def __init__(self):
		super(MainWindow, self).__init__()		
		self.debug = debug

		self.progset = QSettings("ADLMIDI-pyGUI", "ADLMIDI-pyGUI")
		
		self.about_window = None
		self.settings_window = None
		self.paused = False

		self.MaxRecentFiles = int(self.progset.value("file/MaxRecentFiles", 5))

		self.recentList = self.progset.value("file/recent", [])
		if type(self.recentList) is unicode: self.recentList = [self.recentList]

		self.banks = [	" 0 = AIL (Star Control 3, Albion, Empire 2, Sensible Soccer, Settlers 2, many others)",
						"01 = Bisqwit (selection of 4op and 2op)",
						"02 = HMI (Descent, Asterix)",
						"03 = HMI (Descent:: Int)",
						"04 = HMI (Descent:: Ham)",
						"05 = HMI (Descent:: Rick)",
						"06 = HMI (Descent 2)",
						"07 = HMI (Normality)",
						"08 = HMI (Shattered Steel)",
						"09 = HMI (Theme Park)",
						"10 = HMI (3d Table Sports, Battle Arena Toshinden)",
						"11 = HMI (Aces of the Deep)",
						"12 = HMI (Earthsiege)",
						"13 = HMI (Anvil of Dawn)",
						"14 = DMX (Doom           :: partially pseudo 4op)",
						"15 = DMX (Hexen, Heretic :: partially pseudo 4op)",
						"16 = DMX (MUS Play       :: partially pseudo 4op)",
						"17 = AIL (Discworld, Grandest Fleet, Pocahontas, Slob Zone 3d, Ultima 4, Zorro)",
						"18 = AIL (Warcraft 2)",
						"19 = AIL (Syndicate)",
						"20 = AIL (Guilty, Orion Conspiracy, Terra Nova Strike Force Centauri :: 4op)",
						"21 = AIL (Magic Carpet 2)",
						"22 = AIL (Nemesis)",
						"23 = AIL (Jagged Alliance)",
						"24 = AIL (When Two Worlds War :: 4op, MISSING INSTRUMENTS)",
						"25 = AIL (Bards Tale Construction :: MISSING INSTRUMENTS)",
						"26 = AIL (Return to Zork)",
						"27 = AIL (Theme Hospital)",
						"28 = AIL (National Hockey League PA)",
						"29 = AIL (Inherit The Earth)",
						"30 = AIL (Inherit The Earth, file two)",
						"31 = AIL (Little Big Adventure :: 4op)",
						"32 = AIL (Wreckin Crew)",
						"33 = AIL (Death Gate)",
						"34 = AIL (FIFA International Soccer)",
						"35 = AIL (Starship Invasion)",
						"36 = AIL (Super Street Fighter 2 :: 4op)",
						"37 = AIL (Lords of the Realm :: MISSING INSTRUMENTS)",
						"38 = AIL (SimFarm, SimHealth :: 4op)",
						"39 = AIL (SimFarm, Settlers, Serf City)",
						"40 = AIL (Caesar 2 :: partially 4op, MISSING INSTRUMENTS)",
						"41 = AIL (Syndicate Wars)",
						"42 = AIL (Bubble Bobble Feat. Rainbow Islands, Z)",
						"43 = AIL (Warcraft)",
						"44 = AIL (Terra Nova Strike Force Centuri :: partially 4op)",
						"45 = AIL (System Shock :: partially 4op)",
						"46 = AIL (Advanced Civilization)",
						"47 = AIL (Battle Chess 4000 :: partially 4op, melodic only)",
						"48 = AIL (Ultimate Soccer Manager :: partially 4op)",
						"49 = AIL (Air Bucks, Blue And The Gray, America Invades, Terminator 2029)",
						"50 = AIL (Ultima Underworld 2)",
						"51 = AIL (Kasparov's Gambit)",
						"52 = AIL (High Seas Trader :: MISSING INSTRUMENTS)",
						"53 = AIL (Master of Magic, Master of Orion 2 :: 4op, std percussion)",
						"54 = AIL (Master of Magic, Master of Orion 2 :: 4op, orchestral percussion)",
						"55 = SB  (Action Soccer)",
						"56 = SB  (3d Cyberpuck :: melodic only)",
						"57 = SB  (Simon the Sorcerer :: melodic only)",
						"58 = OP3 (The Fat Man 2op set)",
						"59 = OP3 (The Fat Man 4op set)",
						"60 = OP3 (JungleVision 2op set :: melodic only)",
						"61 = OP3 (Wallace 2op set, Nitemare 3D :: melodic only)",
						"62 = TMB (Duke Nukem 3D)",
						"63 = TMB (Shadow Warrior)",
						"64 = DMX (Raptor)"
					]
					
		self.openicon  = QIcon.fromTheme('document-open', QIcon('img/load.png'))
		self.saveicon  = QIcon.fromTheme('document-save', QIcon('img/save.png'))
		self.playicon  = QIcon.fromTheme('media-playback-start', QIcon('img/play.png'))
		self.pauseicon = QIcon.fromTheme('media-playback-pause', QIcon('img/pause.png'))
		self.stopicon  = QIcon.fromTheme('media-playback-stop', QIcon('img/stop.png'))
		self.quiticon  = QIcon.fromTheme('application-exit', QIcon('img/quit.png'))
		self.abouticon = QIcon.fromTheme('help-about', QIcon('img/about.png'))
		self.setticon  = QIcon.fromTheme('preferences-desktop', QIcon('img/settings.png'))

		self.winsetup()

	def addWorker(self, worker):
		worker.message.connect(self.update)
		worker.finished.connect(self.workerFinished)
		self.threads.append(worker)

	def workerFinished(self):
		pass
		#barf('MSG', 'Thread completed the task!')

	def killWorkers(self):
		pass
		#for worker in self.threads:
		#	worker.terminate()
		
	def winsetup(self):
		self.setWindowIcon(QIcon('img/note.png'))
		
		openFile = QAction(self.openicon, 'Open', self)
		openFile.setShortcut('Ctrl+O')
		openFile.triggered.connect(self.load)
		
		saveFile = QAction(self.saveicon, 'Save', self)
		saveFile.setShortcut('Ctrl+S')
		saveFile.triggered.connect(self.save)
		
		playFile = QAction(self.playicon, 'Play', self)
		playFile.setShortcut('Ctrl+P')
		playFile.triggered.connect(self.play)
		
		pausePlayb = QAction(self.pauseicon, 'Pause', self)
		pausePlayb.setShortcut('Ctrl+R')
		pausePlayb.triggered.connect(self.pause)
		
		stopPlay = QAction(self.stopicon, 'Stop', self)
		stopPlay.setShortcut('Ctrl+Z')
		stopPlay.triggered.connect(self.stop)
		
		exitAction = QAction(self.quiticon, 'Quit', self)
		exitAction.setShortcut('Ctrl+X')
		exitAction.triggered.connect(self.quit)
		
		aboutdlg = QAction(self.abouticon, 'About', self)
		aboutdlg.setShortcut('Ctrl+A')
		aboutdlg.triggered.connect(self.about)
		
		showSett = QAction(self.setticon, 'Settings', self)
		showSett.triggered.connect(self.settings)

		menubar = self.menuBar()

		fileMenu = menubar.addMenu('&File')
		configMenu = menubar.addMenu('&Options')
		configMenu.setStyleSheet("border: 1px solid black;")
		
		self.setLooped = QAction('Loop', configMenu, checkable=True)
		if self.progset.value("sound/Looped") == 'true': self.setLooped.setChecked(True)
		else: self.setLooped.setChecked(False)
		self.setLooped.setShortcut('Ctrl+L')
		
		self.setAutoplay = QAction('Autoplay', configMenu, checkable=True)
		if self.progset.value("sound/Autoplay") == 'true': self.setAutoplay.setChecked(True)
		else: self.setAutoplay.setChecked(False)
		self.setAutoplay.setShortcut('Ctrl+K')
		
		configMenu.addAction(self.setAutoplay)
		configMenu.addAction(self.setLooped)

		fileMenu.setStyleSheet("border: 1px solid black;")
		fileMenu.addAction(openFile)
		fileMenu.addAction(saveFile)
		fileMenu.addSeparator()

		self.recentMenu = fileMenu.addMenu('Recent')
		self.rfUpdate()

		fileMenu.addSeparator()
		fileMenu.addAction(showSett)
		fileMenu.addSeparator()
		fileMenu.addAction(exitAction)

		helpMenu = menubar.addMenu('&Help')
		helpMenu.setStyleSheet("border: 1px solid black;")
		helpMenu.addAction(aboutdlg)
		
		self.numCards = QSpinBox()
		numCards_text = QLabel(" OPL : ")
		self.numCards.setRange(1, 100)
		self.numCards.setValue(int(self.progset.value("sound/numCards", 3)))
		self.numCards.valueChanged.connect(self.updateMax4ops)
		
		self.fourOps = QSpinBox()
		fourOps_text = QLabel(" 4op Ch : ")
		self.fourOps.setRange(0, self.numCards.value()*6)
		self.fourOps.setValue(int(self.progset.value("sound/fourOps", self.numCards.value()*6)))
		
		self.twoOps = QSpinBox()
		twoOps_text = QLabel(" 2op Ch : ")
		self.twoOps.setValue((self.numCards.value()*12 - self.fourOps.value()))
		self.twoOps.setRange(self.twoOps.value(), self.twoOps.value())
		
		toolbar = self.addToolBar('Media')
		toolbar.addAction(playFile)
		toolbar.addAction(pausePlayb)
		toolbar.addAction(stopPlay)
		toolbar.setMovable(False)
		toolbar.addSeparator()
		toolbar.addWidget(numCards_text)
		toolbar.addWidget(self.numCards)
		toolbar.addSeparator()
		toolbar.addWidget(fourOps_text)
		toolbar.addWidget(self.fourOps)
		#toolbar.addSeparator()
		#toolbar.addWidget(twoOps_text)
		#toolbar.addWidget(self.twoOps)
		
		self.statusBar()
		
		self.setFixedSize(380, 90)
		self.center()
		self.setWindowTitle('ADLMIDI pyGUI')
		self.show()
		
		if self.debug: barf("MSG", "Loaded Main Window", True, False)
		self.update("ready")

		self.threads = []
		self.addWorker(AdlMidi(1))
		self.addWorker(AdlMidiSave(2))

	def rfUpdate(self):
		self.recentMenu.clear()
		def recentfile(f2l):
			return lambda: self.load2(f2l)
		self.recentFileActs = []
		recentLength = len(self.recentList)
		for i in range(self.MaxRecentFiles):
			try:
				if i >= recentLength: break
				rev = (recentLength-1)-i
				filetoload = self.recentList[rev]
				filename = path.split(filetoload)[1]
				self.fileact = QAction(filename, self.recentMenu)
				self.fileact.triggered.connect(recentfile(filetoload))
				self.recentFileActs.append(self.fileact)
			except Exception: pass
		for i in range(self.MaxRecentFiles):
			try: self.recentMenu.addAction(self.recentFileActs[i])
			except Exception: pass

	def get_bank(self):
		try:
			selection = self.settings_window.combo.currentText()
			selection = str(selection[0])+str(selection[1])
			return int(selection)
		except Exception: return 1
		
	def center(self):
		qr = self.frameGeometry()
		cp = QDesktopWidget().availableGeometry().center()
		qr.moveCenter(cp)
		self.move(qr.topLeft())

	def about(self):
		if self.about_window is None:
			window = QMessageBox(self)
			self.about_window = window
		else: window = self.about_window
		window = self.about_window
		window.setWindowIcon(QIcon(self.abouticon))
		window.setWindowTitle('About ADLMIDI pyGUI')
		
		credits = "<center><b>ADLMIDI pyGUI v%s (%s)</b><br>Developed by Tristy H. \"KittyTristy\"<br>[<a href=\"https://github.com/KittyTristy/ADLMIDI-pyGUI\">Website</a>] [<a href=\"mailto:[email protected]\">Email</a>] <br><br><br>" % (__version__, system())
		title = "<b>ADLMIDI pyGUI</b> is a GUI wrapper<br>written in Python for use with..<br><br><b>ADLMIDI: MIDI Player<br>for Linux and Windows with OPL3 emulation</b><br>"
		cw = "(C) -- <a href=\"http://iki.fi/bisqwit/source/adlmidi.html\">http://iki.fi/bisqwit/source/adlmidi.html</a></center>"
		credits = credits + title + cw
		window.setText(credits)
			
		window.show()
		window.activateWindow()
		window.raise_()
		
	def settings(self):
		if self.settings_window is None:
			window = QDialog(self)
			self.settings_window = window
		else: window = self.settings_window
		window = self.settings_window
		window.setWindowTitle('Settings')
		
		window.notelabel = QLabel("Currently these settings are only guaranteed to work prior to loading the first MIDI!\nYou'll have to restart ADLMIDI pyGui to change them again if they stop working. \n\nSorry! This will be fixed soon!")
		window.notelabel.setWordWrap(True)
		window.notelabel.setStyleSheet("font-size: 8pt; border-style: dotted; border-width: 1px; padding: 12px;")
		window.banklabel = QLabel("<B>Choose Instrument Bank</B>")
		window.space     = QLabel("")
		window.optlabel  = QLabel("<B>Options</B>")
		
		window.combo = QComboBox()
		window.combo.addItems(self.banks)
		#window.combo.setMaximumWidth(350)
		window.combo.setMaxVisibleItems(12)
		window.combo.setStyleSheet("combobox-popup: 0;")
		window.combo.setCurrentIndex(int(self.progset.value("sound/bank", 1)))
		window.combo.currentIndexChanged.connect(self.saveSettings)
		
		window.perc		= QCheckBox("Adlib Percussion Instrument Mode")
		#window.perc.stateChanged.connect(self.checkOpts)
		window.tremamp  = QCheckBox("Tremolo Amplification Mode")
		#window.tremamp.stateChanged.connect(self.checkOpts)
		window.vibamp   = QCheckBox("Vibrato Amplification Mode")
		#window.vibamp.stateChanged.connect(self.checkOpts)
		window.modscale = QCheckBox("Scaling of Modulator Volume")
		#window.modscale.stateChanged.connect(self.checkOpts)
		
		window.okButton = QPushButton('OK')
		window.okButton.clicked.connect(window.hide)
		
		vbox = QVBoxLayout()
		vbox.addWidget(window.space)
		vbox.addWidget(window.banklabel)
		vbox.addWidget(window.combo)
		vbox.addWidget(window.space)
		vbox.addWidget(window.optlabel)
		vbox.addWidget(window.perc)
		vbox.addWidget(window.tremamp)
		vbox.addWidget(window.vibamp)
		vbox.addWidget(window.modscale)
		vbox.addWidget(window.notelabel)
		
		hbox = QHBoxLayout()
		hbox.addStretch(1)
		hbox.addWidget(window.okButton)
		
		vbox.addLayout(hbox)
		window.setLayout(vbox) 
		
		window.setFixedSize(530, 369)
		window.show()
		window.activateWindow()
		window.raise_()
		
	def updateMax4ops(self):
		self.fourOps.setMaximum(self.numCards.value()*6)
		self.fourOps.setValue(self.numCards.value()*6)
		barf("DBG", "Updating Maximum of 4ops Chs to %s" % (self.numCards.value()*6), True, False)
		#self.twoOps.setValue(self.numCards.value()*12 - self.fourOps.value())
		#self.twoOps.setRange(self.twoOps.value(), self.twoOps.value())
		
	def checkOpts(self):
		global arglist
		#barf("ACT", "Checking if Options have changed..", True, False)
		arglist = []
		try:
			if QAbstractButton.isChecked(self.settings_window.perc) and not ('-p' in arglist): arglist.append('-p')
			elif not QAbstractButton.isChecked(self.settings_window.perc) and ('-p' in arglist): arglist.remove('-p')
		except Exception: pass
		try:
			if QAbstractButton.isChecked(self.settings_window.tremamp) and not ('-t' in arglist): arglist.append('-t')
			elif not QAbstractButton.isChecked(self.settings_window.tremamp) and ('-t' in arglist): arglist.remove('-t')
		except Exception: pass
		try:
			if QAbstractButton.isChecked(self.settings_window.vibamp) and not ('-v' in arglist): arglist.append('-v')
			elif not QAbstractButton.isChecked(self.settings_window.vibamp) and ('-v' in arglist): arglist.remove('-v')
		except Exception: pass
		try:
			if QAbstractButton.isChecked(self.settings_window.modscale) and not ('-s' in arglist): arglist.append('-s')
			elif not QAbstractButton.isChecked(self.settings_window.modscale) and ('-s' in arglist): arglist.remove('-s')
		except Exception: pass

		self.sel_bank = self.get_bank()

	def saveSettings(self):
		self.progset.setValue("sound/Autoplay", self.setAutoplay.isChecked())
		self.progset.setValue("sound/Looped", self.setLooped.isChecked())
		self.progset.setValue("sound/numCards", self.numCards.value())
		self.progset.setValue("sound/fourOps", self.fourOps.value())
		try: self.progset.setValue("sound/bank", self.settings_window.combo.currentIndex())
		except Exception: pass
		if len(self.recentList) >= 1: self.progset.setValue("file/recent", self.recentList[-self.MaxRecentFiles:])
		self.progset.setValue("file/MaxRecentFiles", self.MaxRecentFiles)
		#allkeys = self.progset.allKeys()
		#for key in allkeys:
		#	barf('DBG', str(key) + " " + str(self.progset.value(key)))
		
	def closeEvent(self, event):
		self.stop()
		#self.pkill()
		self.saveSettings()
		barf("DBG", "Quitting", True, False)
		
	def quit(self):
		self.stop()
		#self.pkill()
		self.saveSettings()
		barf("DBG", "Quitting", True, False)
		exit(0)

	def pkill(self):
		try: p.kill()
		except Exception: pass
		
	##############################################################
	##### Statusbar Functions ####################################
	##############################################################
	
	def clear(self):
		try: self.statusBar().removeWidget(self.playStatus)
		except Exception: pass
	
	@Slot(str)
	def update(self, status=''):
		self.clear()
		if status == "ready": text = "&nbsp;<B>Ready</b>"
		elif status == "play": text = "&nbsp;<B>Now Playing: </B>" + path.split(f.name)[1]
		elif status == "loop": text = "&nbsp;<B>Looping: </B>" + path.split(f.name)[1]
		elif status == "stop": text = "&nbsp;<B>Stopped: </B>" + path.split(f.name)[1]
		elif status == "pause": text = "&nbsp;<B>Paused: </B>" + path.split(f.name)[1]
		elif status == "loading": text = "&nbsp;<B>Loading.. </B>"
		elif status == "load": text = "&nbsp;<B>Loaded: </B>" + path.split(f.name)[1]
		elif status == "saving": text = "&nbsp;<B>Saving.. </B>"
		elif status == "saved": text = "&nbsp;<B>Saved as: </B>" + "saved/" + path.splitext(path.split(f.name)[1])[0] + ".wav"
		self.playStatus = QLabel(text)
		self.statusBar().addPermanentWidget(self.playStatus, 1)
		
	##############################################################
	####### Sound Functions ######################################
	##############################################################

	def play(self):
		global Paused, arglist
		if f != None and Paused == False:
			Paused = False
			self.stop()
			self.checkOpts()
			if not self.setLooped.isChecked(): arglist.append('-nl')
			arglist.append(str(self.progset.value("sound/bank", 1)))
			arglist.append(str(self.numCards.value()))
			arglist.append(str(self.fourOps.value()))
			for worker in self.threads:
				if worker.id == 1:
					worker.start()
		elif f != None and Paused == True:
			os.kill(p.pid, signal.SIGCONT)
			self.update("play")
			Paused = False

	def pause(self):
		global p, Paused
		if f != None:
			try:
				if Paused == False:
					os.kill(p.pid, signal.SIGSTOP)
					self.update("pause")
					Paused = True
				elif Paused == True:
					os.kill(p.pid, signal.SIGCONT)
					self.update("play")
					Paused = False
			except Exception: pass

	def stop(self):
		global Paused
		if f != None:
			Paused = False 
			self.pkill()
			self.killWorkers()
			self.update("stop")
				
	##############################################################
	##### Load/Save Functions ####################################
	##############################################################

	def load(self):
		global f
		lastdir = str(self.progset.value("file/lastdir", ""))
		fname, _ = QFileDialog.getOpenFileName(None, 'Open File', lastdir, "MIDI Audio File (*.mid *.MID)")
		if fname != "":
			f = file(fname, 'r')
			if not f.name in self.recentList: self.recentList.append(f.name)
			else:
				self.recentList.remove(f.name)
				self.recentList.append(f.name)
			self.progset.setValue("file/lastdir", path.split(f.name)[0])
			self.rfUpdate()
			self.update("load")
			self.pkill()
			if self.debug: barf("SAV", "Loaded %s" % path.split(f.name)[1], True, False)
			if self.setAutoplay.isChecked(): self.play()
			else: self.update("load")

	def load2(self, r_file=None):
		global f
		f = file(r_file, 'r')
		self.recentList.remove(f.name)
		self.recentList.append(f.name)
		self.rfUpdate()
		self.update("load")
		self.pkill()
		if self.debug: barf("SAV", "Loaded %s" % path.split(f.name)[1], True, False)
		if self.setAutoplay.isChecked(): self.play()
		else: self.update("load")
			
	def save(self):
		if f != None:
			self.stop()
			for worker in self.threads:
				if worker.id == 2:
					worker.start()