예제 #1
0
class collectDelegate(QItemDelegate):

    def __init__(self, parent, module):
        self.module = module
        QItemDelegate.__init__(self, parent)

    def createEditor (self, parent, option, index):
        column = index.column()
        row = index.row()
        self.index = index
        content = index.model().data(index, Qt.EditRole)
        if column == 2:
            content = index.model().data(index, Qt.EditRole)
            label = index.model().data(index.model().index(row,1), Qt.EditRole)
            checkrowIndex = index.model().index(row,0)
            checkrowIndex = index.model().data(index.model().index(row,0), Qt.CheckStateRole)
            self.editorQWidget = QComboBox(parent)
            self.editorQWidget.setEditable(True)
            self.editorQWidget.addItems(self.module.fieldMapping.values())
            self.editorQWidget.addItems(['GEOMETRY','ODKUUID'])
            if content in self.module.fieldMapping.values():
                self.editorQWidget.setCurrentIndex(self.editorQWidget.findData(content))
                #self.module.fieldTable.item(row,0).setCheckState(Qt.Checked)
            else:
                #self.editorQWidget.insertItem(0,label)
                self.editorQWidget.insertItem(0,'')
                #self.module.fieldTable.item(row,0).setCheckState(Qt.Unchecked)
                self.editorQWidget.setCurrentIndex(0)
            return self.editorQWidget
        else:
            return None
        return QItemDelegate.createEditor(self, parent, option, index)
예제 #2
0
class AddressColumnConfigurationWidget(columnproviders.AbstractColumnConfigurationWidget, QWidget):
    def __init__(self, parent, hex_widget, column):
        columnproviders.AbstractColumnConfigurationWidget.__init__(self)
        QWidget.__init__(self, parent)
        self.hexWidget = hex_widget
        self.column = column

        self.setLayout(QFormLayout())

        self.cmbBase = QComboBox(self)
        self.cmbBase.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        self.layout().addRow(utils.tr('Base:'), self.cmbBase)
        for base in ((utils.tr('Hex'), 16), (utils.tr('Dec'), 10), (utils.tr('Oct'), 8), (utils.tr('Bin'), 2)):
            self.cmbBase.addItem(base[0], base[1])
        if column is not None:
            self.cmbBase.setCurrentIndex(self.cmbBase.findData(column.formatter.base))

        self.cmbStyle = QComboBox(self)
        self.cmbStyle.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        self.layout().addRow(utils.tr('Style:'), self.cmbStyle)
        for style_data in ((utils.tr('No style'), 'none'), (utils.tr('C'), 'c'), (utils.tr('Assembler'), 'asm')):
            self.cmbStyle.addItem(style_data[0], style_data[1])
        if column is not None:
            self.cmbStyle.setCurrentIndex(self.cmbStyle.findData(column.formatter.styleName))

        self.intBaseAddress = integeredit.IntegerEdit(self)
        self.intBaseAddress.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        self.layout().addRow(utils.tr('Base address:'), self.intBaseAddress)
        self.intBaseAddress.minimum = -10000000000000
        if column is not None:
            self.intBaseAddress.number = column.baseAddress

    @property
    def _formatter(self):
        formatter = formatters.IntegerFormatter()
        formatter.base = self.cmbBase.itemData(self.cmbBase.currentIndex())
        formatter.style = self.cmbStyle.itemData(self.cmbStyle.currentIndex())
        return formatter

    def createColumnModel(self, hex_widget):
        return AddressColumnModel(None, self._formatter, self.intBaseAddress.number)

    def saveToColumn(self, column):
        column.formatter = self._formatter
        column.baseAddress = self.intBaseAddress.number
        column.reset()
    def addAutoFieldToAutoFieldsTable( self, autoField, candidateLayer ):
        """ Add a whole row to the AutoFields table """
        row = self.tblAutoFields.rowCount()
        self.tblAutoFields.insertRow( row )
        layerName = self.ogrLayerName( autoField['layer'] )
        item = QTableWidgetItem( layerName if layerName else autoField['layer'] )
        item.setData( Qt.UserRole, autoField['layer'] )
        item.setData( Qt.ToolTipRole, autoField['layer'] )
        self.tblAutoFields.setItem( row, 0, item )
        item = QTableWidgetItem( autoField['field'] )
        self.tblAutoFields.setItem( row, 1, item )
        item = QTableWidgetItem( autoField['expression'] )
        self.tblAutoFields.setItem( row, 2, item )

        layerCombo = QComboBox()
        layerCombo.addItem( '[Select a layer]', None )
        for layer in self.layers:
           layerCombo.addItem( layer.name(), layer.id() )
        if candidateLayer:
            layerCombo.setCurrentIndex( layerCombo.findData( candidateLayer.id() ) )
        layerCombo.currentIndexChanged.connect( partial( self.layerOrFieldCombosChanged, row ) )
        self.tblAutoFields.setCellWidget( row, 4, layerCombo )

        fieldCombo = QComboBox()
        fieldCombo.addItem( '[Select a field]', None )
        if layerCombo.currentIndex() != 0:
            for field in candidateLayer.fields():
                fieldCombo.addItem( field.name() )
            fieldIndex = fieldCombo.findText( autoField['field'] )
            fieldCombo.setCurrentIndex( fieldIndex if fieldIndex != -1 else 0 )
        fieldCombo.currentIndexChanged.connect( partial( self.layerOrFieldCombosChanged, None ) )
        self.tblAutoFields.setCellWidget( row, 5, fieldCombo )

        label = self.getLabelWithArrow( layerCombo.currentIndex(), fieldCombo.currentIndex(), candidateLayer, autoField['field'] )
        self.tblAutoFields.setCellWidget( row, 3, label )

        self.layerOrFieldCombosChanged( None, None ) # Validate initial load of AutoFields/Layers
예제 #4
0
class collectDelegate(QItemDelegate):
    def __init__(self, parent, module):
        self.module = module
        QItemDelegate.__init__(self, parent)

    def createEditor(self, parent, option, index):
        column = index.column()
        self.index = index
        content = index.model().data(index, Qt.EditRole)
        if column == 2:
            self.content = index.model().data(index, Qt.EditRole)
            self.editorQWidget = QComboBox(parent)
            self.editorQWidget.setEditable(True)
            self.editorQWidget.addItems(self.module.fieldMapping.values())
            if self.content in self.module.fieldMapping.values():
                self.editorQWidget.setCurrentIndex(
                    self.editorQWidget.findData(self.content))
            else:
                self.editorQWidget.insertItem(0, '')
                self.editorQWidget.setCurrentIndex(0)
            return self.editorQWidget
        else:
            return None
            return QItemDelegate.createEditor(self, parent, option, index)
예제 #5
0
class SchemeSelector(QWidget):
    
    currentChanged = pyqtSignal()
    changed = pyqtSignal()
    
    def __init__(self, parent=None):
        super(SchemeSelector, self).__init__(parent)
        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)
        
        self.label = QLabel()
        self.scheme = QComboBox()
        self.menuButton = QPushButton(flat=True)
        menu = QMenu(self.menuButton)
        self.menuButton.setMenu(menu)
        layout.addWidget(self.label)
        layout.addWidget(self.scheme)
        layout.addWidget(self.menuButton)
        layout.addStretch(1)
        # action generator
        def act(slot, icon=None):
            a = QAction(self, triggered=slot)
            self.addAction(a)
            icon and a.setIcon(icons.get(icon))
            return a
        
        # add action
        a = self.addAction_ = act(self.slotAdd, 'list-add')
        menu.addAction(a)
        
        # remove action
        a = self.removeAction = act(self.slotRemove, 'list-remove')
        menu.addAction(a)
        
       
        # rename action
        a = self.renameAction = act(self.slotRename, 'document-edit')
        menu.addAction(a)
        
        menu.addSeparator()
        
        # import action
        a = self.importAction = act(self.slotImport, 'document-open')
        menu.addAction(a)
        
        # export action
        a = self.exportAction = act(self.slotExport, 'document-save-as')
        menu.addAction(a)
        
        
        self.scheme.currentIndexChanged.connect(self.slotSchemeChanged)
        app.translateUI(self)
        
    def translateUI(self):
        self.label.setText(_("Scheme:"))
        self.menuButton.setText(_("&Menu"))
        self.addAction_.setText(_("&Add..."))
        self.removeAction.setText(_("&Remove"))
        self.renameAction.setText(_("Re&name..."))
        self.importAction.setText(_("&Import..."))
        self.exportAction.setText(_("&Export..."))
        
    def slotSchemeChanged(self, index):
        """Called when the Scheme combobox is changed by the user."""
        self.disableDefault(self.scheme.itemData(index) == 'default')
        self.currentChanged.emit()
        self.changed.emit()
    
    def disableDefault(self, val):
        self.removeAction.setDisabled(val)
        self.renameAction.setDisabled(val)
    
    def schemes(self):
        """Returns the list with internal names of currently available schemes."""
        return [self.scheme.itemData(i) for i in range(self.scheme.count())]
        
    def currentScheme(self):
        """Returns the internal name of the currently selected scheme"""
        return self.scheme.itemData(self.scheme.currentIndex())
        
    def insertSchemeItem(self, name, scheme):
        for i in range(1, self.scheme.count()):
            n = self.scheme.itemText(i)
            if n.lower() > name.lower():
                self.scheme.insertItem(i, name, scheme)
                break
        else:
            self.scheme.addItem(name, scheme)
    
    def addScheme(self, name):
        num, key = 1, 'user1'
        while key in self.schemes() or key in self._schemesToRemove:
            num += 1
            key = 'user{0}'.format(num)
        self.insertSchemeItem(name, key)
        self.scheme.setCurrentIndex(self.scheme.findData(key))
        return key
    
    def slotAdd(self):
        name, ok = QInputDialog.getText(self,
            app.caption(_("Add Scheme")),
            _("Please enter a name for the new scheme:"))
        if ok:
            self.addScheme(name)
        
    
    def slotRemove(self):
        index = self.scheme.currentIndex()
        scheme = self.scheme.itemData(index)
        if scheme == 'default':
            return # default can not be removed
        
        self._schemesToRemove.add(scheme)
        self.scheme.removeItem(index)
    
    def slotRename(self):
        index = self.scheme.currentIndex()
        name = self.scheme.itemText(index)
        scheme = self.scheme.itemData(index)
        newName, ok = QInputDialog.getText(self, _("Rename"), _("New name:"), text=name)
        if ok:
            self.scheme.blockSignals(True)
            self.scheme.removeItem(index)
            self.insertSchemeItem(newName, scheme)
            self.scheme.setCurrentIndex(self.scheme.findData(scheme))
            self.scheme.blockSignals(False)
            self.changed.emit()
           
    def slotImport(self):
        filetypes = "{0} (*.xml);;{1} (*)".format(_("XML Files"), _("All Files"))
        caption = app.caption(_("dialog title", "Import color theme"))
        filename = QFileDialog.getOpenFileName(self, caption, os.environ['HOME'], filetypes)
        if filename:
            self.parent().import_(filename)
    
    def slotExport(self):
        name = self.scheme.currentText()
        filetypes = "{0} (*.xml);;{1} (*)".format(_("XML Files"), _("All Files"))
        caption = app.caption(_("dialog title",
            "Export {name}").format(name=name))
        path = os.path.join(os.environ['HOME'], name+'.xml')
        filename = QFileDialog.getSaveFileName(self, caption, path, filetypes)
        if filename:
            if os.path.splitext(filename)[1] != '.xml':
                filename += '.xml'
            self.parent().export(name, filename)
            
    
    def loadSettings(self, currentKey, namesGroup):
        # dont mark schemes for removal anymore
        self._schemesToRemove = set()
        
        s = QSettings()
        cur = s.value(currentKey, "default", type(""))
        
        # load the names for the shortcut schemes
        s.beginGroup(namesGroup)
        self.scheme.clear()
        self.scheme.addItem(_("Default"), "default")
        lst = [(s.value(key, key, type("")), key) for key in s.childKeys()]
        for name, key in sorted(lst, key=lambda f: f[0].lower()):
            self.scheme.addItem(name, key)
        block = self.scheme.blockSignals(True)
        
        # find out index
        index = self.scheme.findData(cur)
        self.disableDefault(cur == 'default')
        self.scheme.setCurrentIndex(index)
        self.scheme.blockSignals(block)
        self.currentChanged.emit()
        
    def saveSettings(self, currentKey, namesGroup, removePrefix=None):
        # first save new scheme names
        s = QSettings()
        s.beginGroup(namesGroup)
        for i in range(self.scheme.count()):
            if self.scheme.itemData(i) != 'default':
                s.setValue(self.scheme.itemData(i), self.scheme.itemText(i))
        
        for scheme in self._schemesToRemove:
            s.remove(scheme)
        s.endGroup()
        if removePrefix:
            for scheme in self._schemesToRemove:
                s.remove("{0}/{1}".format(removePrefix, scheme))
        # then save current
        scheme = self.currentScheme()
        s.setValue(currentKey, scheme)
        # clean up
        self._schemesToRemove = set()
예제 #6
0
파일: analog_in.py 프로젝트: makerpc/brickv
class AnalogIn(PluginBase):
    def __init__(self, *args):
        PluginBase.__init__(self, BrickletAnalogIn, *args)
        
        self.ai = self.device

        self.cbe_voltage = CallbackEmulator(self.ai.get_voltage,
                                            self.cb_voltage,
                                            self.increase_error_count)

        self.voltage_label = VoltageLabel('Voltage: ')
        
        self.current_value = None
        
        plot_list = [['', Qt.red, self.get_current_value]]
        self.plot_widget = PlotWidget('Voltage [mV]', plot_list)

        layout_h2 = QHBoxLayout()
        layout_h2.addStretch()
        layout_h2.addWidget(self.voltage_label)
        layout_h2.addStretch()

        layout = QVBoxLayout(self)
        layout.addLayout(layout_h2)
        layout.addWidget(self.plot_widget)

        if self.firmware_version >= (2, 0, 1):
            self.combo_range = QComboBox()
            self.combo_range.addItem('Automatic', BrickletAnalogIn.RANGE_AUTOMATIC)
            if self.firmware_version >= (2, 0, 3):
                self.combo_range.addItem('0V - 3.30V', BrickletAnalogIn.RANGE_UP_TO_3V)
            self.combo_range.addItem('0V - 6.05V', BrickletAnalogIn.RANGE_UP_TO_6V)
            self.combo_range.addItem('0V - 10.32V', BrickletAnalogIn.RANGE_UP_TO_10V)
            self.combo_range.addItem('0V - 36.30V', BrickletAnalogIn.RANGE_UP_TO_36V)
            self.combo_range.addItem('0V - 45.00V', BrickletAnalogIn.RANGE_UP_TO_45V)
            self.combo_range.currentIndexChanged.connect(self.range_changed)

            layout_h1 = QHBoxLayout()
            layout_h1.addStretch()
            layout_h1.addWidget(QLabel('Range:'))
            layout_h1.addWidget(self.combo_range)

            if self.firmware_version >= (2, 0, 3):
                self.spin_average = QSpinBox()
                self.spin_average.setMinimum(0)
                self.spin_average.setMaximum(255)
                self.spin_average.setSingleStep(1)
                self.spin_average.setValue(50)
                self.spin_average.editingFinished.connect(self.spin_average_finished)

                layout_h1.addStretch()
                layout_h1.addWidget(QLabel('Average Length:'))
                layout_h1.addWidget(self.spin_average)

            layout_h1.addStretch()
            layout.addLayout(layout_h1)

    def get_range_async(self, range_):
        self.combo_range.setCurrentIndex(self.combo_range.findData(range_))

    def get_averaging_async(self, average):
        self.spin_average.setValue(average)

    def start(self):
        if self.firmware_version >= (2, 0, 1):
            async_call(self.ai.get_range, None, self.get_range_async, self.increase_error_count)
        if self.firmware_version >= (2, 0, 3):
            async_call(self.ai.get_averaging, None, self.get_averaging_async, self.increase_error_count)
        async_call(self.ai.get_voltage, None, self.cb_voltage, self.increase_error_count)
        self.cbe_voltage.set_period(100)
        
        self.plot_widget.stop = False
        
    def stop(self):
        self.cbe_voltage.set_period(0)
        
        self.plot_widget.stop = True

    def destroy(self):
        pass

    def get_url_part(self):
        return 'analog_in'

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickletAnalogIn.DEVICE_IDENTIFIER

    def get_current_value(self):
        return self.current_value

    def cb_voltage(self, voltage):
        self.current_value = voltage
        self.voltage_label.setText(str(voltage/1000.0))

    def range_changed(self, index):
        if index >= 0 and self.firmware_version >= (2, 0, 1):
            range_ = self.combo_range.itemData(index)
            async_call(self.ai.set_range, range_, None, self.increase_error_count)

    def spin_average_finished(self):
        self.ai.set_averaging(self.spin_average.value())
예제 #7
0
class TimesDialog(QDialog):
    def __init__(self, parent, params):

        QDialog.__init__(self, parent)

        self.parent = parent
        self.params = params

        self.setMinimumWidth(min_width)

        # Build dialog
        self.setWindowTitle('Options - Times')  # TODO: softcode
        self.setWindowModality(QtCore.Qt.ApplicationModal)

        self.fra_form = QFrame(self)
        fra_form_lay = QFormLayout(self.fra_form)
        fra_form_lay.setContentsMargins(10, 10, 10, 10)

        self.lbl_units = QLabel('Units:')  # TODO: softocode
        self.cbo_units = QComboBox()
        fra_form_lay.addRow(self.lbl_units, self.cbo_units)

        self.lbl_duration = QLabel('Duration:')  # TODO: softocode
        self.txt_duration = QLineEdit()
        fra_form_lay.addRow(self.lbl_duration, self.txt_duration)

        self.lbl_hydraulic_timestep = QLabel(
            'Hydraulic timestep:')  # TODO: softocode
        self.txt_hydraulic_timestep = QLineEdit()
        fra_form_lay.addRow(self.lbl_hydraulic_timestep,
                            self.txt_hydraulic_timestep)

        self.lbl_quality_timestep = QLabel(
            'Quality timestep:')  # TODO: softocode
        self.txt_quality_timestep = QLineEdit()
        fra_form_lay.addRow(self.lbl_quality_timestep,
                            self.txt_quality_timestep)

        self.lbl_rule_timestep = QLabel('Rule timestep:')  # TODO: softocode
        self.txt_rule_timestep = QLineEdit()
        fra_form_lay.addRow(self.lbl_rule_timestep, self.txt_rule_timestep)

        self.lbl_pattern_timestep = QLabel(
            'Pattern timestep:')  # TODO: softocode
        self.txt_pattern_timestep = QLineEdit()
        fra_form_lay.addRow(self.lbl_pattern_timestep,
                            self.txt_pattern_timestep)

        self.lbl_pattern_start = QLabel('Pattern start:')  # TODO: softocode
        self.txt_pattern_start = QLineEdit()
        fra_form_lay.addRow(self.lbl_pattern_start, self.txt_pattern_start)

        self.lbl_report_timestep = QLabel(
            'Report timestep:')  # TODO: softocode
        self.txt_report_timestep = QLineEdit()
        fra_form_lay.addRow(self.lbl_report_timestep, self.txt_report_timestep)

        self.lbl_report_start = QLabel('Report start:')  # TODO: softocode
        self.txt_report_start = QLineEdit()
        fra_form_lay.addRow(self.lbl_report_start, self.txt_report_start)

        self.lbl_clock_time_start = QLabel(
            'Clock start time:')  # TODO: softocode
        self.txt_clock_time_start = QLineEdit()
        fra_form_lay.addRow(self.lbl_clock_time_start,
                            self.txt_clock_time_start)

        self.lbl_statistic = QLabel('Statistic:')  # TODO: softocode
        self.cbo_statistic = QComboBox()
        fra_form_lay.addRow(self.lbl_statistic, self.cbo_statistic)

        # Buttons
        self.fra_buttons = QFrame(self)
        fra_buttons_lay = QHBoxLayout(self.fra_buttons)
        self.btn_Ok = QPushButton('OK')
        self.btn_Cancel = QPushButton('Cancel')
        fra_buttons_lay.addWidget(self.btn_Ok)
        fra_buttons_lay.addWidget(self.btn_Cancel)

        # Add to main
        fra_main_lay = QVBoxLayout(self)
        fra_main_lay.setContentsMargins(0, 0, 0, 0)
        fra_main_lay.addWidget(self.fra_form)
        fra_main_lay.addWidget(self.fra_buttons)

        self.setup()

    def setup(self):

        for key, text in self.params.times.unit_text.iteritems():
            self.cbo_units.addItem(text, key)

        # Buttons
        self.btn_Cancel.clicked.connect(self.btn_cancel_clicked)
        self.btn_Ok.clicked.connect(self.btn_ok_clicked)

        # Validators
        self.txt_duration.setValidator(RegExValidators.get_pos_int())

        self.txt_duration.setInputMask('0009:99')
        self.txt_duration.setValidator(RegExValidators.get_time_hs_mm())

        self.txt_hydraulic_timestep.setInputMask('009:99')
        self.txt_hydraulic_timestep.setValidator(
            RegExValidators.get_time_hs_mm())

        self.txt_quality_timestep.setInputMask('009:99')
        self.txt_quality_timestep.setValidator(
            RegExValidators.get_time_hs_mm())

        self.txt_rule_timestep.setInputMask('009:99')
        self.txt_rule_timestep.setValidator(RegExValidators.get_time_hs_mm())

        self.txt_pattern_timestep.setInputMask('009:99')
        self.txt_pattern_timestep.setValidator(
            RegExValidators.get_time_hs_mm())

        self.txt_pattern_start.setInputMask('09:99')
        self.txt_pattern_start.setValidator(RegExValidators.get_time_hh_mm())

        self.txt_report_timestep.setInputMask('009:99')
        self.txt_report_timestep.setValidator(RegExValidators.get_time_hs_mm())

        self.txt_report_start.setInputMask('09:99')
        self.txt_report_start.setValidator(RegExValidators.get_time_hh_mm())

        self.txt_clock_time_start.setInputMask('09:99')
        self.txt_clock_time_start.setValidator(
            RegExValidators.get_time_hh_mm())

        for key, text in self.params.times.stats_text.iteritems():
            self.cbo_statistic.addItem(text, key)

    def show(self):
        super(TimesDialog, self).show()

        self.cbo_units.setCurrentIndex(
            self.cbo_units.findData(self.params.times.units))
        self.txt_duration.setText(self.params.times.duration.get_as_text(4))
        self.txt_hydraulic_timestep.setText(
            self.params.times.hydraulic_timestep.get_as_text(3))
        self.txt_quality_timestep.setText(
            self.params.times.quality_timestep.get_as_text(3))
        self.txt_rule_timestep.setText(
            self.params.times.rule_timestep.get_as_text(3))
        self.txt_pattern_timestep.setText(
            self.params.times.pattern_timestep.get_as_text(3))
        self.txt_pattern_start.setText(
            self.params.times.pattern_start.get_as_text())
        self.txt_report_timestep.setText(
            self.params.times.report_timestep.get_as_text(3))
        self.txt_report_start.setText(
            self.params.times.report_start.get_as_text())
        self.txt_clock_time_start.setText(
            self.params.times.clocktime_start.get_as_text())
        self.cbo_statistic.setCurrentIndex(
            self.cbo_statistic.findData(self.params.times.statistic))

    def btn_cancel_clicked(self):
        self.setVisible(False)

    def btn_ok_clicked(self):

        # Update parameters and options
        self.params.times.units = self.cbo_units.itemData(
            self.cbo_units.currentIndex())
        self.params.times.duration = Hour.from_string(self.txt_duration.text())
        self.params.times.hydraulic_timestep = Hour.from_string(
            self.txt_hydraulic_timestep.text())
        self.params.times.quality_timestep = Hour.from_string(
            self.txt_quality_timestep.text())
        self.params.times.rule_timestep = Hour.from_string(
            self.txt_rule_timestep.text())
        self.params.times.pattern_timestep = Hour.from_string(
            self.txt_pattern_timestep.text())
        self.params.times.pattern_start = Hour.from_string(
            self.txt_pattern_start.text())
        self.params.times.report_timestep = Hour.from_string(
            self.txt_report_timestep.text())
        self.params.times.report_start = Hour.from_string(
            self.txt_report_start.text())
        self.params.times.clocktime_start = Hour.from_string(
            self.txt_clock_time_start.text())
        self.params.times.statistic = self.cbo_statistic.currentIndex()

        self.setVisible(False)
예제 #8
0
class HydraulicsDialog(QDialog):
    def __init__(self, parent, params, new_proj=False):
        QDialog.__init__(self, parent)

        self.parent = parent
        self.params = params
        self.new_proj = new_proj

        self.setMinimumWidth(min_width)
        # self.setMinimumHeight(min_height)

        # Build dialog
        self.setWindowTitle('Options - Hydraulics')  # TODO: softcode
        self.setWindowModality(QtCore.Qt.ApplicationModal)

        self.fra_form = QFrame(self)
        fra_form_lay = QFormLayout(self.fra_form)
        fra_form_lay.setContentsMargins(10, 10, 10, 10)

        self.lbl_units = QLabel('Units system:')  # TODO: softocode
        self.cbo_units = QComboBox()
        fra_form_lay.addRow(self.lbl_units, self.cbo_units)

        self.lbl_flow_units = QLabel('Flow units:')  # TODO: softocode
        self.cbo_flow_units = QComboBox()
        fra_form_lay.addRow(self.lbl_flow_units, self.cbo_flow_units)

        self.lbl_headloss = QLabel('Head loss:')  # TODO: softocode
        self.cbo_headloss = QComboBox()
        fra_form_lay.addRow(self.lbl_headloss, self.cbo_headloss)

        self.chk_hydraulics = QCheckBox('Hydraulics:')  # TODO: softcode
        self.cbo_hydraulics = QComboBox()
        fra_form_lay.addRow(self.chk_hydraulics, self.cbo_hydraulics)

        self.txt_hydraulics_file = QLineEdit()
        fra_form_lay.addRow(None, self.txt_hydraulics_file)

        self.btn_hydraulics_file = QPushButton('File...')  # TODO: softcode
        fra_form_lay.addRow(None, self.btn_hydraulics_file)

        self.lbl_viscosity = QLabel('Viscosity:')  # TODO: softocode
        self.txt_viscosity = QLineEdit()
        fra_form_lay.addRow(self.lbl_viscosity, self.txt_viscosity)

        self.lbl_diffusivity = QLabel('Diffusivity:')  # TODO: softocode
        self.txt_diffusivity = QLineEdit()
        fra_form_lay.addRow(self.lbl_diffusivity, self.txt_diffusivity)

        self.lbl_spec_gravity = QLabel('Specific gravity:')  # TODO: softocode
        self.txt_spec_gravity = QLineEdit()
        fra_form_lay.addRow(self.lbl_spec_gravity, self.txt_spec_gravity)

        self.lbl_max_trials = QLabel('Max trials:')  # TODO: softocode
        self.txt_max_trials = QLineEdit()
        fra_form_lay.addRow(self.lbl_max_trials, self.txt_max_trials)

        self.lbl_accuracy = QLabel('Accuracy:')  # TODO: softocode
        self.txt_accuracy = QLineEdit()
        fra_form_lay.addRow(self.lbl_accuracy, self.txt_accuracy)

        self.lbl_unbalanced = QLabel('Unbalanced:')  # TODO: softcode
        self.fra_unbalanced = QFrame(self)
        fra_unbalanced_lay = QHBoxLayout(self.fra_unbalanced)
        fra_unbalanced_lay.setContentsMargins(0, 0, 0, 0)
        self.cbo_unbalanced = QComboBox()
        self.txt_unbalanced = QLineEdit()
        fra_unbalanced_lay.addWidget(self.cbo_unbalanced)
        fra_unbalanced_lay.addWidget(self.txt_unbalanced)
        fra_form_lay.addRow(self.lbl_unbalanced, self.fra_unbalanced)

        self.lbl_pattern = QLabel('Pattern:')  # TODO: softocode
        self.cbo_pattern = QComboBox()
        fra_form_lay.addRow(self.lbl_pattern, self.cbo_pattern)

        self.lbl_demand_mult = QLabel('Demand multiplier:')  # TODO: softocode
        self.txt_demand_mult = QLineEdit()
        fra_form_lay.addRow(self.lbl_demand_mult, self.txt_demand_mult)

        self.lbl_emitter_exp = QLabel('Emitter exponent:')  # TODO: softocode
        self.txt_emitter_exp = QLineEdit()
        fra_form_lay.addRow(self.lbl_emitter_exp, self.txt_emitter_exp)

        self.lbl_tolerance = QLabel('Tolerance:')  # TODO: softocode
        self.txt_tolerance = QLineEdit()
        fra_form_lay.addRow(self.lbl_tolerance, self.txt_tolerance)

        # Buttons
        self.fra_buttons = QFrame(self)
        fra_buttons_lay = QHBoxLayout(self.fra_buttons)
        self.btn_Cancel = QPushButton('Cancel')
        self.btn_Ok = QPushButton('OK')
        fra_buttons_lay.addWidget(self.btn_Ok)
        fra_buttons_lay.addWidget(self.btn_Cancel)

        # Add to main
        fra_main_lay = QVBoxLayout(self)
        fra_main_lay.setContentsMargins(0, 0, 0, 0)
        fra_main_lay.addWidget(self.fra_form)
        fra_main_lay.addWidget(self.fra_buttons)

        self.setup()

    def setup(self):

        # Fill units system combo box
        for unit in self.params.options.units_sys:
            self.cbo_units.addItem(self.params.options.units_sys_text[unit],
                                   unit)

        # Fill flow units combo box
        for fu in Options.units_flow[self.params.options.units]:
            self.cbo_flow_units.addItem(Options.units_flow_text[fu], fu)

        self.cbo_units.activated.connect(self.cbo_units_activated)
        # self.cbo_flow_units.activated.connect(self.cbo_flow_units_activated)

        for key, value in self.params.options.headlosses_text.iteritems():
            self.cbo_headloss.addItem(value, key)

        self.cbo_headloss.activated.connect(self.cbo_headloss_activated)

        self.chk_hydraulics.stateChanged.connect(self.chk_hydraulics_changed)
        self.btn_hydraulics_file.clicked.connect(self.btn_hydraulics_clicked)
        self.cbo_hydraulics.addItem(
            self.params.options.hydraulics.action_names[
                self.params.options.hydraulics.action_use],
            self.params.options.hydraulics.action_use)
        self.cbo_hydraulics.addItem(
            self.params.options.hydraulics.action_names[
                self.params.options.hydraulics.action_save],
            self.params.options.hydraulics.action_save)
        self.txt_hydraulics_file.setReadOnly(True)

        # - Unbalanced
        for id, text in self.params.options.unbalanced.unb_text.iteritems():
            self.cbo_unbalanced.addItem(text, id)

        self.cbo_unbalanced.activated.connect(self.cbo_unbalanced_changed)
        self.txt_unbalanced.setValidator(RegExValidators.get_pos_int_no_zero())
        self.txt_unbalanced.setText('1')

        # - Pattern
        self.cbo_pattern.addItem('None (=1.0)', None)
        for pattern_id, pattern in self.params.patterns.iteritems():
            self.cbo_pattern.addItem(pattern_id, pattern)

        # Buttons
        self.btn_Cancel.clicked.connect(self.btn_cancel_clicked)
        self.btn_Ok.clicked.connect(self.btn_ok_clicked)

        # Validators
        self.txt_viscosity.setValidator(RegExValidators.get_pos_decimals())
        self.txt_diffusivity.setValidator(RegExValidators.get_pos_decimals())
        self.txt_spec_gravity.setValidator(RegExValidators.get_pos_decimals())
        self.txt_max_trials.setValidator(RegExValidators.get_pos_int_no_zero())
        self.txt_accuracy.setValidator(RegExValidators.get_pos_decimals())
        self.txt_demand_mult.setValidator(RegExValidators.get_pos_decimals())
        self.txt_emitter_exp.setValidator(RegExValidators.get_pos_decimals())
        self.txt_tolerance.setValidator(RegExValidators.get_pos_decimals())

    def show(self):
        super(HydraulicsDialog, self).show()

        self.cbo_units.setCurrentIndex(
            self.cbo_units.findData(self.params.options.units))
        self.cbo_flow_units.setCurrentIndex(
            self.cbo_flow_units.findData(self.params.options.flow_units))
        self.cbo_headloss.setCurrentIndex(
            self.cbo_headloss.findData(self.params.options.headloss))

        self.chk_hydraulics.setChecked(
            self.params.options.hydraulics.use_hydraulics)
        self.btn_hydraulics_file.setEnabled(self.chk_hydraulics.isChecked())
        self.cbo_hydraulics.setEnabled(self.chk_hydraulics.isChecked())
        self.txt_hydraulics_file.setEnabled(self.chk_hydraulics.isChecked())

        if self.params.options.hydraulics.action is not None:
            self.cbo_hydraulics.setCurrentIndex(
                self.cbo_hydraulics.findData(
                    self.params.options.hydraulics.action))
        if self.params.options.hydraulics.file is not None:
            self.txt_hydraulics_file.setText(
                self.params.options.hydraulics.file)

        self.txt_viscosity.setText(str(self.params.options.viscosity))
        self.txt_diffusivity.setText(str(self.params.options.diffusivity))
        self.txt_spec_gravity.setText(str(self.params.options.spec_gravity))
        self.txt_max_trials.setText(str(self.params.options.trials))
        self.txt_accuracy.setText(str(self.params.options.accuracy))

        self.cbo_unbalanced.setCurrentIndex(
            self.cbo_unbalanced.findData(
                self.params.options.unbalanced.unbalanced))
        self.txt_unbalanced.setEnabled(self.cbo_unbalanced.currentIndex() != 0)
        self.txt_unbalanced.setText(str(self.params.options.unbalanced.trials))

        # Patterns
        if self.params.options.pattern is not None:
            if self.params.options.pattern is None:
                self.cbo_pattern.setCurrentIndex(0)
            else:
                for i in range(self.cbo_pattern.count()):
                    if self.params.options.pattern.id == self.cbo_pattern.itemText(
                            i):
                        self.cbo_pattern.setCurrentIndex(i)
                        break

        self.txt_demand_mult.setText(str(self.params.options.demand_mult))
        self.txt_emitter_exp.setText(str(self.params.options.emitter_exp))
        self.txt_tolerance.setText(str(self.params.options.tolerance))

    def cbo_units_activated(self):

        self.params.options.units = self.cbo_units.itemData(
            self.cbo_units.currentIndex())

        # Parameters combo box
        self.cbo_flow_units.clear()
        for fu in Options.units_flow[self.params.options.units]:
            self.cbo_flow_units.addItem(Options.units_flow_text[fu], fu)

    def cbo_headloss_activated(self):

        # Warning
        if not self.new_proj:
            QMessageBox.warning(
                self, Parameters.plug_in_name,
                u'Head loss units changed: the head loss values already present might need to be reviewed.',
                QMessageBox.Ok)

    def chk_hydraulics_changed(self):

        self.btn_hydraulics_file.setEnabled(self.chk_hydraulics.isChecked())
        self.cbo_hydraulics.setEnabled(self.chk_hydraulics.isChecked())
        self.txt_hydraulics_file.setEnabled(self.chk_hydraulics.isChecked())

    def btn_hydraulics_clicked(self):
        file_dialog = QFileDialog(self, 'Select hydraulics file')
        file_dialog.setLabelText(QFileDialog.Accept, 'Select')
        file_dialog.setLabelText(QFileDialog.Reject, 'Cancel')
        file_dialog.setFileMode(QFileDialog.AnyFile)

        file_dialog.exec_()

        hydraulics_file_path = file_dialog.selectedFiles()

        if not hydraulics_file_path or hydraulics_file_path[
                0] is None or hydraulics_file_path[0] == '':
            return

        self.txt_hydraulics_file.setText(hydraulics_file_path[0])

    def cbo_unbalanced_changed(self):
        self.txt_unbalanced.setEnabled(
            self.cbo_unbalanced.itemData(self.cbo_unbalanced.currentIndex()) ==
            self.params.options.unbalanced.unb_continue)

    def btn_cancel_clicked(self):
        self.setVisible(False)

    def btn_ok_clicked(self):

        if not self.check_params():
            return

        # Update parameters and options
        self.params.options.units = self.cbo_units.itemData(
            self.cbo_units.currentIndex())
        self.params.options.flow_units = self.cbo_flow_units.itemData(
            self.cbo_flow_units.currentIndex())
        self.params.options.headloss = self.cbo_headloss.itemData(
            self.cbo_headloss.currentIndex())
        self.params.options.hydraulics.use_hydraulics = self.chk_hydraulics.isChecked(
        )

        if self.params.options.hydraulics.action is not None:
            self.params.options.hydraulics.action = self.cbo_hydraulics.itemData(
                self.cbo_hydraulics.currentIndex())
            self.params.options.hydraulics.file = self.txt_hydraulics_file.text(
            )

        self.params.options.viscosity = float(self.txt_viscosity.text())
        self.params.options.diffusivity = float(self.txt_diffusivity.text())
        self.params.options.spec_gravity = float(self.txt_spec_gravity.text())
        self.params.options.trials = float(self.txt_max_trials.text())
        self.params.options.accuracy = float(self.txt_accuracy.text())

        self.params.options.unbalanced.unbalanced = self.cbo_unbalanced.itemData(
            self.cbo_unbalanced.currentIndex())
        self.params.options.unbalanced.trials = int(self.txt_unbalanced.text())

        self.params.options.pattern = self.cbo_pattern.itemData(
            self.cbo_pattern.currentIndex())
        self.params.options.demand_mult = float(self.txt_demand_mult.text())
        self.params.options.emitter_exp = float(self.txt_emitter_exp.text())
        self.params.options.tolerance = float(self.txt_tolerance.text())

        # Junctions
        self.parent.lbl_junction_demand.setText(
            pre_l('Demand', Options.units_flow[self.params.options.units]
                  [0]))  # TODO: softcode
        self.parent.lbl_junction_deltaz.setText(
            pre_l('Delta Z', Options.units_deltaz[
                self.params.options.units]))  # TODO: softcode

        # Reservoirs
        self.parent.lbl_reservoir_deltaz.setText(
            pre_l('Delta Z', Options.units_deltaz[
                self.params.options.units]))  # TODO: softcode
        self.parent.lbl_reservoir_pressure_head.setText(
            pre_l('Pressure head', Options.units_deltaz[
                self.params.options.units]))  # TODO: softcode

        # Tanks
        self.parent.lbl_tank_deltaz.setText(
            pre_l('Delta Z', Options.units_deltaz[
                self.params.options.units]))  # TODO: softcode
        self.parent.lbl_tank_level_init.setText(
            pre_l('Level init.', Options.units_deltaz[
                self.params.options.units]))  # TODO: softcode
        self.parent.lbl_tank_level_min.setText(
            pre_l('Level min', Options.units_deltaz[
                self.params.options.units]))  # TODO: softcode
        self.parent.lbl_tank_level_max.setText(
            pre_l('Level max', Options.units_deltaz[
                self.params.options.units]))  # TODO: softcode
        self.parent.lbl_tank_diameter.setText(
            pre_l('Diameter', Options.units_diameter_tanks[
                self.params.options.units]))  # TODO: softcode
        self.parent.lbl_tank_vol_min.setText(
            pre_l('Volume min', Options.units_volume[
                self.params.options.units]))  # TODO: softcode

        # Pipes
        self.parent.lbl_pipe_demand.setText(
            pre_l('Demand', Options.units_flow[self.params.options.units]
                  [0]))  # TODO: softcode
        self.parent.lbl_pipe_diameter.setText(
            pre_l('Diameter', Options.units_diameter_pipes[
                self.params.options.units]))  # TODO: softcode
        self.parent.lbl_pipe_roughness_val.setText(
            pre_l(
                'Value', Options.units_roughness[self.params.options.units][
                    self.params.options.headloss]))  # TODO: softcode

        self.params.options.headloss_units = self.cbo_headloss.itemData(
            self.cbo_headloss.currentIndex())

        self.parent.update_roughness_params(
            self.parent.cbo_pipe_roughness.itemData(
                self.parent.cbo_pipe_roughness.currentIndex())[
                    self.params.options.headloss])

        # self.parent.lbl_pipe_roughness.setText(
        #     pre_l(
        #         'Roughness',
        #         self.params.options.units_roughness[self.params.options.units][self.params.options.headloss_units]))

        # Pumps
        self.parent.lbl_pump_head.setText(
            pre_l('Head',
                  self.params.options.units_deltaz[self.params.options.units]))
        self.parent.lbl_pump_power.setText(
            pre_l('Power',
                  self.params.options.units_power[self.params.options.units]))

        # Valves
        valve_type = self.parent.cbo_valve_type.itemData(
            self.parent.cbo_valve_type.currentIndex())

        # Pressure valves
        if valve_type == Valve.type_psv or valve_type == Valve.type_prv or valve_type == Valve.type_pbv:
            self.parent.lbl_valve_setting.setText(
                pre_l(
                    'Pressure', self.params.options.units_pressure[
                        self.params.options.units]))
        # FCV valve: Flow
        if valve_type == Valve.type_fcv:
            self.parent.lbl_valve_setting.setText(
                pre_l('Flow', self.params.options.flow_units))
        # Throttle control valve
        elif valve_type == Valve.type_tcv:
            self.parent.lbl_valve_setting.setText(pre_l('Loss coeff.', '-'))
        # self.parent.lbl_valve_diameter.setText(pre_l('Pressure', self.params.options.units_diameter_pipes[self.params.options.units]))

        # Flow units
        units = self.cbo_flow_units.itemData(
            self.cbo_flow_units.currentIndex())
        self.parent.lbl_junction_demand.setText(pre_l('Demand',
                                                      units))  # TODO: softcode
        self.parent.lbl_pipe_demand.setText(pre_l('Demand',
                                                  units))  # TODO: softcode

        self.setVisible(False)

    def check_params(self):

        if self.chk_hydraulics.isChecked():
            if not os.path.isfile(self.txt_hydraulics_file.text()):
                QMessageBox.warning(
                    self, Parameters.plug_in_name,
                    u'Hydraulics option slected, but no valid file specified.',
                    QMessageBox.Ok)
                return False

        return True
예제 #9
0
class SchemeSelector(QWidget):

    currentChanged = pyqtSignal()
    changed = pyqtSignal()

    def __init__(self, parent=None):
        super(SchemeSelector, self).__init__(parent)
        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)

        self.label = QLabel()
        self.scheme = QComboBox()
        self.menuButton = QPushButton(flat=True)
        menu = QMenu(self.menuButton)
        self.menuButton.setMenu(menu)
        layout.addWidget(self.label)
        layout.addWidget(self.scheme)
        layout.addWidget(self.menuButton)
        layout.addStretch(1)

        # action generator
        def act(slot, icon=None):
            a = QAction(self, triggered=slot)
            self.addAction(a)
            icon and a.setIcon(icons.get(icon))
            return a

        # add action
        a = self.addAction_ = act(self.slotAdd, 'list-add')
        menu.addAction(a)

        # remove action
        a = self.removeAction = act(self.slotRemove, 'list-remove')
        menu.addAction(a)

        # rename action
        a = self.renameAction = act(self.slotRename, 'document-edit')
        menu.addAction(a)

        menu.addSeparator()

        # import action
        a = self.importAction = act(self.slotImport, 'document-open')
        menu.addAction(a)

        # export action
        a = self.exportAction = act(self.slotExport, 'document-save-as')
        menu.addAction(a)

        self.scheme.currentIndexChanged.connect(self.slotSchemeChanged)
        app.translateUI(self)

    def translateUI(self):
        self.label.setText(_("Scheme:"))
        self.menuButton.setText(_("&Menu"))
        self.addAction_.setText(_("&Add..."))
        self.removeAction.setText(_("&Remove"))
        self.renameAction.setText(_("Re&name..."))
        self.importAction.setText(_("&Import..."))
        self.exportAction.setText(_("&Export..."))

    def slotSchemeChanged(self, index):
        """Called when the Scheme combobox is changed by the user."""
        self.disableDefault(self.scheme.itemData(index) == 'default')
        self.currentChanged.emit()
        self.changed.emit()

    def disableDefault(self, val):
        self.removeAction.setDisabled(val)
        self.renameAction.setDisabled(val)

    def schemes(self):
        """Returns the list with internal names of currently available schemes."""
        return [self.scheme.itemData(i) for i in range(self.scheme.count())]

    def currentScheme(self):
        """Returns the internal name of the currently selected scheme"""
        return self.scheme.itemData(self.scheme.currentIndex())

    def insertSchemeItem(self, name, scheme):
        for i in range(1, self.scheme.count()):
            n = self.scheme.itemText(i)
            if n.lower() > name.lower():
                self.scheme.insertItem(i, name, scheme)
                break
        else:
            self.scheme.addItem(name, scheme)

    def addScheme(self, name):
        num, key = 1, 'user1'
        while key in self.schemes() or key in self._schemesToRemove:
            num += 1
            key = 'user{0}'.format(num)
        self.insertSchemeItem(name, key)
        self.scheme.setCurrentIndex(self.scheme.findData(key))
        return key

    def slotAdd(self):
        name, ok = QInputDialog.getText(
            self, app.caption(_("Add Scheme")),
            _("Please enter a name for the new scheme:"))
        if ok:
            self.addScheme(name)

    def slotRemove(self):
        index = self.scheme.currentIndex()
        scheme = self.scheme.itemData(index)
        if scheme == 'default':
            return  # default can not be removed

        self._schemesToRemove.add(scheme)
        self.scheme.removeItem(index)

    def slotRename(self):
        index = self.scheme.currentIndex()
        name = self.scheme.itemText(index)
        scheme = self.scheme.itemData(index)
        newName, ok = QInputDialog.getText(self,
                                           _("Rename"),
                                           _("New name:"),
                                           text=name)
        if ok:
            self.scheme.blockSignals(True)
            self.scheme.removeItem(index)
            self.insertSchemeItem(newName, scheme)
            self.scheme.setCurrentIndex(self.scheme.findData(scheme))
            self.scheme.blockSignals(False)
            self.changed.emit()

    def slotImport(self):
        filetypes = "{0} (*.xml);;{1} (*)".format(_("XML Files"),
                                                  _("All Files"))
        caption = app.caption(_("dialog title", "Import color theme"))
        filename = QFileDialog.getOpenFileName(self, caption, QDir.homePath(),
                                               filetypes)
        if filename:
            self.parent().import_(filename)

    def slotExport(self):
        name = self.scheme.currentText()
        filetypes = "{0} (*.xml);;{1} (*)".format(_("XML Files"),
                                                  _("All Files"))
        caption = app.caption(
            _("dialog title", "Export {name}").format(name=name))
        path = os.path.join(QDir.homePath(), name + '.xml')
        filename = QFileDialog.getSaveFileName(self, caption, path, filetypes)
        if filename:
            if os.path.splitext(filename)[1] != '.xml':
                filename += '.xml'
            self.parent().export(name, filename)

    def loadSettings(self, currentKey, namesGroup):
        # don't mark schemes for removal anymore
        self._schemesToRemove = set()

        s = QSettings()
        cur = s.value(currentKey, "default", type(""))

        # load the names for the shortcut schemes
        s.beginGroup(namesGroup)
        block = self.scheme.blockSignals(True)
        self.scheme.clear()
        self.scheme.addItem(_("Default"), "default")
        lst = [(s.value(key, key, type("")), key) for key in s.childKeys()]
        for name, key in sorted(lst, key=lambda f: f[0].lower()):
            self.scheme.addItem(name, key)

        # find out index
        index = self.scheme.findData(cur)
        self.disableDefault(cur == 'default')
        self.scheme.setCurrentIndex(index)
        self.scheme.blockSignals(block)
        self.currentChanged.emit()

    def saveSettings(self, currentKey, namesGroup, removePrefix=None):
        # first save new scheme names
        s = QSettings()
        s.beginGroup(namesGroup)
        for i in range(self.scheme.count()):
            if self.scheme.itemData(i) != 'default':
                s.setValue(self.scheme.itemData(i), self.scheme.itemText(i))

        for scheme in self._schemesToRemove:
            s.remove(scheme)
        s.endGroup()
        if removePrefix:
            for scheme in self._schemesToRemove:
                s.remove("{0}/{1}".format(removePrefix, scheme))
        # then save current
        scheme = self.currentScheme()
        s.setValue(currentKey, scheme)
        # clean up
        self._schemesToRemove = set()
예제 #10
0
class UVLightV2(COMCUPluginBase):
    def __init__(self, *args):
        COMCUPluginBase.__init__(self, BrickletUVLightV2, *args)

        self.uv_light = self.device

        self.cbe_uva = CallbackEmulator(self.uv_light.get_uva, self.cb_uva,
                                        self.increase_error_count)

        self.cbe_uvb = CallbackEmulator(self.uv_light.get_uvb, self.cb_uvb,
                                        self.increase_error_count)

        self.cbe_uvi = CallbackEmulator(self.uv_light.get_uvi, self.cb_uvi,
                                        self.increase_error_count)

        self.index_label = IndexLabel(' UVI: ? ')
        self.index_label.setText('0.0')

        self.current_uva = None
        self.current_uvb = None
        self.current_uvi = None

        plots = [('UVA', Qt.red, lambda: self.current_uva, u'{} mW/m²'.format),
                 ('UVB', Qt.darkGreen, lambda: self.current_uvb,
                  u'{} mW/m²'.format)]

        self.plot_widget = PlotWidget(u'UV [mW/m²]',
                                      plots,
                                      extra_key_widgets=[self.index_label])

        self.time_label = QLabel('Integration Time:')
        self.time_combo = QComboBox()
        self.time_combo.addItem("50 ms",
                                BrickletUVLightV2.INTEGRATION_TIME_50MS)
        self.time_combo.addItem("100 ms",
                                BrickletUVLightV2.INTEGRATION_TIME_100MS)
        self.time_combo.addItem("200 ms",
                                BrickletUVLightV2.INTEGRATION_TIME_200MS)
        self.time_combo.addItem("400 ms",
                                BrickletUVLightV2.INTEGRATION_TIME_400MS)
        self.time_combo.addItem("800 ms",
                                BrickletUVLightV2.INTEGRATION_TIME_800MS)
        self.time_combo.currentIndexChanged.connect(self.new_config)

        self.saturation_label = QLabel(
            'Sensor is saturated, choose a shorter integration time!')
        self.saturation_label.setStyleSheet('QLabel { color : red }')
        self.saturation_label.hide()

        hlayout = QHBoxLayout()
        hlayout.addWidget(self.time_label)
        hlayout.addWidget(self.time_combo)
        hlayout.addStretch()
        hlayout.addWidget(self.saturation_label)

        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)

        layout = QVBoxLayout(self)
        layout.addWidget(self.plot_widget)
        layout.addWidget(line)
        layout.addLayout(hlayout)

    def start(self):
        async_call(self.uv_light.get_configuration, None,
                   self.get_configucation_async, self.increase_error_count)
        async_call(self.uv_light.get_uva, None, self.cb_uva,
                   self.increase_error_count)
        self.cbe_uva.set_period(100)
        async_call(self.uv_light.get_uvb, None, self.cb_uvb,
                   self.increase_error_count)
        self.cbe_uvb.set_period(100)
        async_call(self.uv_light.get_uvi, None, self.cb_uvi,
                   self.increase_error_count)
        self.cbe_uvi.set_period(100)

        self.plot_widget.stop = False

    def stop(self):
        self.cbe_uva.set_period(0)
        self.cbe_uvb.set_period(0)
        self.cbe_uvi.set_period(0)

        self.plot_widget.stop = True

    def destroy(self):
        pass

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickletUVLightV2.DEVICE_IDENTIFIER

    def get_configucation_async(self, integration_time):
        self.time_combo.setCurrentIndex(
            self.time_combo.findData(integration_time))

    def new_config(self, value):
        try:
            self.uv_light.set_configuration(
                self.time_combo.itemData(self.time_combo.currentIndex()))
        except:
            pass

    def cb_uva(self, uva):
        self.saturation_label.setVisible(uva < 0)

        if uva < 0:  # saturated
            return

        self.current_uva = uva / 10.0

    def cb_uvb(self, uvb):
        self.saturation_label.setVisible(uvb < 0)

        if uvb < 0:  # saturated
            return

        self.current_uvb = uvb / 10.0

    def cb_uvi(self, uvi):
        self.saturation_label.setVisible(uvi < 0)

        if uvi < 0:  # saturated
            return

        uvi = round(uvi / 10.0, 1)

        self.index_label.setText(unicode(uvi))

        if uvi < 2.5:
            background = 'green'
            color = 'white'
        elif uvi < 5.5:
            background = 'yellow'
            color = 'black'
        elif uvi < 7.5:
            background = 'orange'
            color = 'black'
        elif uvi < 10.5:
            background = 'red'
            color = 'white'
        else:
            background = 'magenta'
            color = 'white'

        self.index_label.setStyleSheet(
            'QLabel {{ background : {0}; color : {1} }}'.format(
                background, color))
예제 #11
0
class AmbientLightV3(COMCUPluginBase):
    def __init__(self, *args):
        COMCUPluginBase.__init__(self, BrickletAmbientLightV3, *args)

        self.al = self.device

        self.cbe_illuminance = CallbackEmulator(self.al.get_illuminance,
                                                self.cb_illuminance,
                                                self.increase_error_count)

        self.alf = AmbientLightFrame()
        self.out_of_range_label = QLabel('Illuminance is out-of-range')
        self.saturated_label = QLabel('Sensor is saturated')

        self.out_of_range_label.hide()
        self.out_of_range_label.setStyleSheet('QLabel { color: red }')
        self.saturated_label.hide()
        self.saturated_label.setStyleSheet('QLabel { color: magenta }')

        self.current_illuminance = None # float, lx

        plots = [('Illuminance', Qt.red, lambda: self.current_illuminance, '{:.2f} lx (Lux)'.format)]
        self.plot_widget = PlotWidget('Illuminance [lx]', plots, extra_key_widgets=[self.out_of_range_label, self.saturated_label, self.alf])

        self.range_label = QLabel('Illuminance Range:')
        self.range_combo = QComboBox()

        self.range_combo.addItem("Unlimited", BrickletAmbientLightV3.ILLUMINANCE_RANGE_UNLIMITED)
        self.range_combo.addItem("0 - 64000 lx", BrickletAmbientLightV3.ILLUMINANCE_RANGE_64000LUX)
        self.range_combo.addItem("0 - 32000 lx", BrickletAmbientLightV3.ILLUMINANCE_RANGE_32000LUX)
        self.range_combo.addItem("0 - 16000 lx", BrickletAmbientLightV3.ILLUMINANCE_RANGE_16000LUX)
        self.range_combo.addItem("0 - 8000 lx", BrickletAmbientLightV3.ILLUMINANCE_RANGE_8000LUX)
        self.range_combo.addItem("0 - 1300 lx", BrickletAmbientLightV3.ILLUMINANCE_RANGE_1300LUX)
        self.range_combo.addItem("0 - 600 lx", BrickletAmbientLightV3.ILLUMINANCE_RANGE_600LUX)
        self.range_combo.currentIndexChanged.connect(self.new_config)

        self.time_label = QLabel('Integration Time:')
        self.time_combo = QComboBox()
        self.time_combo.addItem("50 ms", BrickletAmbientLightV3.INTEGRATION_TIME_50MS)
        self.time_combo.addItem("100 ms", BrickletAmbientLightV3.INTEGRATION_TIME_100MS)
        self.time_combo.addItem("150 ms", BrickletAmbientLightV3.INTEGRATION_TIME_150MS)
        self.time_combo.addItem("200 ms", BrickletAmbientLightV3.INTEGRATION_TIME_200MS)
        self.time_combo.addItem("250 ms", BrickletAmbientLightV3.INTEGRATION_TIME_250MS)
        self.time_combo.addItem("300 ms", BrickletAmbientLightV3.INTEGRATION_TIME_300MS)
        self.time_combo.addItem("350 ms", BrickletAmbientLightV3.INTEGRATION_TIME_350MS)
        self.time_combo.addItem("400 ms", BrickletAmbientLightV3.INTEGRATION_TIME_400MS)
        self.time_combo.currentIndexChanged.connect(self.new_config)

        hlayout = QHBoxLayout()
        hlayout.addWidget(self.range_label)
        hlayout.addWidget(self.range_combo)
        hlayout.addStretch()
        hlayout.addWidget(self.time_label)
        hlayout.addWidget(self.time_combo)

        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)

        layout = QVBoxLayout(self)
        layout.addWidget(self.plot_widget)
        layout.addWidget(line)
        layout.addLayout(hlayout)

    def start(self):
        async_call(self.al.get_configuration, None, self.get_configucation_async, self.increase_error_count)
        async_call(self.al.get_illuminance, None, self.cb_illuminance, self.increase_error_count)
        self.cbe_illuminance.set_period(100)

        self.plot_widget.stop = False

    def stop(self):
        self.cbe_illuminance.set_period(0)

        self.plot_widget.stop = True

    def destroy(self):
        pass

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickletAmbientLightV3.DEVICE_IDENTIFIER

    def get_configucation_async(self, conf):
        self.range_combo.setCurrentIndex(self.range_combo.findData(conf.illuminance_range))
        self.time_combo.setCurrentIndex(self.time_combo.findData(conf.integration_time))

    def new_config(self, value):
        try:
            self.al.set_configuration(self.range_combo.itemData(self.range_combo.currentIndex()),
                                      self.time_combo.itemData(self.time_combo.currentIndex()))
        except:
            pass

    def cb_illuminance(self, illuminance):
        self.current_illuminance = illuminance / 100.0

        max_illuminance = 12000000 # Approximation for unlimited range
        current_range = self.range_combo.itemData(self.range_combo.currentIndex())
        if current_range == BrickletAmbientLightV3.ILLUMINANCE_RANGE_64000LUX:
            max_illuminance = 6400001
        elif current_range == BrickletAmbientLightV3.ILLUMINANCE_RANGE_32000LUX:
            max_illuminance = 3200001
        elif current_range == BrickletAmbientLightV3.ILLUMINANCE_RANGE_16000LUX:
            max_illuminance = 1600001
        elif current_range == BrickletAmbientLightV3.ILLUMINANCE_RANGE_8000LUX:
            max_illuminance = 800001
        elif current_range == BrickletAmbientLightV3.ILLUMINANCE_RANGE_1300LUX:
            max_illuminance = 130001
        elif current_range == BrickletAmbientLightV3.ILLUMINANCE_RANGE_600LUX:
            max_illuminance = 60001

        if illuminance == 0:
            self.plot_widget.get_key_item(0).setStyleSheet('QLabel { color: magenta }')
            self.out_of_range_label.hide()
            self.saturated_label.show()
        elif illuminance >= max_illuminance:
            self.plot_widget.get_key_item(0).setStyleSheet('QLabel { color: red }')
            self.out_of_range_label.show()
            self.saturated_label.hide()
        else:
            self.plot_widget.get_key_item(0).setStyleSheet('')
            self.out_of_range_label.hide()
            self.saturated_label.hide()

        value = min(max(illuminance * 255 / max_illuminance, 0), 255)
        self.alf.set_color(value, value, value)
예제 #12
0
class Thermocouple(PluginBase):
    qtcb_error_state = pyqtSignal(bool, bool)

    def __init__(self, *args):
        PluginBase.__init__(self, BrickletThermocouple, *args)

        self.thermo = self.device

        self.qtcb_error_state.connect(self.cb_error_state)
        self.thermo.register_callback(self.thermo.CALLBACK_ERROR_STATE,
                                      self.qtcb_error_state.emit)

        self.cbe_temperature = CallbackEmulator(self.thermo.get_temperature,
                                                self.cb_temperature,
                                                self.increase_error_count)

        self.current_temperature = None # float, °C

        self.error_label = QLabel('Current Errors: None')
        self.error_label.setAlignment(Qt.AlignVCenter | Qt.AlignRight)

        plots = [('Temperature', Qt.red, lambda: self.current_temperature, u'{:.2f} °C'.format)]
        self.plot_widget = PlotWidget(u'Temperature [°C]', plots, extra_key_widgets=[self.error_label])

        self.averaging_label = QLabel('Averaging:')
        self.averaging_combo = QComboBox()
        self.averaging_combo.addItem('1', BrickletThermocouple.AVERAGING_1)
        self.averaging_combo.addItem('2', BrickletThermocouple.AVERAGING_2)
        self.averaging_combo.addItem('4', BrickletThermocouple.AVERAGING_4)
        self.averaging_combo.addItem('8', BrickletThermocouple.AVERAGING_8)
        self.averaging_combo.addItem('16', BrickletThermocouple.AVERAGING_16)

        self.type_label = QLabel('Thermocouple Type:')
        self.type_combo = QComboBox()
        self.type_combo.addItem('B', BrickletThermocouple.TYPE_B)
        self.type_combo.addItem('E', BrickletThermocouple.TYPE_E)
        self.type_combo.addItem('J', BrickletThermocouple.TYPE_J)
        self.type_combo.addItem('K', BrickletThermocouple.TYPE_K)
        self.type_combo.addItem('N', BrickletThermocouple.TYPE_N)
        self.type_combo.addItem('R', BrickletThermocouple.TYPE_R)
        self.type_combo.addItem('S', BrickletThermocouple.TYPE_S)
        self.type_combo.addItem('T', BrickletThermocouple.TYPE_T)
        self.type_combo.addItem('Gain 8', BrickletThermocouple.TYPE_G8)
        self.type_combo.addItem('Gain 32', BrickletThermocouple.TYPE_G32)

        self.filter_label = QLabel('Noise Rejection Filter:')
        self.filter_combo = QComboBox()
        self.filter_combo.addItem('50 Hz', BrickletThermocouple.FILTER_OPTION_50HZ)
        self.filter_combo.addItem('60 Hz', BrickletThermocouple.FILTER_OPTION_60HZ)

        hlayout = QHBoxLayout()
        hlayout.addWidget(self.averaging_label)
        hlayout.addWidget(self.averaging_combo)
        hlayout.addStretch()
        hlayout.addWidget(self.type_label)
        hlayout.addWidget(self.type_combo)
        hlayout.addStretch()
        hlayout.addWidget(self.filter_label)
        hlayout.addWidget(self.filter_combo)

        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)

        layout = QVBoxLayout(self)
        layout.addWidget(self.plot_widget)
        layout.addWidget(line)
        layout.addLayout(hlayout)

        self.averaging_combo.currentIndexChanged.connect(self.configuration_changed)
        self.type_combo.currentIndexChanged.connect(self.configuration_changed)
        self.filter_combo.currentIndexChanged.connect(self.configuration_changed)

    def start(self):
        async_call(self.thermo.get_temperature, None, self.cb_temperature, self.increase_error_count)
        async_call(self.thermo.get_configuration, None, self.cb_configuration, self.increase_error_count)
        async_call(self.thermo.get_error_state, None, lambda e: self.cb_error_state(e.over_under, e.open_circuit))
        self.cbe_temperature.set_period(100)

        self.plot_widget.stop = False

    def stop(self):
        self.cbe_temperature.set_period(0)

        self.plot_widget.stop = True

    def destroy(self):
        pass

    def get_url_part(self):
        return 'thermocouple'

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickletThermocouple.DEVICE_IDENTIFIER

    def get_current_value(self):
        return self.current_value

    def configuration_changed(self, _):
        conf_averaging = self.averaging_combo.itemData(self.averaging_combo.currentIndex())
        conf_type = self.type_combo.itemData(self.type_combo.currentIndex())
        conf_filter = self.filter_combo.itemData(self.filter_combo.currentIndex())

        self.thermo.set_configuration(conf_averaging, conf_type, conf_filter)

    def cb_temperature(self, temperature):
        self.current_temperature = temperature / 100.0

    def cb_configuration(self, conf):
        self.averaging_combo.blockSignals(True)
        self.averaging_combo.setCurrentIndex(self.averaging_combo.findData(conf.averaging))
        self.averaging_combo.blockSignals(False)

        self.type_combo.blockSignals(True)
        self.type_combo.setCurrentIndex(self.type_combo.findData(conf.thermocouple_type))
        self.type_combo.blockSignals(False)

        self.filter_combo.blockSignals(True)
        self.filter_combo.setCurrentIndex(self.filter_combo.findData(conf.filter))
        self.filter_combo.blockSignals(False)

    def cb_error_state(self, over_under, open_circuit):
        if over_under or open_circuit:
            text = 'Current Errors: '
            if over_under:
                text += 'Over/Under Voltage'
            if over_under and open_circuit:
                text += ' and '
            if open_circuit:
                text += 'Open Circuit\n(defective thermocouple or nothing connected)'

            self.error_label.setStyleSheet('QLabel { color : red }')
            self.error_label.setText(text)
        else:
            self.error_label.setStyleSheet('')
            self.error_label.setText('Current Errors: None')
예제 #13
0
class ScoringDialog(QWidget):
    """a dialog for entering the scores"""
    # pylint: disable=R0902
    # pylint we need more than 10 instance attributes

    scoringClosed = pyqtSignal()

    def __init__(self, game):
        QWidget.__init__(self, None)
        self.game = None
        self.setWindowTitle(m18n('Scoring for this Hand') + ' - Kajongg')
        self.nameLabels = [None] * 4
        self.spValues = [None] * 4
        self.windLabels = [None] * 4
        self.wonBoxes = [None] * 4
        self.detailsLayout = [None] * 4
        self.details = [None] * 4
        self.__tilePixMaps = []
        self.__meldPixMaps = []
        grid = QGridLayout(self)
        pGrid = QGridLayout()
        grid.addLayout(pGrid, 0, 0, 2, 1)
        pGrid.addWidget(QLabel(m18nc('kajongg', "Player")), 0, 0)
        pGrid.addWidget(QLabel(m18nc('kajongg', "Wind")), 0, 1)
        pGrid.addWidget(QLabel(m18nc('kajongg', 'Score')), 0, 2)
        pGrid.addWidget(QLabel(m18n("Winner")), 0, 3)
        self.detailTabs = QTabWidget()
        self.detailTabs.setDocumentMode(True)
        pGrid.addWidget(self.detailTabs, 0, 4, 8, 1)
        for idx in range(4):
            self.setupUiForPlayer(pGrid, idx)
        self.draw = QCheckBox(m18nc('kajongg','Draw'))
        self.draw.clicked.connect(self.wonChanged)
        btnPenalties = QPushButton(m18n("&Penalties"))
        btnPenalties.clicked.connect(self.penalty)
        self.btnSave = QPushButton(m18n('&Save Hand'))
        self.btnSave.setEnabled(False)
        self.setupUILastTileMeld(pGrid)
        pGrid.setRowStretch(87, 10)
        pGrid.addWidget(self.draw, 7, 3)
        self.cbLastTile.currentIndexChanged.connect(self.slotLastTile)
        self.cbLastMeld.currentIndexChanged.connect(self.slotInputChanged)
        btnBox = QHBoxLayout()
        btnBox.addWidget(btnPenalties)
        btnBox.addWidget(self.btnSave)
        pGrid.addLayout(btnBox, 8, 4)
        StateSaver(self)
        self.refresh(game)

    def setupUILastTileMeld(self, pGrid):
        """setup UI elements for last tile and last meld"""
        self.lblLastTile = QLabel(m18n('&Last Tile:'))
        self.cbLastTile = QComboBox()
        self.cbLastTile.setMinimumContentsLength(1)
        vpol = QSizePolicy()
        vpol.setHorizontalPolicy(QSizePolicy.Fixed)
        self.cbLastTile.setSizePolicy(vpol)
        self.cbLastTile.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLengthWithIcon)
        self.lblLastTile.setBuddy(self.cbLastTile)
        self.lblLastMeld = QLabel(m18n('L&ast Meld:'))
        self.prevLastTile = None
        self.cbLastMeld = QComboBox()
        self.cbLastMeld.setMinimumContentsLength(1)
        self.cbLastMeld.setSizePolicy(vpol)
        self.cbLastMeld.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLengthWithIcon)
        self.lblLastMeld.setBuddy(self.cbLastMeld)
        self.comboTilePairs = set()
        pGrid.setRowStretch(6, 5)
        pGrid.addWidget(self.lblLastTile, 7, 0, 1, 2)
        pGrid.addWidget(self.cbLastTile, 7, 2, 1, 1)
        pGrid.addWidget(self.lblLastMeld, 8, 0, 1, 2)
        pGrid.addWidget(self.cbLastMeld, 8, 2, 1, 2)

    def setupUiForPlayer(self, pGrid, idx):
        """setup UI elements for a player"""
        self.spValues[idx] = QSpinBox()
        self.nameLabels[idx] = QLabel()
        self.nameLabels[idx].setBuddy(self.spValues[idx])
        self.windLabels[idx] = WindLabel()
        pGrid.addWidget(self.nameLabels[idx], idx+2, 0)
        pGrid.addWidget(self.windLabels[idx], idx+2, 1)
        pGrid.addWidget(self.spValues[idx], idx+2, 2)
        self.wonBoxes[idx] = QCheckBox("")
        pGrid.addWidget(self.wonBoxes[idx], idx+2, 3)
        self.wonBoxes[idx].clicked.connect(self.wonChanged)
        self.spValues[idx].valueChanged.connect(self.slotInputChanged)
        detailTab = QWidget()
        self.detailTabs.addTab(detailTab,'')
        self.details[idx] = QWidget()
        detailTabLayout = QVBoxLayout(detailTab)
        detailTabLayout.addWidget(self.details[idx])
        detailTabLayout.addStretch()
        self.detailsLayout[idx] = QVBoxLayout(self.details[idx])


    def refresh(self, game):
        """reload game"""
        if game and not game.isScoringGame():
            return
        self.game = game
        self.clear()
        self.setVisible(game is not None and not game.finished())
        if game:
            for idx, player in enumerate(game.players):
                for child in self.details[idx].children():
                    if isinstance(child, RuleBox):
                        child.hide()
                        self.detailsLayout[idx].removeWidget(child)
                        del child
                if game:
                    self.spValues[idx].setRange(0, game.ruleset.limit or 99999)
                    self.nameLabels[idx].setText(player.localName)
                    self.windLabels[idx].wind = player.wind
                    self.windLabels[idx].roundsFinished = game.roundsFinished
                    self.detailTabs.setTabText(idx, player.localName)
                    player.manualRuleBoxes = [RuleBox(x) for x in game.ruleset.allRules if x.hasSelectable]
                    for ruleBox in player.manualRuleBoxes:
                        self.detailsLayout[idx].addWidget(ruleBox)
                        ruleBox.clicked.connect(self.slotInputChanged)
                player.refreshManualRules()

    def show(self):
        """only now compute content"""
        if self.game and not self.game.finished():
            self.slotInputChanged()
            QWidget.show(self)

    def penalty(self):
        """penalty button clicked"""
        dlg = PenaltyDialog(self.game)
        dlg.exec_()

    def slotLastTile(self):
        """called when the last tile changes"""
        newLastTile = self.computeLastTile()
        if not newLastTile:
            return
        prevLower, newLower = self.prevLastTile.islower(), newLastTile.islower()
        if prevLower != newLower:
            # state of last tile (concealed/exposed) changed:
            # for all checked boxes check if they still are applicable
            winner = self.game.winner
            if winner:
                for box in winner.manualRuleBoxes:
                    if box.isChecked():
                        box.setChecked(False)
                        if winner.hand.manualRuleMayApply(box.rule):
                            box.setChecked(True)
        self.prevLastTile = newLastTile
        self.fillLastMeldCombo()
        self.slotInputChanged()

    def computeLastTile(self):
        """returns the currently selected last tile"""
        idx = self.cbLastTile.currentIndex()
        if idx >= 0:
            return str(self.cbLastTile.itemData(idx).toString())

    def closeEvent(self, event):
        """the user pressed ALT-F4"""
        self.hide()
        event.ignore()
        self.scoringClosed.emit()

    def clickedPlayerIdx(self, checkbox):
        """the player whose box has been clicked"""
        for idx in range(4):
            if checkbox == self.wonBoxes[idx]:
                return idx
        assert False

    def wonChanged(self):
        """if a new winner has been defined, uncheck any previous winner"""
        newWinner = None
        if self.sender() != self.draw:
            clicked = self.clickedPlayerIdx(self.sender())
            if self.wonBoxes[clicked].isChecked():
                newWinner = self.game.players[clicked]
            else:
                newWinner = None
        self.game.winner = newWinner
        for idx in range(4):
            if newWinner != self.game.players[idx]:
                self.wonBoxes[idx].setChecked(False)
        if newWinner:
            self.draw.setChecked(False)
        self.fillLastTileCombo()
        self.slotInputChanged()

    def updateManualRules(self):
        """enable/disable them"""
        # if an exclusive rule has been activated, deactivate it for
        # all other players
        if isinstance(self.sender(), RuleBox):
            ruleBox = self.sender()
            if ruleBox.isChecked() and ruleBox.rule.exclusive():
                for idx, player in enumerate(self.game.players):
                    if ruleBox.parentWidget() != self.details[idx]:
                        for pBox in player.manualRuleBoxes:
                            if pBox.rule.name == ruleBox.rule.name:
                                pBox.setChecked(False)
        try:
            newState = bool(self.game.winner.handBoard.tiles)
        except AttributeError:
            newState = False
        self.lblLastTile.setEnabled(newState)
        self.cbLastTile.setEnabled(newState)
        self.lblLastMeld.setEnabled(newState)
        self.cbLastMeld.setEnabled(newState)
        if self.game:
            for player in self.game.players:
                player.refreshManualRules(self.sender())

    def clear(self):
        """prepare for next hand"""
        if self.game:
            for idx, player in enumerate(self.game.players):
                self.spValues[idx].clear()
                self.spValues[idx].setValue(0)
                self.wonBoxes[idx].setChecked(False)
                player.payment = 0
                player.invalidateHand()
        for box in self.wonBoxes:
            box.setVisible(False)
        self.draw.setChecked(False)
        self.updateManualRules()

        if self.game is None:
            self.hide()
        else:
            for idx, player in enumerate(self.game.players):
                self.windLabels[idx].setPixmap(WINDPIXMAPS[(player.wind,
                            player.wind == WINDS[self.game.roundsFinished % 4])])
            self.computeScores()
            self.spValues[0].setFocus()
            self.spValues[0].selectAll()

    def computeScores(self):
        """if tiles have been selected, compute their value"""
        # pylint: disable=R0912
        # too many branches
        if not self.game:
            return
        if self.game.finished():
            self.hide()
            return
        for idx, player in enumerate(self.game.players):
            self.spValues[idx].blockSignals(True) # we do not want that change to call computeScores again
            self.wonBoxes[idx].blockSignals(True) # we do not want that change to call computeScores again
            if player.handBoard and player.handBoard.tiles:
                self.spValues[idx].setEnabled(False)
                self.nameLabels[idx].setBuddy(self.wonBoxes[idx])
                for loop in range(10):
                    prevTotal = player.handTotal
                    handContent = player.computeHand(asWinner=True)
                    self.wonBoxes[idx].setVisible(handContent.won)
                    if not self.wonBoxes[idx].isVisibleTo(self) and self.wonBoxes[idx].isChecked():
                        self.wonBoxes[idx].setChecked(False)
                        self.game.winner = None
                    elif prevTotal == player.handTotal:
                        break
                    player.refreshManualRules()
                self.spValues[idx].setValue(player.handTotal)
            else:
                if not self.spValues[idx].isEnabled():
                    self.spValues[idx].clear()
                    self.spValues[idx].setValue(0)
                    self.spValues[idx].setEnabled(True)
                    self.nameLabels[idx].setBuddy(self.spValues[idx])
                self.wonBoxes[idx].setVisible(player.handTotal >= self.game.ruleset.minMJTotal())
                if not self.wonBoxes[idx].isVisibleTo(self) and self.wonBoxes[idx].isChecked():
                    self.wonBoxes[idx].setChecked(False)
            if not self.wonBoxes[idx].isVisibleTo(self) and player is self.game.winner:
                self.game.winner = None
            self.spValues[idx].blockSignals(False)
            self.wonBoxes[idx].blockSignals(False)
        if Internal.field.explainView:
            Internal.field.explainView.refresh(self.game)

    def __lastMeldContent(self):
        """prepare content for lastmeld combo"""
        lastTiles = set()
        winnerTiles = []
        if self.game.winner and self.game.winner.handBoard:
            winnerTiles = self.game.winner.handBoard.tiles
            pairs = []
            for meld in self.game.winner.hand.melds:
                if len(meld) < 4:
                    pairs.extend(meld.pairs)
            for tile in winnerTiles:
                if tile.element in pairs and not tile.isBonus():
                    lastTiles.add(tile.element)
        return lastTiles, winnerTiles

    def __fillLastTileComboWith(self, lastTiles, winnerTiles):
        """fill last meld combo with prepared content"""
        self.comboTilePairs = lastTiles
        idx = self.cbLastTile.currentIndex()
        if idx < 0:
            idx = 0
        indexedTile = str(self.cbLastTile.itemData(idx).toPyObject())
        restoredIdx = None
        self.cbLastTile.clear()
        if not winnerTiles:
            return
        pmSize = winnerTiles[0].board.tileset.faceSize
        pmSize = QSize(pmSize.width() * 0.5, pmSize.height() * 0.5)
        self.cbLastTile.setIconSize(pmSize)
        QPixmapCache.clear()
        self.__tilePixMaps = []
        shownTiles = set()
        for tile in winnerTiles:
            if tile.element in lastTiles and tile.element not in shownTiles:
                shownTiles.add(tile.element)
                self.cbLastTile.addItem(QIcon(tile.graphics.pixmapFromSvg(pmSize, withBorders=False)),
                        '', QVariant(tile.element))
                if indexedTile == tile.element:
                    restoredIdx = self.cbLastTile.count() - 1
        if not restoredIdx and indexedTile:
            # try again, maybe the tile changed between concealed and exposed
            indexedTile = indexedTile.lower()
            for idx in range(self.cbLastTile.count()):
                if indexedTile == str(self.cbLastTile.itemData(idx).toPyObject()).lower():
                    restoredIdx = idx
                    break
        if not restoredIdx:
            restoredIdx = 0
        self.cbLastTile.setCurrentIndex(restoredIdx)
        self.prevLastTile = self.computeLastTile()

    def clearLastTileCombo(self):
        """as the name says"""
        self.comboTilePairs = None
        self.cbLastTile.clear()

    def fillLastTileCombo(self):
        """fill the drop down list with all possible tiles.
        If the drop down had content before try to preserve the
        current index. Even if the tile changed state meanwhile."""
        if self.game is None:
            return
        lastTiles, winnerTiles = self.__lastMeldContent()
        if self.comboTilePairs == lastTiles:
            return
        self.cbLastTile.blockSignals(True) # we only want to emit the changed signal once
        try:
            self.__fillLastTileComboWith(lastTiles, winnerTiles)
        finally:
            self.cbLastTile.blockSignals(False)
            self.cbLastTile.currentIndexChanged.emit(0)

    def __fillLastMeldComboWith(self, winnerMelds, indexedMeld, lastTile):
        """fill last meld combo with prepared content"""
        winner = self.game.winner
        faceWidth = winner.handBoard.tileset.faceSize.width() * 0.5
        faceHeight = winner.handBoard.tileset.faceSize.height() * 0.5
        restoredIdx = None
        for meld in winnerMelds:
            pixMap = QPixmap(faceWidth * len(meld), faceHeight)
            pixMap.fill(Qt.transparent)
            self.__meldPixMaps.append(pixMap)
            painter = QPainter(pixMap)
            for element in meld.pairs:
                painter.drawPixmap(0, 0,
                    winner.handBoard.tilesByElement(element) \
                    [0].graphics.pixmapFromSvg(QSize(faceWidth, faceHeight), withBorders=False))
                painter.translate(QPointF(faceWidth, 0.0))
            self.cbLastMeld.addItem(QIcon(pixMap), '', QVariant(meld.joined))
            if indexedMeld == meld.joined:
                restoredIdx = self.cbLastMeld.count() - 1
        if not restoredIdx and indexedMeld:
            # try again, maybe the meld changed between concealed and exposed
            indexedMeld = indexedMeld.lower()
            for idx in range(self.cbLastMeld.count()):
                meldContent = str(self.cbLastMeld.itemData(idx).toPyObject())
                if indexedMeld == meldContent.lower():
                    restoredIdx = idx
                    if lastTile not in meldContent:
                        if lastTile.lower() == lastTile:
                            lastTile = lastTile.capitalize()
                        else:
                            lastTile = lastTile.lower()
                        assert lastTile in meldContent
                        self.cbLastTile.blockSignals(True) # we want to continue right here
                        idx = self.cbLastTile.findData(QVariant(lastTile))
                        self.cbLastTile.setCurrentIndex(idx)
                        self.cbLastTile.blockSignals(False)
                    break
        if not restoredIdx:
            restoredIdx = 0
        self.cbLastMeld.setCurrentIndex(restoredIdx)
        self.cbLastMeld.setIconSize(QSize(faceWidth * 3, faceHeight))

    def fillLastMeldCombo(self):
        """fill the drop down list with all possible melds.
        If the drop down had content before try to preserve the
        current index. Even if the meld changed state meanwhile."""
        self.cbLastMeld.blockSignals(True) # we only want to emit the changed signal once
        try:
            showCombo = False
            idx = self.cbLastMeld.currentIndex()
            if idx < 0:
                idx = 0
            indexedMeld = str(self.cbLastMeld.itemData(idx).toPyObject())
            self.cbLastMeld.clear()
            self.__meldPixMaps = []
            if not self.game.winner:
                return
            if self.cbLastTile.count() == 0:
                return
            lastTile = Internal.field.computeLastTile()
            winnerMelds = [m for m in self.game.winner.hand.melds if len(m) < 4 \
                and lastTile in m.pairs]
            assert len(winnerMelds)
            if len(winnerMelds) == 1:
                self.cbLastMeld.addItem(QIcon(), '', QVariant(winnerMelds[0].joined))
                self.cbLastMeld.setCurrentIndex(0)
                return
            showCombo = True
            self.__fillLastMeldComboWith(winnerMelds, indexedMeld, lastTile)
        finally:
            self.lblLastMeld.setVisible(showCombo)
            self.cbLastMeld.setVisible(showCombo)
            self.cbLastMeld.blockSignals(False)
            self.cbLastMeld.currentIndexChanged.emit(0)

    def slotInputChanged(self):
        """some input fields changed: update"""
        for player in self.game.players:
            player.invalidateHand()
        self.updateManualRules()
        self.computeScores()
        self.validate()

    def validate(self):
        """update the status of the OK button"""
        game = self.game
        if game:
            valid = True
            if game.winner and game.winner.handTotal < game.ruleset.minMJTotal():
                valid = False
            elif not game.winner and not self.draw.isChecked():
                valid = False
            self.btnSave.setEnabled(valid)
예제 #14
0
파일: updatebox.py 프로젝트: urkh/Turpial
class UpdateBox(QWidget):
    def __init__(self, base):
        QWidget.__init__(self)
        self.base = base
        self.showed = False
        self.setFixedSize(500, 120)

        self.text_edit = CompletionTextEdit()

        self.upload_button = ImageButton(base, 'action-upload.png',
                i18n.get('upload_image'))
        self.short_button = ImageButton(base, 'action-shorten.png',
                i18n.get('short_urls'))

        font = QFont()
        font.setPointSize(18)
        font.setBold(True)
        self.char_count = QLabel('140')
        self.char_count.setFont(font)

        self.update_button = QPushButton(i18n.get('update'))
        self.update_button.setToolTip(self.base.get_shortcut_string('Enter'))
        self.queue_button = QPushButton(i18n.get('add_to_queue'))
        self.queue_button.setToolTip(self.base.get_shortcut_string('P'))

        self.accounts_combo = QComboBox()

        buttons = QHBoxLayout()
        buttons.setSpacing(4)
        buttons.addWidget(self.accounts_combo)
        buttons.addWidget(self.upload_button)
        buttons.addWidget(self.short_button)
        buttons.addStretch(0)
        buttons.addWidget(self.char_count)
        buttons.addWidget(self.queue_button)
        buttons.addWidget(self.update_button)

        self.loader = BarLoadIndicator()

        self.error_message = ErrorLabel()

        self.update_button.clicked.connect(self.__update_status)
        self.queue_button.clicked.connect(self.__queue_status)
        self.short_button.clicked.connect(self.__short_urls)
        self.upload_button.clicked.connect(self.__upload_image)
        self.text_edit.textChanged.connect(self.__update_count)
        self.text_edit.quit.connect(self.closeEvent)
        self.text_edit.activated.connect(self.__update_status)
        self.text_edit.enqueued.connect(self.__queue_status)

        layout = QVBoxLayout()
        layout.setSpacing(0)
        layout.addWidget(self.text_edit)
        layout.addWidget(self.loader)
        layout.addSpacing(5)
        layout.addWidget(self.error_message)
        layout.addLayout(buttons)
        layout.setContentsMargins(5, 5, 5, 5)
        self.setLayout(layout)

        self.__clear()

    def __count_chars(self):
        message = self.text_edit.toPlainText()
        urls = [str(url) for url in get_urls(message) if len(url) > 23]
        for url in urls:
            message = message.replace(url, '0' * 23)
        return MAX_CHAR - len(message)

    def __update_count(self):
        remaining_chars = self.__count_chars()
        if remaining_chars <= 10:
            self.char_count.setStyleSheet("QLabel { color: #D40D12 }")
        elif remaining_chars > 10 and remaining_chars <= 20:
            self.char_count.setStyleSheet("QLabel { color: #D4790D }")
        else:
            self.char_count.setStyleSheet("QLabel { color: #000000 }")
        self.char_count.setText(str(remaining_chars))

    def __validate(self, message, accounts, index):
        if len(message) == 0:
            self.error(i18n.get('you_can_not_submit_an_empty_message'))
            return False

        if index == 0 and len(accounts) > 1:
            self.error(i18n.get('select_an_account_before_post'))
            return False

        if self.__count_chars() < 0:
            self.error(i18n.get('message_too_long'))
            return False

        return True

    def __short_urls(self):
        self.enable(False)
        message = unicode(self.text_edit.toPlainText())
        self.base.short_urls(message)

    def __upload_image(self):
        index = self.accounts_combo.currentIndex()
        accounts = self.base.core.get_registered_accounts()

        if index == 0 and len(accounts) > 1:
            self.error(i18n.get('select_an_account_before_post'))
            return False

        account_id = str(self.accounts_combo.itemData(index).toPyObject())
        filename = str(QFileDialog.getOpenFileName(self, i18n.get('upload_image'),
            self.base.home_path))
        if filename != '':
            self.enable(False)
            self.base.upload_media(account_id, filename)

    def __update_status(self):
        index = self.accounts_combo.currentIndex()
        accounts = self.base.core.get_registered_accounts()
        message = unicode(self.text_edit.toPlainText())

        if not self.__validate(message, accounts, index):
            self.enable(True)
            return

        self.enable(False)
        account_id = str(self.accounts_combo.itemData(index).toPyObject())

        if self.direct_message_to:
            self.base.send_direct_message(account_id, self.direct_message_to, message)
        else:
            if account_id == 'broadcast':
                self.base.broadcast_status(message)
            else:
                self.base.update_status(account_id, message, self.in_reply_to_id)

    def __queue_status(self):
        index = self.accounts_combo.currentIndex()
        accounts = self.base.core.get_registered_accounts()
        account_id = str(self.accounts_combo.itemData(index).toPyObject())
        message = unicode(self.text_edit.toPlainText())

        if not self.__validate(message, accounts, index):
            self.enable(True)
            return

        self.enable(False)
        self.base.push_status_to_queue(account_id, message)

    def __clear(self):
        self.account_id = None
        self.in_reply_to_id = None
        self.in_reply_to_user = None
        self.direct_message_to = None
        self.quoting = False
        self.message = None
        self.cursor_position = None
        self.text_edit.setText('')
        self.accounts_combo.setCurrentIndex(0)
        self.queue_button.setEnabled(True)
        self.loader.setVisible(False)
        self.error_message.setVisible(False)
        self.error_message.setText('')
        self.enable(True)
        self.showed = False

    def __show(self):
        self.update_friends_list()
        short_service = self.base.get_shorten_url_service()
        short_tooltip = "%s (%s)" % (i18n.get('short_url'), short_service)
        self.short_button.setToolTip(short_tooltip)
        upload_service = self.base.get_upload_media_service()
        upload_tooltip = "%s (%s)" % (i18n.get('upload_image'), upload_service)
        self.upload_button.setToolTip(upload_tooltip)
        self.accounts_combo.clear()
        accounts = self.base.core.get_registered_accounts()
        if len(accounts) > 1:
            self.accounts_combo.addItem('--', '')
        for account in accounts:
            protocol = get_protocol_from(account.id_)
            icon = QIcon(self.base.get_image_path('%s.png' % protocol))
            self.accounts_combo.addItem(icon, get_username_from(account.id_), account.id_)
        if len(accounts) > 1:
            icon = QIcon(self.base.get_image_path('action-conversation.png'))
            self.accounts_combo.addItem(icon, i18n.get('broadcast'), 'broadcast')
        if self.account_id:
            index = self.accounts_combo.findData(self.account_id)
            if index > 0:
                self.accounts_combo.setCurrentIndex(index)
            self.accounts_combo.setEnabled(False)
        if self.message:
            self.text_edit.setText(self.message)
            cursor = self.text_edit.textCursor()
            cursor.movePosition(self.cursor_position, QTextCursor.MoveAnchor)
            self.text_edit.setTextCursor(cursor)

        QWidget.show(self)
        self.showed = True

    def __on_timeout(self):
        self.error_message.setText('')
        self.error_message.setVisible(False)

    def show(self):
        if self.showed:
            return self.raise_()
        self.setWindowTitle(i18n.get('whats_happening'))
        self.__show()

    def show_for_reply(self, account_id, status):
        if self.showed:
            return self.raise_()
        title = "%s @%s" % (i18n.get('reply_to'), status.username)
        self.setWindowTitle(title)
        self.account_id = account_id
        self.in_reply_to_id = status.id_
        self.in_reply_to_user = status.username
        mentions = ' '.join(["@%s" % user for user in status.get_mentions()])
        self.message = "%s " % mentions
        self.cursor_position = QTextCursor.End
        self.__show()

    def show_for_send_direct(self, account_id, username):
        if self.showed:
            return self.raise_()
        title = "%s @%s" % (i18n.get('send_message_to'), username)
        self.setWindowTitle(title)
        self.account_id = account_id
        self.direct_message_to = username
        self.__show()
        self.queue_button.setEnabled(False)

    def show_for_reply_direct(self, account_id, status):
        if self.showed:
            return self.raise_()
        title = "%s @%s" % (i18n.get('send_message_to'), status.username)
        self.setWindowTitle(title)
        self.account_id = account_id
        self.direct_message_to = status.username
        self.__show()
        self.queue_button.setEnabled(False)

    def show_for_quote(self, account_id, status):
        if self.showed:
            return self.raise_()
        self.setWindowTitle(i18n.get('quoting'))
        self.account_id = account_id
        self.message = " RT @%s %s" % (status.username, status.text)
        self.cursor_position = QTextCursor.Start
        self.quoting = True
        self.__show()
        self.queue_button.setEnabled(False)

    def closeEvent(self, event=None):
        message = unicode(self.text_edit.toPlainText())

        if len(message) > 0:
            confirmation = self.base.show_confirmation_message(i18n.get('confirm_discard'),
                i18n.get('do_you_want_to_discard_message'))
            if not confirmation:
                return

        if event:
            event.ignore()
        self.__clear()
        self.hide()

    def enable(self, value):
        self.text_edit.setEnabled(value)
        if not self.account_id:
            self.accounts_combo.setEnabled(value)
        if self.in_reply_to_id or self.direct_message_to or self.quoting:
            self.queue_button.setEnabled(False)
        else:
            self.queue_button.setEnabled(value)
        self.upload_button.setEnabled(value)
        self.short_button.setEnabled(value)
        self.update_button.setEnabled(value)
        self.loader.setVisible(not value)

    def done(self):
        self.__clear()
        self.hide()

    def error(self, message):
        self.enable(True)
        self.error_message.setText(message)
        self.error_message.setVisible(True)
        self.timer = QTimer()
        self.timer.timeout.connect(self.__on_timeout)
        self.timer.start(5000)

    def after_short_url(self, message):
        if self.base.is_exception(message):
            self.error(i18n.get('error_shorting_url'))
        else:
            self.text_edit.setText(message)
        self.enable(True)

    def after_upload_media(self, media_url):
        if self.base.is_exception(media_url):
            self.error(i18n.get('error_uploading_image'))
        else:
            text_cursor = self.text_edit.textCursor()
            text_cursor.select(QTextCursor.WordUnderCursor)
            if text_cursor.selectedText() != '':
                media_url = " %s" % media_url
            text_cursor.clearSelection()
            text_cursor.insertText(media_url)
            self.text_edit.setTextCursor(text_cursor)
        self.enable(True)

    def update_friends_list(self):
        completer = QCompleter(self.base.load_friends_list_with_extras())
        self.text_edit.setCompleter(completer)
예제 #15
0
class Thermocouple(PluginBase):
    qtcb_error_state = pyqtSignal(bool, bool)

    def __init__(self, *args):
        PluginBase.__init__(self, BrickletThermocouple, *args)

        self.thermo = self.device

        self.qtcb_error_state.connect(self.cb_error_state)
        self.thermo.register_callback(self.thermo.CALLBACK_ERROR_STATE,
                                      self.qtcb_error_state.emit)

        self.cbe_temperature = CallbackEmulator(self.thermo.get_temperature,
                                                self.cb_temperature,
                                                self.increase_error_count)

        self.current_temperature = None  # float, °C

        self.error_label = QLabel('Current Errors: None')
        self.error_label.setAlignment(Qt.AlignVCenter | Qt.AlignRight)

        plots = [('Temperature', Qt.red, lambda: self.current_temperature,
                  u'{:.2f} °C'.format)]
        self.plot_widget = PlotWidget(u'Temperature [°C]',
                                      plots,
                                      extra_key_widgets=[self.error_label])

        self.averaging_label = QLabel('Averaging:')
        self.averaging_combo = QComboBox()
        self.averaging_combo.addItem('1', BrickletThermocouple.AVERAGING_1)
        self.averaging_combo.addItem('2', BrickletThermocouple.AVERAGING_2)
        self.averaging_combo.addItem('4', BrickletThermocouple.AVERAGING_4)
        self.averaging_combo.addItem('8', BrickletThermocouple.AVERAGING_8)
        self.averaging_combo.addItem('16', BrickletThermocouple.AVERAGING_16)

        self.type_label = QLabel('Thermocouple Type:')
        self.type_combo = QComboBox()
        self.type_combo.addItem('B', BrickletThermocouple.TYPE_B)
        self.type_combo.addItem('E', BrickletThermocouple.TYPE_E)
        self.type_combo.addItem('J', BrickletThermocouple.TYPE_J)
        self.type_combo.addItem('K', BrickletThermocouple.TYPE_K)
        self.type_combo.addItem('N', BrickletThermocouple.TYPE_N)
        self.type_combo.addItem('R', BrickletThermocouple.TYPE_R)
        self.type_combo.addItem('S', BrickletThermocouple.TYPE_S)
        self.type_combo.addItem('T', BrickletThermocouple.TYPE_T)
        self.type_combo.addItem('Gain 8', BrickletThermocouple.TYPE_G8)
        self.type_combo.addItem('Gain 32', BrickletThermocouple.TYPE_G32)

        self.filter_label = QLabel('Noise Rejection Filter:')
        self.filter_combo = QComboBox()
        self.filter_combo.addItem('50 Hz',
                                  BrickletThermocouple.FILTER_OPTION_50HZ)
        self.filter_combo.addItem('60 Hz',
                                  BrickletThermocouple.FILTER_OPTION_60HZ)

        hlayout = QHBoxLayout()
        hlayout.addWidget(self.averaging_label)
        hlayout.addWidget(self.averaging_combo)
        hlayout.addStretch()
        hlayout.addWidget(self.type_label)
        hlayout.addWidget(self.type_combo)
        hlayout.addStretch()
        hlayout.addWidget(self.filter_label)
        hlayout.addWidget(self.filter_combo)

        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)

        layout = QVBoxLayout(self)
        layout.addWidget(self.plot_widget)
        layout.addWidget(line)
        layout.addLayout(hlayout)

        self.averaging_combo.currentIndexChanged.connect(
            self.configuration_changed)
        self.type_combo.currentIndexChanged.connect(self.configuration_changed)
        self.filter_combo.currentIndexChanged.connect(
            self.configuration_changed)

    def start(self):
        async_call(self.thermo.get_temperature, None, self.cb_temperature,
                   self.increase_error_count)
        async_call(self.thermo.get_configuration, None, self.cb_configuration,
                   self.increase_error_count)
        async_call(self.thermo.get_error_state, None,
                   lambda e: self.cb_error_state(e.over_under, e.open_circuit))
        self.cbe_temperature.set_period(100)

        self.plot_widget.stop = False

    def stop(self):
        self.cbe_temperature.set_period(0)

        self.plot_widget.stop = True

    def destroy(self):
        pass

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickletThermocouple.DEVICE_IDENTIFIER

    def get_current_value(self):
        return self.current_value

    def configuration_changed(self, _):
        conf_averaging = self.averaging_combo.itemData(
            self.averaging_combo.currentIndex())
        conf_type = self.type_combo.itemData(self.type_combo.currentIndex())
        conf_filter = self.filter_combo.itemData(
            self.filter_combo.currentIndex())

        self.thermo.set_configuration(conf_averaging, conf_type, conf_filter)

    def cb_temperature(self, temperature):
        self.current_temperature = temperature / 100.0

    def cb_configuration(self, conf):
        self.averaging_combo.blockSignals(True)
        self.averaging_combo.setCurrentIndex(
            self.averaging_combo.findData(conf.averaging))
        self.averaging_combo.blockSignals(False)

        self.type_combo.blockSignals(True)
        self.type_combo.setCurrentIndex(
            self.type_combo.findData(conf.thermocouple_type))
        self.type_combo.blockSignals(False)

        self.filter_combo.blockSignals(True)
        self.filter_combo.setCurrentIndex(
            self.filter_combo.findData(conf.filter))
        self.filter_combo.blockSignals(False)

    def cb_error_state(self, over_under, open_circuit):
        if over_under or open_circuit:
            text = 'Current Errors: '
            if over_under:
                text += 'Over/Under Voltage'
            if over_under and open_circuit:
                text += ' and '
            if open_circuit:
                text += 'Open Circuit\n(defective thermocouple or nothing connected)'

            self.error_label.setStyleSheet('QLabel { color : red }')
            self.error_label.setText(text)
        else:
            self.error_label.setStyleSheet('')
            self.error_label.setText('Current Errors: None')
예제 #16
0
class ActionBar(QFrame):
    """
    SIGNALS:
    @changeCurrent(PyQt_PyObject)
    @runFile(QString)
    @reopenTab(QString)
    @recentTabsModified()
    """
    def __init__(self, main_combo=False):
        super(ActionBar, self).__init__()
        self.setObjectName("actionbar")
        hbox = QHBoxLayout(self)
        hbox.setContentsMargins(1, 1, 1, 1)
        hbox.setSpacing(1)

        self.lbl_checks = QLabel('')
        self.lbl_checks.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.lbl_checks.setFixedWidth(48)
        self.lbl_checks.setVisible(False)
        hbox.addWidget(self.lbl_checks)

        self.combo = QComboBox()
        #model = QStandardItemModel()
        #self.combo.setModel(model)
        #self.combo.view().setDragDropMode(QAbstractItemView.InternalMove)
        self.combo.setMaximumWidth(300)
        self.combo.setObjectName("combotab")
        self.connect(self.combo, SIGNAL("currentIndexChanged(int)"),
                     self.current_changed)
        self.combo.setToolTip(translations.TR_COMBO_FILE_TOOLTIP)
        self.combo.setContextMenuPolicy(Qt.CustomContextMenu)
        self.connect(self.combo,
                     SIGNAL("customContextMenuRequested(const QPoint &)"),
                     self._context_menu_requested)
        hbox.addWidget(self.combo)

        self.symbols_combo = QComboBox()
        self.symbols_combo.setObjectName("combo_symbols")
        self.connect(self.symbols_combo, SIGNAL("activated(int)"),
                     self.current_symbol_changed)
        hbox.addWidget(self.symbols_combo)

        self.code_navigator = CodeNavigator()
        hbox.addWidget(self.code_navigator)

        self._pos_text = "Line: %d, Col: %d"
        self.lbl_position = QLabel(self._pos_text % (0, 0))
        self.lbl_position.setObjectName("position")
        self.lbl_position.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        hbox.addWidget(self.lbl_position)

        self.btn_close = QPushButton(
            self.style().standardIcon(QStyle.SP_DialogCloseButton), '')
        if main_combo:
            self.btn_close.setObjectName('navigation_button')
            self.btn_close.setToolTip(translations.TR_CLOSE_FILE)
            self.connect(self.btn_close, SIGNAL("clicked()"),
                         self.about_to_close_file)
        else:
            self.btn_close.setObjectName('close_split')
            self.btn_close.setToolTip(translations.TR_CLOSE_SPLIT)
            self.connect(self.btn_close, SIGNAL("clicked()"), self.close_split)
        self.btn_close.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        hbox.addWidget(self.btn_close)

    def resizeEvent(self, event):
        super(ActionBar, self).resizeEvent(event)
        if event.size().width() < 350:
            self.symbols_combo.hide()
            self.code_navigator.hide()
            self.lbl_position.hide()
        else:
            self.symbols_combo.show()
            self.code_navigator.show()
            self.lbl_position.show()

    def add_item(self, text, neditable):
        """Add a new item to the combo and add the neditable data."""
        self.combo.addItem(text, neditable)
        self.combo.setCurrentIndex(self.combo.count() - 1)

    def get_editables(self):
        editables = []
        for index in range(self.combo.count()):
            neditable = self.combo.itemData(index)
            editables.append(neditable)
        return editables

    def add_symbols(self, symbols):
        """Add the symbols to the symbols's combo."""
        self.symbols_combo.clear()
        for symbol in symbols:
            data = symbol[1]
            if data[1] == 'f':
                icon = QIcon(":img/function")
            else:
                icon = QIcon(":img/class")
            self.symbols_combo.addItem(icon, data[0])

    def set_current_symbol(self, index):
        self.symbols_combo.setCurrentIndex(index)

    def update_item_icon(self, neditable, icon):
        index = self.combo.findData(neditable)
        self.combo.setItemIcon(index, icon)

    def update_item_text(self, neditable, text):
        index = self.combo.findData(neditable)
        self.combo.setItemText(index, text)

    def current_changed(self, index):
        """Change the current item in the combo."""
        neditable = self.combo.itemData(index)
        self.emit(SIGNAL("changeCurrent(PyQt_PyObject, int)"), neditable,
                  index)

    def current_symbol_changed(self, index):
        """Change the current symbol in the combo."""
        self.emit(SIGNAL("goToSymbol(int)"), index)

    def update_line_col(self, line, col):
        """Update the line and column position."""
        self.lbl_position.setText(self._pos_text % (line, col))

    def _context_menu_requested(self, point):
        """Display context menu for the combo file."""
        if self.combo.count() == 0:
            # If there is not an Editor opened, don't show the menu
            return
        menu = QMenu()
        actionAdd = menu.addAction(translations.TR_ADD_TO_PROJECT)
        actionRun = menu.addAction(translations.TR_RUN_FILE)
        menuSyntax = menu.addMenu(translations.TR_CHANGE_SYNTAX)
        self._create_menu_syntax(menuSyntax)
        menu.addSeparator()
        actionClose = menu.addAction(translations.TR_CLOSE_FILE)
        actionCloseAll = menu.addAction(translations.TR_CLOSE_ALL_FILES)
        actionCloseAllNotThis = menu.addAction(
            translations.TR_CLOSE_OTHER_FILES)
        menu.addSeparator()
        actionSplitH = menu.addAction(translations.TR_SPLIT_VERTICALLY)
        actionSplitV = menu.addAction(translations.TR_SPLIT_HORIZONTALLY)
        menu.addSeparator()
        actionCopyPath = menu.addAction(
            translations.TR_COPY_FILE_PATH_TO_CLIPBOARD)
        actionReopen = menu.addAction(translations.TR_REOPEN_FILE)
        actionUndock = menu.addAction(translations.TR_UNDOCK_EDITOR)
        if len(settings.LAST_OPENED_FILES) == 0:
            actionReopen.setEnabled(False)
        #Connect actions
        self.connect(actionSplitH, SIGNAL("triggered()"),
                     lambda: self._split(False))
        self.connect(actionSplitV, SIGNAL("triggered()"),
                     lambda: self._split(True))
        self.connect(actionRun, SIGNAL("triggered()"), self._run_this_file)
        self.connect(actionAdd, SIGNAL("triggered()"), self._add_to_project)
        self.connect(actionClose, SIGNAL("triggered()"),
                     self.about_to_close_file)
        self.connect(actionCloseAllNotThis, SIGNAL("triggered()"),
                     self._close_all_files_except_this)
        self.connect(actionCloseAll, SIGNAL("triggered()"),
                     self._close_all_files)
        self.connect(actionCopyPath, SIGNAL("triggered()"),
                     self._copy_file_location)
        self.connect(actionReopen, SIGNAL("triggered()"),
                     self._reopen_last_tab)
        self.connect(actionUndock, SIGNAL("triggered()"), self._undock_editor)

        menu.exec_(QCursor.pos())

    def _create_menu_syntax(self, menuSyntax):
        """Create Menu with the list of syntax supported."""
        syntax = list(settings.SYNTAX.keys())
        syntax.sort()
        for syn in syntax:
            menuSyntax.addAction(syn)
            self.connect(menuSyntax, SIGNAL("triggered(QAction*)"),
                         self._reapply_syntax)

    def _reapply_syntax(self, syntaxAction):
        #TODO
        if [self.currentIndex(), syntaxAction] != self._resyntax:
            self._resyntax = [self.currentIndex(), syntaxAction]
            self.emit(SIGNAL("syntaxChanged(QWidget, QString)"),
                      self.currentWidget(), syntaxAction.text())

    def set_current_file(self, neditable):
        index = self.combo.findData(neditable)
        self.combo.setCurrentIndex(index)

    def set_current_by_index(self, index):
        self.combo.setCurrentIndex(index)

    def about_to_close_file(self, index=None):
        """Close the NFile object."""
        if index is None:
            index = self.combo.currentIndex()
        neditable = self.combo.itemData(index)
        if neditable:
            neditable.nfile.close()

    def close_split(self):
        self.emit(SIGNAL("closeSplit()"))

    def close_file(self, neditable):
        """Receive the confirmation to close the file."""
        index = self.combo.findData(neditable)
        self.combo.removeItem(index)
        return index

    def _run_this_file(self):
        """Execute the current file."""
        neditable = self.combo.itemData(self.combo.currentIndex())
        self.emit(SIGNAL("runFile(QString)"), neditable.file_path)

    def _add_to_project(self):
        """Emit a signal to let someone handle the inclusion of the file
        inside a project."""
        neditable = self.combo.itemData(self.combo.currentIndex())
        self.emit(SIGNAL("addToProject(QString)"), neditable.file_path)

    def _reopen_last_tab(self):
        self.emit(SIGNAL("reopenTab(QString)"),
                  settings.LAST_OPENED_FILES.pop())
        self.emit(SIGNAL("recentTabsModified()"))

    def _undock_editor(self):
        self.emit(SIGNAL("undockEditor()"))

    def _split(self, orientation):
        self.emit(SIGNAL("splitEditor(bool)"), orientation)

    def _copy_file_location(self):
        """Copy the path of the current opened file to the clipboard."""
        neditable = self.combo.itemData(self.combo.currentIndex())
        QApplication.clipboard().setText(neditable.file_path,
                                         QClipboard.Clipboard)

    def _close_all_files(self):
        """Close all the files opened."""
        for i in range(self.combo.count()):
            self.about_to_close_file(0)

    def _close_all_files_except_this(self):
        """Close all the files except the current one."""
        neditable = self.combo.itemData(self.combo.currentIndex())
        for i in reversed(list(range(self.combo.count()))):
            ne = self.combo.itemData(i)
            if ne is not neditable:
                self.about_to_close_file(i)
예제 #17
0
class AmbientLightV2(PluginBase):
    def __init__(self, *args):
        PluginBase.__init__(self, BrickletAmbientLightV2, *args)

        self.al = self.device

        self.has_clamped_output = self.firmware_version >= (2, 0, 2)

        self.cbe_illuminance = CallbackEmulator(self.al.get_illuminance,
                                                self.cb_illuminance,
                                                self.increase_error_count)

        self.illuminance_label = IlluminanceLabel('Illuminance: ')
        self.alf = AmbientLightFrame()
        self.out_of_range_label = QLabel('out-of-range')
        self.saturated_label = QLabel('sensor saturated')

        self.out_of_range_label.hide()
        self.out_of_range_label.setStyleSheet('QLabel { color: red }')
        self.saturated_label.hide()
        self.saturated_label.setStyleSheet('QLabel { color: magenta }')

        self.current_value = None

        plot_list = [['', Qt.red, self.get_current_value]]
        self.plot_widget = PlotWidget('Illuminance [lx]', plot_list)

        layout_h = QHBoxLayout()
        layout_h.addStretch()
        layout_h.addWidget(self.illuminance_label)
        layout_h.addWidget(self.out_of_range_label)
        layout_h.addWidget(self.saturated_label)
        layout_h.addWidget(self.alf)
        layout_h.addStretch()
        
        self.range_label = QLabel('Illuminance Range: ')
        self.range_combo = QComboBox()
        if self.has_clamped_output: # Also means that the unlimited range is available
            self.range_combo.addItem("Unlimited", BrickletAmbientLightV2.ILLUMINANCE_RANGE_UNLIMITED)
        self.range_combo.addItem("0 - 64000 Lux", BrickletAmbientLightV2.ILLUMINANCE_RANGE_64000LUX)
        self.range_combo.addItem("0 - 32000 Lux", BrickletAmbientLightV2.ILLUMINANCE_RANGE_32000LUX)
        self.range_combo.addItem("0 - 16000 Lux", BrickletAmbientLightV2.ILLUMINANCE_RANGE_16000LUX)
        self.range_combo.addItem("0 - 8000 Lux", BrickletAmbientLightV2.ILLUMINANCE_RANGE_8000LUX)
        self.range_combo.addItem("0 - 1300 Lux", BrickletAmbientLightV2.ILLUMINANCE_RANGE_1300LUX)
        self.range_combo.addItem("0 - 600 Lux", BrickletAmbientLightV2.ILLUMINANCE_RANGE_600LUX)
        self.range_combo.currentIndexChanged.connect(self.new_config)
        
        self.time_label = QLabel('Integration Time: ')
        self.time_combo = QComboBox()
        self.time_combo.addItem("50ms", BrickletAmbientLightV2.INTEGRATION_TIME_50MS)
        self.time_combo.addItem("100ms", BrickletAmbientLightV2.INTEGRATION_TIME_100MS)
        self.time_combo.addItem("150ms", BrickletAmbientLightV2.INTEGRATION_TIME_150MS)
        self.time_combo.addItem("200ms", BrickletAmbientLightV2.INTEGRATION_TIME_200MS)
        self.time_combo.addItem("250ms", BrickletAmbientLightV2.INTEGRATION_TIME_250MS)
        self.time_combo.addItem("300ms", BrickletAmbientLightV2.INTEGRATION_TIME_300MS)
        self.time_combo.addItem("350ms", BrickletAmbientLightV2.INTEGRATION_TIME_350MS)
        self.time_combo.addItem("400ms", BrickletAmbientLightV2.INTEGRATION_TIME_400MS)
        self.time_combo.currentIndexChanged.connect(self.new_config)
        
        layout_hc = QHBoxLayout()
        layout_hc.addStretch()
        layout_hc.addWidget(self.range_label)
        layout_hc.addWidget(self.range_combo)
        layout_hc.addStretch()
        layout_hc.addWidget(self.time_label)
        layout_hc.addWidget(self.time_combo)
        layout_hc.addStretch()

        layout = QVBoxLayout(self)
        layout.addLayout(layout_h)
        layout.addWidget(self.plot_widget)
        layout.addLayout(layout_hc)

    def start(self):
        async_call(self.al.get_configuration, None, self.get_configucation_async, self.increase_error_count)
        async_call(self.al.get_illuminance, None, self.cb_illuminance, self.increase_error_count)
        self.cbe_illuminance.set_period(100)

        self.plot_widget.stop = False

    def stop(self):
        self.cbe_illuminance.set_period(0)

        self.plot_widget.stop = True

    def destroy(self):
        pass

    def get_url_part(self):
        return 'ambient_light_v2'

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickletAmbientLightV2.DEVICE_IDENTIFIER
    
    def get_configucation_async(self, conf):
        self.range_combo.setCurrentIndex(self.range_combo.findData(conf.illuminance_range))
        self.time_combo.setCurrentIndex(self.time_combo.findData(conf.integration_time))
        
    def new_config(self, value):
        try:
            self.al.set_configuration(self.range_combo.itemData(self.range_combo.currentIndex()),
                                      self.time_combo.itemData(self.time_combo.currentIndex()))
        except:
            pass

    def get_current_value(self):
        return self.current_value

    def cb_illuminance(self, illuminance):
        self.current_value = illuminance/100.0
        self.illuminance_label.setText(illuminance)

        max_illuminance = 12000000 # Approximation for unlimited range
        current_range = self.range_combo.itemData(self.range_combo.currentIndex())
        if current_range == BrickletAmbientLightV2.ILLUMINANCE_RANGE_64000LUX:
            max_illuminance = 6400001
        elif current_range == BrickletAmbientLightV2.ILLUMINANCE_RANGE_32000LUX:
            max_illuminance = 3200001
        elif current_range == BrickletAmbientLightV2.ILLUMINANCE_RANGE_16000LUX:
            max_illuminance = 1600001
        elif current_range == BrickletAmbientLightV2.ILLUMINANCE_RANGE_8000LUX:
            max_illuminance = 800001
        elif current_range == BrickletAmbientLightV2.ILLUMINANCE_RANGE_1300LUX:
            max_illuminance = 130001
        elif current_range == BrickletAmbientLightV2.ILLUMINANCE_RANGE_600LUX:
            max_illuminance = 60001

        if self.has_clamped_output: # Also means that the unlimited range is available
            if illuminance == 0:
                self.illuminance_label.setStyleSheet('QLabel { color: magenta }')
                self.out_of_range_label.hide()
                self.saturated_label.show()
            elif illuminance >= max_illuminance:
                self.illuminance_label.setStyleSheet('QLabel { color: red }')
                self.out_of_range_label.show()
                self.saturated_label.hide()
            else:
                self.illuminance_label.setStyleSheet('')
                self.out_of_range_label.hide()
                self.saturated_label.hide()

        value = min(max(illuminance*255/max_illuminance, 0), 255)
        self.alf.set_color(value, value, value)
예제 #18
0
class UpdateIntervalDialog(QDialog):

    def __init__(self, parent, updater):

        QDialog.__init__(self, parent)

        self.updater = updater
        self.prop = MaeMoneyProperties.instance()
        self.setupUi()

    def setupUi(self):
        self.setWindowModality(Qt.WindowModal)

        self.layout = QVBoxLayout()
        self.setLayout(self.layout)

        self.btnPauseUpdate = QPushButton()
        self.setPauseUpdateButtonStatus()
        self.layout.addWidget(self.btnPauseUpdate)

        self.comboBoxUpdInterval = QComboBox()
        self.comboBoxUpdInterval.addItem(self.tr("Pause update"), 0)
        self.comboBoxUpdInterval.addItem(
                self.tr("Update interval - %1s").arg(Properties.DEFAULT_UPDATE_INTERVAL),
                Properties.DEFAULT_UPDATE_INTERVAL)
        self.comboBoxUpdInterval.addItem(self.tr("Update interval - 25s"), 25)
        self.comboBoxUpdInterval.addItem(self.tr("Update interval - 1 min"), 60)
        self.comboBoxUpdInterval.addItem(self.tr("Update interval - 5 min"), 5 * 60)
        self.comboBoxUpdInterval.addItem(self.tr("Update interval - 15 min"), 15 * 60)
        self.comboBoxUpdInterval.addItem(self.tr("Update interval - 30 min"), 30 * 60)
        self.comboBoxUpdInterval.addItem(self.tr("Update interval - 45 min"), 45 * 60)
        self.comboBoxUpdInterval.addItem(self.tr("Update interval - 1 hr"), 1 * 60 * 60)
        self.comboBoxUpdInterval.addItem(self.tr("Update interval - 2 hr"), 2 * 60 * 60)
        self.setCurrentComboBoxUpdInterval()
        self.setComboBoxStatus()
        self.layout.addWidget(self.comboBoxUpdInterval)

        self.btnBackToMainApp = QPushButton(self.tr("Back to Main Application"))
        self.layout.addWidget(self.btnBackToMainApp)

        self.setWindowTitle(self.tr("Update Interval"))

        self.connect(self.btnPauseUpdate, SIGNAL("clicked()"), self.pauseUpdate)
        self.connect(self.comboBoxUpdInterval, SIGNAL("activated(int)"), self.updateIntervalSelected)
        self.connect(self.btnBackToMainApp, SIGNAL("clicked()"), self.accept)

    def setCurrentComboBoxUpdInterval(self):
        curInterval = self.prop.getUpdateInterval()
        index = self.comboBoxUpdInterval.findData(curInterval)
        if index >= 0:
            self.comboBoxUpdInterval.setCurrentIndex(index)
        else:
            qWarning("Update interval of %ds is not available." %(curInterval))
            qWarning("Resetting to default of %ds" %(Properties.DEFAULT_UPDATE_INTERVAL))
            self.prop.setUpdateInterval(Properties.DEFAULT_UPDATE_INTERVAL)
            self.setCurrentComboBoxUpdInterval()

    def updateIntervalSelected(self, index):
        if self.updater is not None:
            intervalSelected = self.comboBoxUpdInterval.itemData(index).toInt()[0]
            self.prop.setUpdateInterval(intervalSelected)
            if intervalSelected == 0:
                self.pauseUpdate()
            else:
                self.updater.terminate()
                self.updater.start()
                self.updater.setUpdateInterval(intervalSelected)
                self.setPauseUpdateButtonStatus()

    def pauseUpdate(self):
        if self.updater is not None:
            self.updater.terminate()
            self.setPauseUpdateButtonStatus()
            pauseInterval = 0
            index = self.comboBoxUpdInterval.findData(pauseInterval)
            self.comboBoxUpdInterval.setCurrentIndex(index)
            self.prop.setUpdateInterval(pauseInterval)

    def setPauseUpdateButtonStatus(self):
        if self.btnPauseUpdate is not None:
            if self.updater is not None and self.updater.isRunning():
                self.btnPauseUpdate.setText(self.tr("Timer currently active. Click to pause update"))
                self.btnPauseUpdate.setEnabled(True)
            else:
                self.btnPauseUpdate.setText(self.tr("Update not running"))
                self.btnPauseUpdate.setEnabled(False)

    def setComboBoxStatus(self):
        if self.comboBoxUpdInterval is not None:
            if self.updater is None:
                self.comboBoxUpdInterval.setEnabled(False)
            else:
                self.comboBoxUpdInterval.setEnabled(True)
예제 #19
0
class BarometerV2(COMCUPluginBase):
    def __init__(self, *args):
        COMCUPluginBase.__init__(self, BrickletBarometerV2, *args)

        self.barometer = self.device

        self.cbe_air_pressure = CallbackEmulator(
            self.barometer.get_air_pressure, self.cb_get_air_pressure,
            self.increase_error_count)

        self.cbe_altitude = CallbackEmulator(self.barometer.get_altitude,
                                             self.cb_get_altitude,
                                             self.increase_error_count)

        self.cbe_temperature = CallbackEmulator(self.barometer.get_temperature,
                                                self.cb_get_temperature,
                                                self.increase_error_count)

        self.current_altitude = None
        self.current_temperature = None
        self.current_air_pressure = None

        self.calibration = None
        self.btn_clear_graphs = QPushButton('Clear Graphs')
        self.btn_calibration = QPushButton('Calibration...')
        self.btn_calibration.clicked.connect(self.btn_calibration_clicked)

        self.lbl_temperature_value = QLabel('-')

        self.sbox_reference_air_pressure = QDoubleSpinBox()
        self.sbox_reference_air_pressure.setMinimum(260)
        self.sbox_reference_air_pressure.setMaximum(1260)
        self.sbox_reference_air_pressure.setDecimals(3)
        self.sbox_reference_air_pressure.setValue(1013.25)
        self.sbox_reference_air_pressure.setSingleStep(1)
        self.btn_use_current = QPushButton('Use Current')
        self.btn_use_current.clicked.connect(self.btn_use_current_clicked)
        self.sbox_reference_air_pressure.editingFinished.connect(
            self.sbox_reference_air_pressure_editing_finished)

        self.sbox_moving_avg_len_air_pressure = QSpinBox()
        self.sbox_moving_avg_len_air_pressure.setMinimum(1)
        self.sbox_moving_avg_len_air_pressure.setMaximum(1000)
        self.sbox_moving_avg_len_air_pressure.setSingleStep(1)
        self.sbox_moving_avg_len_air_pressure.setValue(100)
        self.sbox_moving_avg_len_air_pressure.editingFinished.connect(
            self.sbox_moving_avg_len_editing_finished)

        self.sbox_moving_avg_len_temperature = QSpinBox()
        self.sbox_moving_avg_len_temperature.setMinimum(1)
        self.sbox_moving_avg_len_temperature.setMaximum(1000)
        self.sbox_moving_avg_len_temperature.setSingleStep(1)
        self.sbox_moving_avg_len_temperature.setValue(100)
        self.sbox_moving_avg_len_temperature.editingFinished.connect(
            self.sbox_moving_avg_len_editing_finished)

        plot_config_air_pressure = [
            ('Air Pressure', Qt.red, lambda: self.current_air_pressure,
             '{:.3f} mbar (QFE)'.format)
        ]

        plot_config_altitude = [(
            'Altitude', Qt.darkGreen, lambda: self.current_altitude,
            lambda value: '{:.3f} m ({:.3f} ft)'.format(value, value / 0.3048))
                                ]

        self.plot_widget_air_pressure = PlotWidget('Air Pressure [mbar]',
                                                   plot_config_air_pressure,
                                                   self.btn_clear_graphs)

        self.plot_widget_altitude = PlotWidget('Altitude [m]',
                                               plot_config_altitude,
                                               self.btn_clear_graphs)

        self.combo_data_rate = QComboBox()
        self.combo_data_rate.addItem('Off', BrickletBarometerV2.DATA_RATE_OFF)
        self.combo_data_rate.addItem('1 Hz', BrickletBarometerV2.DATA_RATE_1HZ)
        self.combo_data_rate.addItem('10 Hz',
                                     BrickletBarometerV2.DATA_RATE_10HZ)
        self.combo_data_rate.addItem('25 Hz',
                                     BrickletBarometerV2.DATA_RATE_25HZ)
        self.combo_data_rate.addItem('50 Hz',
                                     BrickletBarometerV2.DATA_RATE_50HZ)
        self.combo_data_rate.addItem('75 Hz',
                                     BrickletBarometerV2.DATA_RATE_75HZ)
        self.combo_data_rate.currentIndexChanged.connect(
            self.new_sensor_config)

        self.combo_air_pressure_low_pass_filter = QComboBox()
        self.combo_air_pressure_low_pass_filter.addItem(
            'Off', BrickletBarometerV2.LOW_PASS_FILTER_OFF)
        self.combo_air_pressure_low_pass_filter.addItem(
            '1/9th', BrickletBarometerV2.LOW_PASS_FILTER_1_9TH)
        self.combo_air_pressure_low_pass_filter.addItem(
            '1/20th', BrickletBarometerV2.LOW_PASS_FILTER_1_20TH)
        self.combo_air_pressure_low_pass_filter.currentIndexChanged.connect(
            self.new_sensor_config)

        # Layout
        layout_h1 = QHBoxLayout()
        layout_h1.addWidget(self.plot_widget_air_pressure)
        layout_h1.addWidget(self.plot_widget_altitude)

        layout = QVBoxLayout(self)
        layout.addLayout(layout_h1)

        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)

        layout.addWidget(line)

        layout_h2 = QHBoxLayout()
        layout_h2.addWidget(QLabel('Reference Air Pressure [mbar]:'))
        layout_h2.addWidget(self.sbox_reference_air_pressure)
        layout_h2.addWidget(self.btn_use_current)
        layout_h2.addStretch()
        layout_h2.addWidget(QLabel('Temperature:'))
        layout_h2.addWidget(self.lbl_temperature_value)
        layout_h2.addStretch()
        layout_h2.addWidget(self.btn_clear_graphs)

        layout.addLayout(layout_h2)

        layout_h3 = QHBoxLayout()
        layout_h3.addWidget(QLabel('Air Pressure Moving Average Length:'))
        layout_h3.addWidget(self.sbox_moving_avg_len_air_pressure)
        layout_h3.addStretch()
        layout_h3.addWidget(QLabel('Temperature Moving Average Length:'))
        layout_h3.addWidget(self.sbox_moving_avg_len_temperature)

        layout.addLayout(layout_h3)

        layout_h4 = QHBoxLayout()
        layout_h4.addWidget(QLabel('Data Rate:'))
        layout_h4.addWidget(self.combo_data_rate)
        layout_h4.addStretch()
        layout_h4.addWidget(QLabel('Air Pressure Low Pass Filter:'))
        layout_h4.addWidget(self.combo_air_pressure_low_pass_filter)
        layout_h4.addStretch()
        layout_h4.addWidget(self.btn_calibration)

        layout.addLayout(layout_h4)

    def start(self):
        async_call(self.barometer.get_air_pressure, None,
                   self.cb_get_air_pressure, self.increase_error_count)

        async_call(self.barometer.get_altitude, None, self.cb_get_altitude,
                   self.increase_error_count)

        async_call(self.barometer.get_temperature, None,
                   self.cb_get_temperature, self.increase_error_count)

        async_call(self.barometer.get_reference_air_pressure, None,
                   self.get_reference_air_pressure_async,
                   self.increase_error_count)

        async_call(self.barometer.get_moving_average_configuration, None,
                   self.get_moving_average_configuration_async,
                   self.increase_error_count)

        async_call(self.barometer.get_sensor_configuration, None,
                   self.get_sensor_configuration_async,
                   self.increase_error_count)

        self.cbe_air_pressure.set_period(50)
        self.cbe_altitude.set_period(50)
        self.cbe_temperature.set_period(100)

        self.plot_widget_air_pressure.stop = False
        self.plot_widget_altitude.stop = False

    def stop(self):
        self.cbe_air_pressure.set_period(0)
        self.cbe_altitude.set_period(0)
        self.cbe_temperature.set_period(0)

        self.plot_widget_air_pressure.stop = True
        self.plot_widget_altitude.stop = True

    def destroy(self):
        if self.calibration != None:
            self.calibration.close()

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickletBarometerV2.DEVICE_IDENTIFIER

    def cb_get_air_pressure(self, air_pressure):
        self.current_air_pressure = air_pressure / 1000.0

    def cb_get_altitude(self, altitude):
        self.current_altitude = altitude / 1000.0

    def cb_get_temperature(self, temperature):
        self.current_temperature = temperature / 100.0
        self.lbl_temperature_value.setText(u'{:.2f} °C'.format(
            self.current_temperature))

    def get_reference_air_pressure_async(self, air_pressure):
        self.sbox_reference_air_pressure.setValue(air_pressure / 1000.0)

    def btn_use_current_clicked(self):
        self.barometer.set_reference_air_pressure(0)
        async_call(self.barometer.get_reference_air_pressure, None,
                   self.get_reference_air_pressure_async,
                   self.increase_error_count)

    def sbox_reference_air_pressure_editing_finished(self):
        self.barometer.set_reference_air_pressure(
            self.sbox_reference_air_pressure.value() * 1000.0)

    def get_moving_average_configuration_async(self, avg):
        m_avg_air_pressure, m_avg_temperature = avg

        self.sbox_moving_avg_len_air_pressure.setValue(m_avg_air_pressure)
        self.sbox_moving_avg_len_temperature.setValue(m_avg_temperature)

    def sbox_moving_avg_len_editing_finished(self):
        self.barometer.set_moving_average_configuration(
            self.sbox_moving_avg_len_air_pressure.value(),
            self.sbox_moving_avg_len_temperature.value())

    def get_sensor_configuration_async(self, config):
        data_rate, air_pressure_low_pass_filter = config

        self.combo_data_rate.setCurrentIndex(
            self.combo_data_rate.findData(data_rate))
        self.combo_air_pressure_low_pass_filter.setCurrentIndex(
            self.combo_air_pressure_low_pass_filter.findData(
                air_pressure_low_pass_filter))

    def new_sensor_config(self):
        data_rate = self.combo_data_rate.itemData(
            self.combo_data_rate.currentIndex())
        air_pressure_low_pass_filter = self.combo_air_pressure_low_pass_filter.itemData(
            self.combo_air_pressure_low_pass_filter.currentIndex())

        self.barometer.set_sensor_configuration(data_rate,
                                                air_pressure_low_pass_filter)

    def btn_calibration_clicked(self):
        if self.calibration == None:
            self.calibration = Calibration(self)

        self.btn_calibration.setEnabled(False)
        self.calibration.show()
예제 #20
0
class AnalogIn(PluginBase):
    def __init__(self, *args):
        PluginBase.__init__(self, BrickletAnalogIn, *args)

        self.ai = self.device

        self.cbe_voltage = CallbackEmulator(self.ai.get_voltage,
                                            self.cb_voltage,
                                            self.increase_error_count)

        self.current_voltage = None  # float, V

        plots = [('Voltage', Qt.red, lambda: self.current_voltage,
                  format_voltage)]
        self.plot_widget = PlotWidget('Voltage [V]', plots)

        layout = QVBoxLayout(self)
        layout.addWidget(self.plot_widget)

        if self.firmware_version >= (2, 0, 1):
            self.combo_range = QComboBox()
            self.combo_range.addItem('Automatic',
                                     BrickletAnalogIn.RANGE_AUTOMATIC)
            if self.firmware_version >= (2, 0, 3):
                self.combo_range.addItem('0 - 3.30 V',
                                         BrickletAnalogIn.RANGE_UP_TO_3V)
            self.combo_range.addItem('0 - 6.05 V',
                                     BrickletAnalogIn.RANGE_UP_TO_6V)
            self.combo_range.addItem('0 - 10.32 V',
                                     BrickletAnalogIn.RANGE_UP_TO_10V)
            self.combo_range.addItem('0 - 36.30 V',
                                     BrickletAnalogIn.RANGE_UP_TO_36V)
            self.combo_range.addItem('0 - 45.00 V',
                                     BrickletAnalogIn.RANGE_UP_TO_45V)
            self.combo_range.currentIndexChanged.connect(self.range_changed)

            hlayout = QHBoxLayout()
            hlayout.addWidget(QLabel('Range:'))
            hlayout.addWidget(self.combo_range)
            hlayout.addStretch()

            if self.firmware_version >= (2, 0, 3):
                self.spin_average = QSpinBox()
                self.spin_average.setMinimum(0)
                self.spin_average.setMaximum(255)
                self.spin_average.setSingleStep(1)
                self.spin_average.setValue(50)
                self.spin_average.editingFinished.connect(
                    self.spin_average_finished)

                hlayout.addWidget(QLabel('Average Length:'))
                hlayout.addWidget(self.spin_average)

            line = QFrame()
            line.setFrameShape(QFrame.HLine)
            line.setFrameShadow(QFrame.Sunken)

            layout.addWidget(line)
            layout.addLayout(hlayout)

    def get_range_async(self, range_):
        self.combo_range.setCurrentIndex(self.combo_range.findData(range_))

    def get_averaging_async(self, average):
        self.spin_average.setValue(average)

    def start(self):
        if self.firmware_version >= (2, 0, 1):
            async_call(self.ai.get_range, None, self.get_range_async,
                       self.increase_error_count)

            if self.firmware_version >= (2, 0, 3):
                async_call(self.ai.get_averaging, None,
                           self.get_averaging_async, self.increase_error_count)

        async_call(self.ai.get_voltage, None, self.cb_voltage,
                   self.increase_error_count)

        self.cbe_voltage.set_period(100)

        self.plot_widget.stop = False

    def stop(self):
        self.cbe_voltage.set_period(0)

        self.plot_widget.stop = True

    def destroy(self):
        pass

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickletAnalogIn.DEVICE_IDENTIFIER

    def cb_voltage(self, voltage):
        self.current_voltage = voltage / 1000.0

    def range_changed(self, index):
        if index >= 0 and self.firmware_version >= (2, 0, 1):
            range_ = self.combo_range.itemData(index)
            async_call(self.ai.set_range, range_, None,
                       self.increase_error_count)

    def spin_average_finished(self):
        self.ai.set_averaging(self.spin_average.value())
예제 #21
0
class AnalogIn(PluginBase):
    def __init__(self, *args):
        PluginBase.__init__(self, BrickletAnalogIn, *args)

        self.ai = self.device

        self.cbe_voltage = CallbackEmulator(self.ai.get_voltage,
                                            self.cb_voltage,
                                            self.increase_error_count)

        self.voltage_label = VoltageLabel('Voltage: ')

        self.current_value = None

        plot_list = [['', Qt.red, self.get_current_value]]
        self.plot_widget = PlotWidget('Voltage [mV]', plot_list)

        layout_h2 = QHBoxLayout()
        layout_h2.addStretch()
        layout_h2.addWidget(self.voltage_label)
        layout_h2.addStretch()

        layout = QVBoxLayout(self)
        layout.addLayout(layout_h2)
        layout.addWidget(self.plot_widget)

        if self.firmware_version >= (2, 0, 1):
            self.combo_range = QComboBox()
            self.combo_range.addItem('Automatic',
                                     BrickletAnalogIn.RANGE_AUTOMATIC)
            if self.firmware_version >= (2, 0, 3):
                self.combo_range.addItem('0V - 3.30V',
                                         BrickletAnalogIn.RANGE_UP_TO_3V)
            self.combo_range.addItem('0V - 6.05V',
                                     BrickletAnalogIn.RANGE_UP_TO_6V)
            self.combo_range.addItem('0V - 10.32V',
                                     BrickletAnalogIn.RANGE_UP_TO_10V)
            self.combo_range.addItem('0V - 36.30V',
                                     BrickletAnalogIn.RANGE_UP_TO_36V)
            self.combo_range.addItem('0V - 45.00V',
                                     BrickletAnalogIn.RANGE_UP_TO_45V)
            self.combo_range.currentIndexChanged.connect(self.range_changed)

            layout_h1 = QHBoxLayout()
            layout_h1.addStretch()
            layout_h1.addWidget(QLabel('Range:'))
            layout_h1.addWidget(self.combo_range)

            if self.firmware_version >= (2, 0, 3):
                self.spin_average = QSpinBox()
                self.spin_average.setMinimum(0)
                self.spin_average.setMaximum(255)
                self.spin_average.setSingleStep(1)
                self.spin_average.setValue(50)
                self.spin_average.editingFinished.connect(
                    self.spin_average_finished)

                layout_h1.addStretch()
                layout_h1.addWidget(QLabel('Average Length:'))
                layout_h1.addWidget(self.spin_average)

            layout_h1.addStretch()
            layout.addLayout(layout_h1)

    def get_range_async(self, range_):
        self.combo_range.setCurrentIndex(self.combo_range.findData(range_))

    def get_averaging_async(self, average):
        self.spin_average.setValue(average)

    def start(self):
        if self.firmware_version >= (2, 0, 1):
            async_call(self.ai.get_range, None, self.get_range_async,
                       self.increase_error_count)
        if self.firmware_version >= (2, 0, 3):
            async_call(self.ai.get_averaging, None, self.get_averaging_async,
                       self.increase_error_count)
        async_call(self.ai.get_voltage, None, self.cb_voltage,
                   self.increase_error_count)
        self.cbe_voltage.set_period(100)

        self.plot_widget.stop = False

    def stop(self):
        self.cbe_voltage.set_period(0)

        self.plot_widget.stop = True

    def destroy(self):
        pass

    def get_url_part(self):
        return 'analog_in'

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickletAnalogIn.DEVICE_IDENTIFIER

    def get_current_value(self):
        return self.current_value

    def cb_voltage(self, voltage):
        self.current_value = voltage
        self.voltage_label.setText(str(voltage / 1000.0))

    def range_changed(self, index):
        if index >= 0 and self.firmware_version >= (2, 0, 1):
            range_ = self.combo_range.itemData(index)
            async_call(self.ai.set_range, range_, None,
                       self.increase_error_count)

    def spin_average_finished(self):
        self.ai.set_averaging(self.spin_average.value())
예제 #22
0
class QualityDialog(QDialog):
    def __init__(self, parent, params):

        QDialog.__init__(self, parent)

        self.parent = parent
        self.params = params

        self.setMinimumWidth(min_width)
        # self.setMinimumHeight(min_height)

        # Build dialog
        self.setWindowTitle('Options - Quality')  # TODO: softcode
        self.setWindowModality(QtCore.Qt.ApplicationModal)

        self.fra_form = QFrame(self)
        fra_form_lay = QFormLayout(self.fra_form)
        fra_form_lay.setContentsMargins(10, 10, 10, 10)

        self.lbl_parameter = QLabel('Parameter:')  # TODO: softocode
        self.cbo_parameter = QComboBox()
        fra_form_lay.addRow(self.lbl_parameter, self.cbo_parameter)

        self.lbl_mass_units = QLabel('Mass units:')  # TODO: softocode
        self.cbo_mass_units = QComboBox()
        fra_form_lay.addRow(self.lbl_mass_units, self.cbo_mass_units)

        self.lbl_rel_diff = QLabel('Relative diffusivity:')  # TODO: softocode
        self.txt_rel_diff = QLineEdit()
        fra_form_lay.addRow(self.lbl_rel_diff, self.txt_rel_diff)

        self.lbl_trace_node = QLabel('Trace node:')  # TODO: softocode
        self.txt_trace_node = QLineEdit()
        fra_form_lay.addRow(self.lbl_trace_node, self.txt_trace_node)

        self.lbl_quality_tol = QLabel('Quality tolerance:')  # TODO: softocode
        self.txt_quality_tol = QLineEdit()
        fra_form_lay.addRow(self.lbl_quality_tol, self.txt_quality_tol)

        # Buttons
        self.fra_buttons = QFrame(self)
        fra_buttons_lay = QHBoxLayout(self.fra_buttons)
        self.btn_Ok = QPushButton('OK')
        self.btn_Cancel = QPushButton('Cancel')
        fra_buttons_lay.addWidget(self.btn_Ok)
        fra_buttons_lay.addWidget(self.btn_Cancel)

        # Add to main
        fra_main_lay = QVBoxLayout(self)
        fra_main_lay.setContentsMargins(0, 0, 0, 0)
        fra_main_lay.addWidget(self.fra_form)
        fra_main_lay.addWidget(self.fra_buttons)

        self.setup()

    def setup(self):
        for key, value in self.params.options.quality.quality_text.iteritems():
            self.cbo_parameter.addItem(value, key)

        for key, value in self.params.options.quality.quality_units_text.iteritems(
        ):
            self.cbo_mass_units.addItem(value, key)

        # Buttons
        self.btn_Cancel.clicked.connect(self.btn_cancel_clicked)
        self.btn_Ok.clicked.connect(self.btn_ok_clicked)

        # Validators
        self.txt_rel_diff.setValidator(RegExValidators.get_pos_decimals())
        self.txt_quality_tol.setValidator(RegExValidators.get_pos_decimals())

    def show(self):
        super(QualityDialog, self).show()

        self.cbo_parameter.setCurrentIndex(
            self.cbo_parameter.findData(self.params.options.quality.parameter))
        self.cbo_mass_units.setCurrentIndex(
            self.cbo_mass_units.findData(
                self.params.options.quality.mass_units))
        self.txt_rel_diff.setText(
            str(self.params.options.quality.relative_diff))
        self.txt_trace_node.setText(
            str(self.params.options.quality.trace_junction_id))
        self.txt_quality_tol.setText(
            str(self.params.options.quality.quality_tol))

    def btn_cancel_clicked(self):
        self.setVisible(False)

    def btn_ok_clicked(self):

        # Update parameters and options
        self.params.options.quality.parameter = self.cbo_parameter.itemData(
            self.cbo_parameter.currentIndex())
        self.params.options.quality.mass_units = self.cbo_mass_units.itemData(
            self.cbo_mass_units.currentIndex())

        self.params.options.quality.relative_diff = float(
            self.txt_rel_diff.text())
        self.params.options.quality.trace_junction_id = self.txt_trace_node.text(
        )
        self.params.options.quality.quality_tol = float(
            self.txt_quality_tol.text())

        self.setVisible(False)
예제 #23
0
파일: config.py 프로젝트: maximerobin/Ufwi
class ConfigPage(QWizardPage):
    def __init__(self, parent):
        QWizardPage.__init__(self, parent)
        layout = QFormLayout(self)

        config = QHAObject.getInstance().hacfg

        self.setTitle(tr("High Availability Configuration"))

        self.ha_type = QComboBox() # primary / secondary
        self.ha_type.addItem(tr('Disabled'), QVariant(ENOHA))
        self.ha_type.addItem(tr('Primary'), QVariant(PENDING_PRIMARY))
        self.ha_type.addItem(tr('Secondary'), QVariant(PENDING_SECONDARY))
        index = self.ha_type.findData(QVariant(config.ha_type))
        self.ha_type.setCurrentIndex(index)

        layout.addRow(tr('Status of this cluster member:'), self.ha_type)
        self.registerField('type', self.ha_type)

        self.interface = InterfaceChoice(self.selectInterface, self)
        self.label_interface = QLabel(tr('Interface'))
        layout.addRow(self.label_interface, self.interface)
        self.registerField('interface', self.interface)

        self.connect(self.ha_type, SIGNAL('currentIndexChanged(int)'), self.toggleType)
        self.toggleType(index)

        if config.ha_type != ENOHA:
            message = tr("'%s' already configured as '%s'.") % (config.interface_id,
                config.ha_type)
            message += '<br />'
            message += tr("The configuration for this interface will be cleared.")

            warning_message = MessageArea()
            warning_message.setMessage(tr("Warning"), message,
                status=MessageArea.WARNING)
            layout.addRow(warning_message)

    def selectInterface(self, interface):
        return interface.canReserve() or interface.hasHA()

    def toggleType(self, index):
        selected_type = self.ha_type.itemData(index)
        self.interface.setVisible(selected_type.toString() != ENOHA)
        self.label_interface.setVisible(selected_type.toString() != ENOHA)

    def validatePage(self):
        type_index, is_ok = self.field('type').toInt()
        ha_type = unicode(self.ha_type.itemData(type_index).toString())

        if QHAObject.getInstance().cfg.ha_type == SECONDARY and ha_type == ENOHA:
            #SECONDARY -> ENOHA is forbidden
            #when PRIMARY, this wizard is not even displayed
            QMessageBox.warning(self,
                tr('Invalid configuration'),
                tr(
                    "In order to fully deconfigure high availability, you "
                    "need to restore this appliance to factory defaults."
                )
                )
            return False

        if ha_type != ENOHA:
            net_cfg = QNetObject.getInstance().netcfg
            iface = self.interface.getInterface()
            iface_id = net_cfg.getHardLabel(iface)
            iface_name = iface.system_name
        else:
            iface_id = None
            iface_name = None
        config = HAConf(ha_type=ha_type, interface_id=iface_id, interface_name=iface_name)
        msg = config.isValidWithMsg()
        if msg is None:
            self.config = config
        else:
            QMessageBox.warning(self, tr('Invalid configuration'), msg[0] % msg[1:])
        if msg is not None:
            return False

        if ha_type != PENDING_PRIMARY:
            return True

        user_valid = QMessageBox.question(
                self,
                tr("Configuring primary appliance. Are you sure?"),
                "<div>%s<br/>%s<br/>%s<br/>%s</div>" % (
                    tr(
                        "After this configuration step, <b>you will not be able to "
                        "change the hostname anymore.</b>"
                      ),
                    tr(
                        "Abort now, or reject the saved configuration if you "
                        "need to change the hostname."
                      ),
                    tr("The hostname is currently <i><b>'%(HOSTNAME)s'</b></i>"
                      ) % {'HOSTNAME': QHostnameObject.getInstance().cfg.hostname},
                    tr("Do you want to continue?"),
                    ),
                QMessageBox.Yes | QMessageBox.Abort
                )

        return user_valid == QMessageBox.Yes

    def getData(self):
        return self.config
예제 #24
0
class ReportDialog(QDialog):
    def __init__(self, parent, params):

        QDialog.__init__(self, parent)

        self.parent = parent
        self.params = params

        self.setMinimumWidth(min_width)
        # self.setMinimumHeight(min_height)

        # Build dialog
        self.setWindowTitle('Options - Report')  # TODO: softcode
        self.setWindowModality(QtCore.Qt.ApplicationModal)

        self.fra_form = QFrame(self)
        fra_form_lay = QFormLayout(self.fra_form)
        fra_form_lay.setContentsMargins(10, 10, 10, 10)

        self.lbl_status = QLabel('Hydraulic status:')  # TODO: softocode
        self.cbo_status = QComboBox()
        fra_form_lay.addRow(self.lbl_status, self.cbo_status)

        self.lbl_summary = QLabel('Summary')  # TODO: softocode
        self.cbo_summary = QComboBox()
        fra_form_lay.addRow(self.lbl_summary, self.cbo_summary)

        self.lbl_energy = QLabel('Energy')  # TODO: softocode
        self.cbo_energy = QComboBox()
        fra_form_lay.addRow(self.lbl_energy, self.cbo_energy)

        self.lbl_nodes = QLabel('Nodes')  # TODO: softocode
        self.cbo_nodes = QComboBox()
        fra_form_lay.addRow(self.lbl_nodes, self.cbo_nodes)

        self.lbl_links = QLabel('Links')  # TODO: softocode
        self.cbo_links = QComboBox()
        fra_form_lay.addRow(self.lbl_links, self.cbo_links)

        # Buttons
        self.fra_buttons = QFrame(self)
        fra_buttons_lay = QHBoxLayout(self.fra_buttons)
        self.btn_Ok = QPushButton('OK')
        self.btn_Cancel = QPushButton('Cancel')
        fra_buttons_lay.addWidget(self.btn_Ok)
        fra_buttons_lay.addWidget(self.btn_Cancel)

        # Add to main
        fra_main_lay = QVBoxLayout(self)
        fra_main_lay.setContentsMargins(0, 0, 0, 0)
        fra_main_lay.addWidget(self.fra_form)
        fra_main_lay.addWidget(self.fra_buttons)

        self.setup()

    def setup(self):

        # Combos
        for key, value in Report.status_names.iteritems():
            self.cbo_status.addItem(value, key)

        for key, value in Report.summary_names.iteritems():
            self.cbo_summary.addItem(value, key)

        for key, value in Report.energy_names.iteritems():
            self.cbo_energy.addItem(value, key)

        for key, value in Report.nodes_names.iteritems():
            self.cbo_nodes.addItem(value, key)

        for key, value in Report.links_names.iteritems():
            self.cbo_links.addItem(value, key)

        # Buttons
        self.btn_Cancel.clicked.connect(self.btn_cancel_clicked)
        self.btn_Ok.clicked.connect(self.btn_ok_clicked)

    def show(self):
        super(ReportDialog, self).show()
        self.cbo_status.setCurrentIndex(
            self.cbo_status.findData(self.params.report.status))
        self.cbo_summary.setCurrentIndex(
            self.cbo_summary.findData(self.params.report.summary))
        self.cbo_energy.setCurrentIndex(
            self.cbo_energy.findData(self.params.report.energy))
        self.cbo_nodes.setCurrentIndex(
            self.cbo_nodes.findData(self.params.report.nodes))
        self.cbo_links.setCurrentIndex(
            self.cbo_links.findData(self.params.report.links))

    def btn_cancel_clicked(self):
        self.setVisible(False)

    def btn_ok_clicked(self):

        self.params.report.status = self.cbo_status.itemData(
            self.cbo_status.currentIndex())
        self.params.report.summary = self.cbo_summary.itemData(
            self.cbo_summary.currentIndex())
        self.params.report.energy = self.cbo_energy.itemData(
            self.cbo_energy.currentIndex())
        self.params.report.nodes = self.cbo_nodes.itemData(
            self.cbo_nodes.currentIndex())
        self.params.report.links = self.cbo_links.itemData(
            self.cbo_links.currentIndex())

        self.setVisible(False)
예제 #25
0
class AmbientLightV2(PluginBase):
    def __init__(self, *args):
        PluginBase.__init__(self, BrickletAmbientLightV2, *args)

        self.al = self.device

        self.has_clamped_output = self.firmware_version >= (2, 0, 2)

        self.cbe_illuminance = CallbackEmulator(self.al.get_illuminance, self.cb_illuminance, self.increase_error_count)

        self.alf = AmbientLightFrame()
        self.out_of_range_label = QLabel("Illuminance is out-of-range")
        self.saturated_label = QLabel("Sensor is saturated")

        self.out_of_range_label.hide()
        self.out_of_range_label.setStyleSheet("QLabel { color: red }")
        self.saturated_label.hide()
        self.saturated_label.setStyleSheet("QLabel { color: magenta }")

        self.current_illuminance = None  # float, lx

        plots = [("Illuminance", Qt.red, lambda: self.current_illuminance, "{:.2f} lx (Lux)".format)]
        self.plot_widget = PlotWidget(
            "Illuminance [lx]", plots, extra_key_widgets=[self.out_of_range_label, self.saturated_label, self.alf]
        )

        self.range_label = QLabel("Illuminance Range: ")
        self.range_combo = QComboBox()
        if self.has_clamped_output:  # Also means that the unlimited range is available
            self.range_combo.addItem("Unlimited", BrickletAmbientLightV2.ILLUMINANCE_RANGE_UNLIMITED)
        self.range_combo.addItem("0 - 64000 lx", BrickletAmbientLightV2.ILLUMINANCE_RANGE_64000LUX)
        self.range_combo.addItem("0 - 32000 lx", BrickletAmbientLightV2.ILLUMINANCE_RANGE_32000LUX)
        self.range_combo.addItem("0 - 16000 lx", BrickletAmbientLightV2.ILLUMINANCE_RANGE_16000LUX)
        self.range_combo.addItem("0 - 8000 lx", BrickletAmbientLightV2.ILLUMINANCE_RANGE_8000LUX)
        self.range_combo.addItem("0 - 1300 lx", BrickletAmbientLightV2.ILLUMINANCE_RANGE_1300LUX)
        self.range_combo.addItem("0 - 600 lx", BrickletAmbientLightV2.ILLUMINANCE_RANGE_600LUX)
        self.range_combo.currentIndexChanged.connect(self.new_config)

        self.time_label = QLabel("Integration Time: ")
        self.time_combo = QComboBox()
        self.time_combo.addItem("50 ms", BrickletAmbientLightV2.INTEGRATION_TIME_50MS)
        self.time_combo.addItem("100 ms", BrickletAmbientLightV2.INTEGRATION_TIME_100MS)
        self.time_combo.addItem("150 ms", BrickletAmbientLightV2.INTEGRATION_TIME_150MS)
        self.time_combo.addItem("200 ms", BrickletAmbientLightV2.INTEGRATION_TIME_200MS)
        self.time_combo.addItem("250 ms", BrickletAmbientLightV2.INTEGRATION_TIME_250MS)
        self.time_combo.addItem("300 ms", BrickletAmbientLightV2.INTEGRATION_TIME_300MS)
        self.time_combo.addItem("350 ms", BrickletAmbientLightV2.INTEGRATION_TIME_350MS)
        self.time_combo.addItem("400 ms", BrickletAmbientLightV2.INTEGRATION_TIME_400MS)
        self.time_combo.currentIndexChanged.connect(self.new_config)

        hlayout = QHBoxLayout()
        hlayout.addWidget(self.range_label)
        hlayout.addWidget(self.range_combo)
        hlayout.addStretch()
        hlayout.addWidget(self.time_label)
        hlayout.addWidget(self.time_combo)

        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)

        layout = QVBoxLayout(self)
        layout.addWidget(self.plot_widget)
        layout.addWidget(line)
        layout.addLayout(hlayout)

    def start(self):
        async_call(self.al.get_configuration, None, self.get_configucation_async, self.increase_error_count)
        async_call(self.al.get_illuminance, None, self.cb_illuminance, self.increase_error_count)
        self.cbe_illuminance.set_period(100)

        self.plot_widget.stop = False

    def stop(self):
        self.cbe_illuminance.set_period(0)

        self.plot_widget.stop = True

    def destroy(self):
        pass

    def get_url_part(self):
        return "ambient_light_v2"

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickletAmbientLightV2.DEVICE_IDENTIFIER

    def get_configucation_async(self, conf):
        self.range_combo.setCurrentIndex(self.range_combo.findData(conf.illuminance_range))
        self.time_combo.setCurrentIndex(self.time_combo.findData(conf.integration_time))

    def new_config(self, value):
        try:
            self.al.set_configuration(
                self.range_combo.itemData(self.range_combo.currentIndex()),
                self.time_combo.itemData(self.time_combo.currentIndex()),
            )
        except:
            pass

    def cb_illuminance(self, illuminance):
        self.current_illuminance = illuminance / 100.0

        max_illuminance = 12000000  # Approximation for unlimited range
        current_range = self.range_combo.itemData(self.range_combo.currentIndex())
        if current_range == BrickletAmbientLightV2.ILLUMINANCE_RANGE_64000LUX:
            max_illuminance = 6400001
        elif current_range == BrickletAmbientLightV2.ILLUMINANCE_RANGE_32000LUX:
            max_illuminance = 3200001
        elif current_range == BrickletAmbientLightV2.ILLUMINANCE_RANGE_16000LUX:
            max_illuminance = 1600001
        elif current_range == BrickletAmbientLightV2.ILLUMINANCE_RANGE_8000LUX:
            max_illuminance = 800001
        elif current_range == BrickletAmbientLightV2.ILLUMINANCE_RANGE_1300LUX:
            max_illuminance = 130001
        elif current_range == BrickletAmbientLightV2.ILLUMINANCE_RANGE_600LUX:
            max_illuminance = 60001

        if self.has_clamped_output:  # Also means that the unlimited range is available
            if illuminance == 0:
                self.plot_widget.get_key_item(0).setStyleSheet("QLabel { color: magenta }")
                self.out_of_range_label.hide()
                self.saturated_label.show()
            elif illuminance >= max_illuminance:
                self.plot_widget.get_key_item(0).setStyleSheet("QLabel { color: red }")
                self.out_of_range_label.show()
                self.saturated_label.hide()
            else:
                self.plot_widget.get_key_item(0).setStyleSheet("")
                self.out_of_range_label.hide()
                self.saturated_label.hide()

        value = min(max(illuminance * 255 / max_illuminance, 0), 255)
        self.alf.set_color(value, value, value)
예제 #26
0
class ActionBar(QFrame):
    """
    SIGNALS:
    @changeCurrent(PyQt_PyObject)
    @runFile(QString)
    @reopenTab(QString)
    @recentTabsModified()
    """

    def __init__(self, main_combo=False):
        super(ActionBar, self).__init__()
        self.setObjectName("actionbar")
        hbox = QHBoxLayout(self)
        hbox.setContentsMargins(1, 1, 1, 1)
        hbox.setSpacing(1)

        self.lbl_checks = QLabel('')
        self.lbl_checks.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.lbl_checks.setFixedWidth(48)
        self.lbl_checks.setVisible(False)
        hbox.addWidget(self.lbl_checks)

        self.combo = QComboBox()
        self.combo.setIconSize(QSize(16, 16))
        #model = QStandardItemModel()
        #self.combo.setModel(model)
        #self.combo.view().setDragDropMode(QAbstractItemView.InternalMove)
        self.combo.setMaximumWidth(300)
        self.combo.setObjectName("combotab")
        self.connect(self.combo, SIGNAL("currentIndexChanged(int)"),
            self.current_changed)
        self.combo.setToolTip(translations.TR_COMBO_FILE_TOOLTIP)
        self.combo.setContextMenuPolicy(Qt.CustomContextMenu)
        self.connect(self.combo, SIGNAL(
            "customContextMenuRequested(const QPoint &)"),
            self._context_menu_requested)
        hbox.addWidget(self.combo)

        self.symbols_combo = QComboBox()
        self.symbols_combo.setIconSize(QSize(16, 16))
        self.symbols_combo.setObjectName("combo_symbols")
        self.connect(self.symbols_combo, SIGNAL("activated(int)"),
            self.current_symbol_changed)
        hbox.addWidget(self.symbols_combo)

        self.code_navigator = CodeNavigator()
        hbox.addWidget(self.code_navigator)

        self._pos_text = "Line: %d, Col: %d"
        self.lbl_position = QLabel(self._pos_text % (0, 0))
        self.lbl_position.setObjectName("position")
        self.lbl_position.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        hbox.addWidget(self.lbl_position)

        self.btn_close = QPushButton(
            self.style().standardIcon(QStyle.SP_DialogCloseButton), '')
        self.btn_close.setIconSize(QSize(16, 16))
        if main_combo:
            self.btn_close.setObjectName('navigation_button')
            self.btn_close.setToolTip(translations.TR_CLOSE_FILE)
            self.connect(self.btn_close, SIGNAL("clicked()"),
                self.about_to_close_file)
        else:
            self.btn_close.setObjectName('close_split')
            self.btn_close.setToolTip(translations.TR_CLOSE_SPLIT)
            self.connect(self.btn_close, SIGNAL("clicked()"),
                self.close_split)
        self.btn_close.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        hbox.addWidget(self.btn_close)

    def resizeEvent(self, event):
        super(ActionBar, self).resizeEvent(event)
        if event.size().width() < 350:
            self.symbols_combo.hide()
            self.code_navigator.hide()
            self.lbl_position.hide()
        else:
            self.symbols_combo.show()
            self.code_navigator.show()
            self.lbl_position.show()

    def add_item(self, text, neditable):
        """Add a new item to the combo and add the neditable data."""
        self.combo.addItem(text, neditable)
        self.combo.setCurrentIndex(self.combo.count() - 1)

    def get_editables(self):
        editables = []
        for index in range(self.combo.count()):
            neditable = self.combo.itemData(index)
            editables.append(neditable)
        return editables

    def add_symbols(self, symbols):
        """Add the symbols to the symbols's combo."""
        self.symbols_combo.clear()
        for symbol in symbols:
            data = symbol[1]
            if data[1] == 'f':
                icon = QIcon(":img/function")
            else:
                icon = QIcon(":img/class")
            self.symbols_combo.addItem(icon, data[0])

    def set_current_symbol(self, index):
        self.symbols_combo.setCurrentIndex(index)

    def update_item_icon(self, neditable, icon):
        index = self.combo.findData(neditable)
        self.combo.setItemIcon(index, icon)

    def update_item_text(self, neditable, text):
        index = self.combo.findData(neditable)
        self.combo.setItemText(index, text)

    def current_changed(self, index):
        """Change the current item in the combo."""
        neditable = self.combo.itemData(index)
        self.emit(SIGNAL("changeCurrent(PyQt_PyObject, int)"), neditable, index)

    def current_symbol_changed(self, index):
        """Change the current symbol in the combo."""
        self.emit(SIGNAL("goToSymbol(int)"), index)

    def update_line_col(self, line, col):
        """Update the line and column position."""
        self.lbl_position.setText(self._pos_text % (line, col))

    def _context_menu_requested(self, point):
        """Display context menu for the combo file."""
        if self.combo.count() == 0:
            # If there is not an Editor opened, don't show the menu
            return
        menu = QMenu()
        actionAdd = menu.addAction(translations.TR_ADD_TO_PROJECT)
        actionRun = menu.addAction(translations.TR_RUN_FILE)
        menuSyntax = menu.addMenu(translations.TR_CHANGE_SYNTAX)
        self._create_menu_syntax(menuSyntax)
        menu.addSeparator()
        actionClose = menu.addAction(translations.TR_CLOSE_FILE)
        actionCloseAll = menu.addAction(translations.TR_CLOSE_ALL_FILES)
        actionCloseAllNotThis = menu.addAction(
            translations.TR_CLOSE_OTHER_FILES)
        menu.addSeparator()
        actionSplitH = menu.addAction(translations.TR_SPLIT_VERTICALLY)
        actionSplitV = menu.addAction(translations.TR_SPLIT_HORIZONTALLY)
        menu.addSeparator()
        actionCopyPath = menu.addAction(
            translations.TR_COPY_FILE_PATH_TO_CLIPBOARD)
        actionReopen = menu.addAction(translations.TR_REOPEN_FILE)
        actionUndock = menu.addAction(translations.TR_UNDOCK_EDITOR)
        if len(settings.LAST_OPENED_FILES) == 0:
            actionReopen.setEnabled(False)
        #Connect actions
        self.connect(actionSplitH, SIGNAL("triggered()"),
            lambda: self._split(False))
        self.connect(actionSplitV, SIGNAL("triggered()"),
            lambda: self._split(True))
        self.connect(actionRun, SIGNAL("triggered()"),
            self._run_this_file)
        self.connect(actionAdd, SIGNAL("triggered()"),
            self._add_to_project)
        self.connect(actionClose, SIGNAL("triggered()"),
            self.about_to_close_file)
        self.connect(actionCloseAllNotThis, SIGNAL("triggered()"),
            self._close_all_files_except_this)
        self.connect(actionCloseAll, SIGNAL("triggered()"),
            self._close_all_files)
        self.connect(actionCopyPath, SIGNAL("triggered()"),
            self._copy_file_location)
        self.connect(actionReopen, SIGNAL("triggered()"),
            self._reopen_last_tab)
        self.connect(actionUndock, SIGNAL("triggered()"),
            self._undock_editor)

        menu.exec_(QCursor.pos())

    def _create_menu_syntax(self, menuSyntax):
        """Create Menu with the list of syntax supported."""
        syntax = list(settings.SYNTAX.keys())
        syntax.sort()
        for syn in syntax:
            menuSyntax.addAction(syn)
            self.connect(menuSyntax, SIGNAL("triggered(QAction*)"),
                self._reapply_syntax)

    def _reapply_syntax(self, syntaxAction):
        #TODO
        if [self.currentIndex(), syntaxAction] != self._resyntax:
            self._resyntax = [self.currentIndex(), syntaxAction]
            self.emit(SIGNAL("syntaxChanged(QWidget, QString)"),
                self.currentWidget(), syntaxAction.text())

    def set_current_file(self, neditable):
        index = self.combo.findData(neditable)
        self.combo.setCurrentIndex(index)

    def set_current_by_index(self, index):
        self.combo.setCurrentIndex(index)

    def about_to_close_file(self, index=None):
        """Close the NFile object."""
        if index is None:
            index = self.combo.currentIndex()
        neditable = self.combo.itemData(index)
        if neditable:
            neditable.nfile.close()

    def close_split(self):
        self.emit(SIGNAL("closeSplit()"))

    def close_file(self, neditable):
        """Receive the confirmation to close the file."""
        index = self.combo.findData(neditable)
        self.combo.removeItem(index)
        return index

    def _run_this_file(self):
        """Execute the current file."""
        neditable = self.combo.itemData(self.combo.currentIndex())
        self.emit(SIGNAL("runFile(QString)"), neditable.file_path)

    def _add_to_project(self):
        """Emit a signal to let someone handle the inclusion of the file
        inside a project."""
        neditable = self.combo.itemData(self.combo.currentIndex())
        self.emit(SIGNAL("addToProject(QString)"), neditable.file_path)

    def _reopen_last_tab(self):
        self.emit(SIGNAL("reopenTab(QString)"),
            settings.LAST_OPENED_FILES.pop())
        self.emit(SIGNAL("recentTabsModified()"))

    def _undock_editor(self):
        self.emit(SIGNAL("undockEditor()"))

    def _split(self, orientation):
        self.emit(SIGNAL("splitEditor(bool)"), orientation)

    def _copy_file_location(self):
        """Copy the path of the current opened file to the clipboard."""
        neditable = self.combo.itemData(self.combo.currentIndex())
        QApplication.clipboard().setText(neditable.file_path,
            QClipboard.Clipboard)

    def _close_all_files(self):
        """Close all the files opened."""
        for i in range(self.combo.count()):
            self.about_to_close_file(0)

    def _close_all_files_except_this(self):
        """Close all the files except the current one."""
        neditable = self.combo.itemData(self.combo.currentIndex())
        for i in reversed(list(range(self.combo.count()))):
            ne = self.combo.itemData(i)
            if ne is not neditable:
                self.about_to_close_file(i)
예제 #27
0
class HexColumnConfigurationWidget(QWidget, columnproviders.AbstractColumnConfigurationWidget):
    def __init__(self, parent, hex_widget, column):
        QWidget.__init__(self, parent)
        columnproviders.AbstractColumnConfigurationWidget.__init__(self)
        self.hexWidget = hex_widget
        self.column = column

        self.setLayout(QFormLayout())
        self.layout().setContentsMargins(0, 0, 0, 0)

        self.cmbBinaryFormat = QComboBox(self)
        self.cmbBinaryFormat.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        self.layout().addRow(utils.tr('Binary format:'), self.cmbBinaryFormat)
        self.cmbBinaryFormat.currentIndexChanged[int].connect(self._onBinaryFormatChanged)

        self.chkSigned = QCheckBox()
        self.layout().addRow(utils.tr('Signed values:'), self.chkSigned)
        if column is not None:
            self.chkSigned.setChecked(column.valuecodec.signed)

        self.cmbEndianess = QComboBox(self)
        self.cmbEndianess.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        self.layout().addRow(utils.tr('Endianess:'), self.cmbEndianess)
        self.cmbEndianess.addItem(utils.tr('Little endian'), valuecodecs.LittleEndian)
        self.cmbEndianess.addItem(utils.tr('Big endian'), valuecodecs.BigEndian)
        if column is not None:
            self.cmbEndianess.setCurrentIndex(self.cmbEndianess.findData(column.valuecodec.endianess))
        else:
            self.cmbEndianess.setCurrentIndex(0)

        icodec = valuecodecs.IntegerCodec
        for fmt in (icodec.Format8Bit, icodec.Format16Bit, icodec.Format32Bit, icodec.Format64Bit):
            self.cmbBinaryFormat.addItem(icodec.formatName(fmt), fmt)
            if column is not None and column.valuecodec.binaryFormat == fmt:
                self.cmbBinaryFormat.setCurrentIndex(self.cmbBinaryFormat.count() - 1)
        if column is None:
            self.cmbBinaryFormat.setCurrentIndex(0)

        self.cmbBase = QComboBox(self)
        self.cmbBase.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        self.layout().addRow(utils.tr('Base:'), self.cmbBase)
        for base in ((utils.tr('Hex'), 16), (utils.tr('Dec'), 10), (utils.tr('Oct'), 8), (utils.tr('Bin'), 2)):
            self.cmbBase.addItem(base[0], base[1])
        if column is not None:
            self.cmbBase.setCurrentIndex(self.cmbBase.findData(column.formatter.base))

        self.spnColumnsOnRow = QSpinBox(self)
        self.spnColumnsOnRow.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        self.spnColumnsOnRow.setMinimum(1)
        self.spnColumnsOnRow.setMaximum(32)
        self.layout().addRow(utils.tr('Columns on row:'), self.spnColumnsOnRow)
        if column is not None:
            self.spnColumnsOnRow.setValue(column.columnsOnRow)
        else:
            self.spnColumnsOnRow.setValue(16)

    def _onBinaryFormatChanged(self, index):
        self.cmbEndianess.setEnabled(self.cmbBinaryFormat.itemData(index) != valuecodecs.IntegerCodec.Format8Bit)

    @property
    def _valueCodec(self):
        valuecodec = valuecodecs.IntegerCodec()
        valuecodec.binaryFormat = self.cmbBinaryFormat.itemData(self.cmbBinaryFormat.currentIndex())
        valuecodec.signed = self.chkSigned.isChecked()
        valuecodec.endianess = self.cmbEndianess.itemData(self.cmbEndianess.currentIndex())
        return valuecodec

    @property
    def _formatter(self):
        valuecodec = self._valueCodec
        formatter = formatters.IntegerFormatter()
        formatter.base = self.cmbBase.itemData(self.cmbBase.currentIndex())
        maximal = formatter.format(valuecodec.maximal)
        minimal = formatter.format(valuecodec.minimal)
        if minimal.startswith('-'):
            minimal = minimal[1:]
        formatter.padding = max(len(maximal), len(minimal))
        return formatter

    def createColumnModel(self, hex_widget):
        return HexColumnModel(hex_widget.document, self._valueCodec, self._formatter, self.spnColumnsOnRow.value())

    def saveToColumn(self, column):
        column.valuecodec = self._valueCodec
        column.formatter = self._formatter
        column.columnsOnRow = self.spnColumnsOnRow.value()
        column.reset()