Example #1
0
class SpinBoxImageView(QHBoxLayout):
    valueChanged = pyqtSignal(int)
    def __init__(self, parentView, backgroundColor, foregroundColor,
                 value, height, fontSize):
        QHBoxLayout.__init__(self)
        self.backgroundColor = backgroundColor
        self.foregroundColor = foregroundColor

        self.labelLayout = QVBoxLayout()
        self.upLabel = LabelButtons('spin-up', parentView,
                                    backgroundColor, foregroundColor,
                                    height/2, height/2)
        self.labelLayout.addWidget(self.upLabel)
        self.upLabel.clicked.connect(self.on_upLabel)

        self.downLabel = LabelButtons('spin-down', parentView,
                                      backgroundColor,
                                      foregroundColor, height/2,
                                      height/2)
        self.labelLayout.addWidget(self.downLabel)
        self.downLabel.clicked.connect(self.on_downLabel)

        self.addLayout(self.labelLayout)

        self.spinBox = QSpinBox()
        self.spinBox.valueChanged.connect(self.spinBoxValueChanged)
        self.addWidget(self.spinBox)
        self.spinBox.setToolTip("Spinbox")
        self.spinBox.setButtonSymbols(QAbstractSpinBox.NoButtons)
        self.spinBox.setAlignment(Qt.AlignRight)
        self.spinBox.setMaximum(value)
        self.spinBox.setMaximumHeight(height)
        self.spinBox.setSuffix("/" + str(value))
        font = self.spinBox.font()
        font.setPixelSize(fontSize)
        self.spinBox.setFont(font)
        self.do_draw()

    def do_draw(self):
        r, g, b, a = self.foregroundColor.getRgb()
        rgb = "rgb({0},{1},{2})".format(r, g, b)
        sheet = TEMPLATE.format(rgb,
                                self.backgroundColor.name())
        self.spinBox.setStyleSheet(sheet)

    def spinBoxValueChanged(self, value):
        self.valueChanged.emit(value)

    def setValue(self, value):
        self.spinBox.setValue(value)

    def setNewValue(self, value):
        self.spinBox.setMaximum(value)
        self.spinBox.setSuffix("/" + str(value))

    def on_upLabel(self):
        self.spinBox.setValue(self.spinBox.value() + 1)

    def on_downLabel(self):
        self.spinBox.setValue(self.spinBox.value() - 1)
Example #2
0
class Prefs(preferences.Group):
    def __init__(self, page):
        super(Prefs, self).__init__(page)

        self._closeOutputs = QCheckBox(clicked=self.changed)
        self._pollingLabel = QLabel()
        self._pollingTime = QSpinBox()
        self._pollingTime.setRange(0, 1000)
        self._pollingTime.setSuffix(" ms")
        self._pollingTime.valueChanged.connect(self.changed)

        layout = QVBoxLayout()
        self.setLayout(layout)

        layout.addWidget(self._closeOutputs)
        app.translateUI(self)

        hbox = QHBoxLayout()
        layout.addLayout(hbox)

        hbox.addWidget(self._pollingLabel)
        hbox.addWidget(self._pollingTime)

    def translateUI(self):
        self.setTitle(_("Preferences"))
        self._closeOutputs.setText(_("Close unused MIDI output"))
        self._closeOutputs.setToolTip(
            _("Closes unused MIDI ports after one minute. " 'See "What\'s This" for more information.')
        )
        self._closeOutputs.setWhatsThis(
            _(
                "<p>If checked, Frescobaldi will close MIDI output ports that are not "
                "used for one minute.</p>\n"
                "<p>This could free up system resources that a software MIDI synthesizer "
                "might be using, thus saving battery power.</p>\n"
                "<p>A side effect is that if you pause a MIDI file for a long time "
                "the instruments are reset to the default piano (instrument 0). "
                "In that case, playing the file from the beginning sets up the "
                "instruments again.</p>\n"
            )
        )
        self._pollingLabel.setText(_("Polling time for input:"))
        self._pollingTime.setToolTip(_("Polling time for MIDI input. " 'See "What\'s This" for more information.'))
        self._pollingTime.setWhatsThis(
            _(
                "Sets the time between the polling of the MIDI input port in milliseconds. "
                "Small values lead to faster recognition of incoming MIDI events, but stress "
                "the CPU. 10 ms should be a good value."
            )
        )

    def loadSettings(self):
        s = QSettings()
        self._closeOutputs.setChecked(s.value("midi/close_outputs", False, bool))
        self._pollingTime.setValue(s.value("midi/polling_time", 10, int))

    def saveSettings(self):
        s = QSettings()
        s.setValue("midi/close_outputs", self._closeOutputs.isChecked())
        s.setValue("midi/polling_time", self._pollingTime.value())
class SpinBoxImageView(QHBoxLayout):
    valueChanged = pyqtSignal(int)
    def __init__(self, parentView, backgroundColor, foregroundColor,
                 value, height, fontSize):
        QHBoxLayout.__init__(self)
        self.backgroundColor = backgroundColor
        self.foregroundColor = foregroundColor

        self.labelLayout = QVBoxLayout()
        self.upLabel = LabelButtons('spin-up', parentView,
                                    backgroundColor, foregroundColor,
                                    height/2, height/2)
        self.labelLayout.addWidget(self.upLabel)
        self.upLabel.clicked.connect(self.on_upLabel)

        self.downLabel = LabelButtons('spin-down', parentView,
                                      backgroundColor,
                                      foregroundColor, height/2,
                                      height/2)
        self.labelLayout.addWidget(self.downLabel)
        self.downLabel.clicked.connect(self.on_downLabel)

        self.addLayout(self.labelLayout)

        self.spinBox = QSpinBox()
        self.spinBox.valueChanged.connect(self.spinBoxValueChanged)
        self.addWidget(self.spinBox)
        self.spinBox.setToolTip("Spinbox")
        self.spinBox.setButtonSymbols(QAbstractSpinBox.NoButtons)
        self.spinBox.setAlignment(Qt.AlignRight)
        self.spinBox.setMaximum(value)
        self.spinBox.setMaximumHeight(height)
        self.spinBox.setSuffix("/" + str(value))
        font = self.spinBox.font()
        font.setPixelSize(fontSize)
        self.spinBox.setFont(font)
        self.do_draw()

    def do_draw(self):
        r, g, b, a = self.foregroundColor.getRgb()
        rgb = "rgb({0},{1},{2})".format(r, g, b)
        sheet = TEMPLATE.format(rgb,
                                self.backgroundColor.name())
        self.spinBox.setStyleSheet(sheet)

    def spinBoxValueChanged(self, value):
        self.valueChanged.emit(value)

    def setValue(self, value):
        self.spinBox.setValue(value)

    def setNewValue(self, value):
        self.spinBox.setMaximum(value)
        self.spinBox.setSuffix("/" + str(value))

    def on_upLabel(self):
        self.spinBox.setValue(self.spinBox.value() + 1)

    def on_downLabel(self):
        self.spinBox.setValue(self.spinBox.value() - 1)
class SpinBoxImageView(QHBoxLayout):
    valueChanged = pyqtSignal(int)
    def __init__(self, backgroundColor, foregroundColor, value, height, fontSize):
        QHBoxLayout.__init__(self)
        self.backgroundColor = backgroundColor
        self.foregroundColor = foregroundColor
        
        self.labelLayout = QVBoxLayout()
        self.upLabel = LabelButtons(backgroundColor, foregroundColor, height/2, height/2)
        self.labelLayout.addWidget(self.upLabel)
        self.upLabel.setSpinBoxUpIcon()
        self.upLabel.clicked.connect(self.on_upLabel)
        
        self.downLabel = LabelButtons(backgroundColor, foregroundColor, height/2, height/2)
        self.labelLayout.addWidget(self.downLabel)
        self.downLabel.setSpinBoxDownIcon()
        self.downLabel.clicked.connect(self.on_downLabel)
        
        self.addLayout(self.labelLayout)

        
        self.spinBox = QSpinBox()
        self.spinBox.valueChanged.connect(self.spinBoxValueChanged)
        self.addWidget(self.spinBox)
        self.spinBox.setToolTip("Spinbox")
        self.spinBox.setButtonSymbols(QAbstractSpinBox.NoButtons)
        self.spinBox.setAlignment(Qt.AlignRight)
        self.spinBox.setMaximum(value)
        self.spinBox.setMaximumHeight(height)
        self.spinBox.setSuffix("/" + str(value))
        font = self.spinBox.font()
        font.setPixelSize(fontSize)
        self.spinBox.setFont(font)
        rgb = foregroundColor.getRgb()
        rgba_string = "rgba("+str(rgb[0])+","+str(rgb[1])+","+str(rgb[2])+","+str(0.6*100)+"%)"
        self.spinBox.setStyleSheet("QSpinBox { color: " + rgba_string + "; font: bold; background-color: " + str(backgroundColor.name()) + "; border:0;}")

    def changeOpacity(self, opacity):
        rgb = self.foregroundColor.getRgb()
        rgba_string = "rgba("+str(rgb[0])+","+str(rgb[1])+","+str(rgb[2])+","+str(opacity*100)+"%)"
        self.spinBox.setStyleSheet("QSpinBox { color: " + rgba_string + "; font: bold; background-color: " + str(self.backgroundColor.name()) + "; border:0;}")
        self.upLabel.changeOpacity(opacity)
        self.downLabel.changeOpacity(opacity)

    def spinBoxValueChanged(self, value):
        self.valueChanged.emit(value)    
    
    def setValue(self, value):
        self.spinBox.setValue(value)
    
    def setNewValue(self, value):
        self.spinBox.setMaximum(value)
        self.spinBox.setSuffix("/" + str(value))
    
    def on_upLabel(self):
        self.spinBox.setValue(self.spinBox.value() + 1)
        
    def on_downLabel(self):
        self.spinBox.setValue(self.spinBox.value() - 1)
Example #5
0
class Prefs(preferences.Group):
    def __init__(self, page):
        super(Prefs, self).__init__(page)

        self._closeOutputs = QCheckBox(clicked=self.changed)
        self._pollingLabel = QLabel()
        self._pollingTime = QSpinBox()
        self._pollingTime.setRange(0, 1000)
        self._pollingTime.setSuffix(" ms")
        self._pollingTime.valueChanged.connect(self.changed)

        layout = QVBoxLayout()
        self.setLayout(layout)

        layout.addWidget(self._closeOutputs)
        app.translateUI(self)

        hbox = QHBoxLayout()
        layout.addLayout(hbox)

        hbox.addWidget(self._pollingLabel)
        hbox.addWidget(self._pollingTime)

    def translateUI(self):
        self.setTitle(_("Preferences"))
        self._closeOutputs.setText(_("Close unused MIDI output"))
        self._closeOutputs.setToolTip(
            _("Closes unused MIDI ports after one minute. "
              "See \"What's This\" for more information."))
        self._closeOutputs.setWhatsThis(
            _("<p>If checked, Frescobaldi will close MIDI output ports that are not "
              "used for one minute.</p>\n"
              "<p>This could free up system resources that a software MIDI synthesizer "
              "might be using, thus saving battery power.</p>\n"
              "<p>A side effect is that if you pause a MIDI file for a long time "
              "the instruments are reset to the default piano (instrument 0). "
              "In that case, playing the file from the beginning sets up the "
              "instruments again.</p>\n"))
        self._pollingLabel.setText(_("Polling time for input:"))
        self._pollingTime.setToolTip(
            _("Polling time for MIDI input. "
              "See \"What's This\" for more information."))
        self._pollingTime.setWhatsThis(
            _("Sets the time between the polling of the MIDI input port in milliseconds. "
              "Small values lead to faster recognition of incoming MIDI events, but stress "
              "the CPU. 10 ms should be a good value."))

    def loadSettings(self):
        s = QSettings()
        self._closeOutputs.setChecked(
            s.value("midi/close_outputs", False, bool))
        self._pollingTime.setValue(s.value("midi/polling_time", 10, int))

    def saveSettings(self):
        s = QSettings()
        s.setValue("midi/close_outputs", self._closeOutputs.isChecked())
        s.setValue("midi/polling_time", self._pollingTime.value())
Example #6
0
class MusicView(preferences.Group):
    def __init__(self, page):
        super(MusicView, self).__init__(page)
        
        layout = QGridLayout()
        self.setLayout(layout)

        self.magnifierSizeLabel = QLabel()
        self.magnifierSizeSlider = QSlider(Qt.Horizontal, valueChanged=self.changed)
        self.magnifierSizeSlider.setSingleStep(50)
        self.magnifierSizeSlider.setRange(*popplerview.MagnifierSettings.sizeRange)
        self.magnifierSizeSpinBox = QSpinBox()
        self.magnifierSizeSpinBox.setRange(*popplerview.MagnifierSettings.sizeRange)
        self.magnifierSizeSpinBox.valueChanged.connect(self.magnifierSizeSlider.setValue)
        self.magnifierSizeSlider.valueChanged.connect(self.magnifierSizeSpinBox.setValue)
        layout.addWidget(self.magnifierSizeLabel, 0, 0)
        layout.addWidget(self.magnifierSizeSlider, 0, 1)
        layout.addWidget(self.magnifierSizeSpinBox, 0, 2)
        
        self.magnifierScaleLabel = QLabel()
        self.magnifierScaleSlider = QSlider(Qt.Horizontal, valueChanged=self.changed)
        self.magnifierScaleSlider.setSingleStep(50)
        self.magnifierScaleSlider.setRange(*popplerview.MagnifierSettings.scaleRange)
        self.magnifierScaleSpinBox = QSpinBox()
        self.magnifierScaleSpinBox.setRange(*popplerview.MagnifierSettings.scaleRange)
        self.magnifierScaleSpinBox.valueChanged.connect(self.magnifierScaleSlider.setValue)
        self.magnifierScaleSlider.valueChanged.connect(self.magnifierScaleSpinBox.setValue)
        layout.addWidget(self.magnifierScaleLabel, 1, 0)
        layout.addWidget(self.magnifierScaleSlider, 1, 1)
        layout.addWidget(self.magnifierScaleSpinBox, 1, 2)
        
        app.translateUI(self)
        
    def translateUI(self):
        self.setTitle(_("Music View"))
        self.magnifierSizeLabel.setText(_("Magnifier Size:"))
        self.magnifierSizeLabel.setToolTip(_(
            "Size of the magnifier glass (Ctrl+Click in the Music View)."))
        # L10N: as in "400 pixels", appended after number in spinbox, note the leading space
        self.magnifierSizeSpinBox.setSuffix(_(" pixels"))
        self.magnifierScaleLabel.setText(_("Magnifier Scale:"))
        self.magnifierScaleLabel.setToolTip(_(
            "Magnification of the magnifier."))
        self.magnifierScaleSpinBox.setSuffix(_("percent unit sign", "%"))
            
    def loadSettings(self):
        s = popplerview.MagnifierSettings.load()
        self.magnifierSizeSlider.setValue(s.size)
        self.magnifierScaleSlider.setValue(s.scale)
    
    def saveSettings(self):
        s = popplerview.MagnifierSettings()
        s.size = self.magnifierSizeSlider.value()
        s.scale = self.magnifierScaleSlider.value()
        s.save()
Example #7
0
class Updates(QWidget):
    
    def __init__(self, pref):
        QWidget.__init__(self)
        vbox = QVBoxLayout(self)

        vbox.addWidget(QLabel('Set the interval for updates:'))
        self.spin = QSpinBox()
        self.spin.setRange(1, 60)
        self.spin.setSuffix(' minutes')
        self.spin.setValue(pref.get('time', 10))
        vbox.addWidget(self.spin)
Example #8
0
class Form(QDialog):
    def __init__(self, parent=None):
        super(Form, self).__init__(parent)

        self.label_amount = QLabel('Amount')
        self.spin_amount = QDoubleSpinBox()
        self.spin_amount.setRange(0, 10000000000)
        self.spin_amount.setPrefix('Rp. ')
        self.spin_amount.setSingleStep(100000)

        self.label_rate = QLabel('Rate')
        self.spin_rate = QDoubleSpinBox()
        self.spin_rate.setSuffix(' %')
        self.spin_rate.setSingleStep(0.1)
        self.spin_rate.setRange(0, 100)

        self.label_year = QLabel('Years')
        self.spin_year = QSpinBox()
        self.spin_year.setSuffix(' year')
        self.spin_year.setSingleStep(1)
        self.spin_year.setRange(0, 1000)
        self.spin_year.setValue(1)

        self.label_total_ = QLabel('Total')
        self.label_total = QLabel('Rp. 0.00')

        grid = QGridLayout()
        grid.addWidget(self.label_amount, 0, 0)
        grid.addWidget(self.spin_amount, 0, 1)
        grid.addWidget(self.label_rate, 1, 0)
        grid.addWidget(self.spin_rate, 1, 1)
        grid.addWidget(self.label_year, 2, 0)
        grid.addWidget(self.spin_year, 2, 1)
        grid.addWidget(self.label_total_, 3, 0)
        grid.addWidget(self.label_total, 3, 1)
        self.setLayout(grid)

        self.connect(self.spin_amount, SIGNAL('valueChanged(double)'),
                     self.update_ui)
        self.connect(self.spin_rate, SIGNAL('valueChanged(double)'),
                     self.update_ui)
        self.connect(self.spin_year, SIGNAL('valueChanged(int)'),
                     self.update_ui)
        self.setWindowTitle('Interest')

    def update_ui(self):
        amount = self.spin_amount.value()
        rate = self.spin_rate.value()
        year = self.spin_year.value()
        total = amount * (1 + rate / 100.0)**year

        self.label_total.setText('Rp. %.2f' % total)
Example #9
0
    def __init__(self, attr_name, attr_val, parent=None):
        super(Attribute, self).__init__(parent)

        # The label with the attribute's name
        label = QLabel(attr_name)

        # Now create the editing element, initialized with the attribute's
        # value.
        # First, if the value is an integer, use a spinbox
        if type(attr_val) is int:
            value = QSpinBox()
            value.setMaximum(1E9)
            value.setValue(attr_val)
        # Second, if the value is a float, use a doublespinbox, with some
        # customizations for certain attributes.
        elif type(attr_val) is float:
            # We want to display the sensitivities in useful units, which should
            # simulate scientific notation. The attribute value is the
            # sensitivity's index in the SENSVECTOR.
            if "Sens" in attr_name:
                value = QSpinBox()
                value.setMaximum(1E10)
                value.setMinimum(1)
                attr_val = SENSVECTOR[int(attr_val)]
                # Figure out which units to use
                for ex in [(1E-3, 'mV'), (1E-6, 'uV'), (1E-9, 'nV')]:
                    if attr_val / ex[0] > 1 and attr_val / ex[0] < 1000:
                        value.setValue(attr_val / ex[0])
                        value.setSuffix(' {units}'.format(units=ex[1]))
            # If the value is a float, but not a sensitivity, just use a normal
            # doublespinbox
            else:
                value = QDoubleSpinBox()
                value.setMaximum(1E9)
                value.setMinimum(-1E9)
                value.setValue(attr_val)
        # Third, if the value is a datetime, dispaly it in a datetimeedit
        # element.
        elif type(attr_val) is datetime:
            value = QDateTimeEdit()
            value.setDateTime(attr_val)
        # Finally, for everything else just display it in a lineedit element.
        else:
            value = QLineEdit()
            value.setText(str(attr_val))

        layout = QHBoxLayout()
        layout.addWidget(label)
        layout.addWidget(value)

        self.setLayout(layout)
class Form(QDialog):
    def __init__(self, parent=None):
        super(Form, self).__init__(parent)
        
        self.label_amount = QLabel('Amount')
        self.spin_amount = QDoubleSpinBox()
        self.spin_amount.setRange(0, 10000000000)
        self.spin_amount.setPrefix('Rp. ')
        self.spin_amount.setSingleStep(100000)
        
        self.label_rate = QLabel('Rate')
        self.spin_rate = QDoubleSpinBox()
        self.spin_rate.setSuffix(' %')
        self.spin_rate.setSingleStep(0.1)
        self.spin_rate.setRange(0, 100)
        
        self.label_year = QLabel('Years')
        self.spin_year = QSpinBox()
        self.spin_year.setSuffix(' year')
        self.spin_year.setSingleStep(1)
        self.spin_year.setRange(0, 1000)
        self.spin_year.setValue(1)
        
        
        self.label_total_ = QLabel('Total')
        self.label_total = QLabel('Rp. 0.00')
        
        grid = QGridLayout()
        grid.addWidget(self.label_amount, 0, 0)
        grid.addWidget(self.spin_amount, 0, 1)
        grid.addWidget(self.label_rate, 1, 0)
        grid.addWidget(self.spin_rate, 1, 1)
        grid.addWidget(self.label_year, 2, 0)
        grid.addWidget(self.spin_year, 2, 1)
        grid.addWidget(self.label_total_, 3, 0)
        grid.addWidget(self.label_total, 3, 1)
        self.setLayout(grid)
        
        self.connect(self.spin_amount, SIGNAL('valueChanged(double)'), self.update_ui)
        self.connect(self.spin_rate, SIGNAL('valueChanged(double)'), self.update_ui)
        self.connect(self.spin_year, SIGNAL('valueChanged(int)'), self.update_ui)
        self.setWindowTitle('Interest')
    
    def update_ui(self):        
        amount = self.spin_amount.value()
        rate = self.spin_rate.value()
        year = self.spin_year.value()
        total = amount * (1 + rate / 100.0) ** year
        
        self.label_total.setText('Rp. %.2f' % total)
Example #11
0
class ProjectXively(QWidget):
    qtcb_update_illuminance = pyqtSignal(float)
    qtcb_update_air_pressure = pyqtSignal(float)
    qtcb_update_temperature = pyqtSignal(float)
    qtcb_update_humidity = pyqtSignal(float)
    qtcb_button_pressed = pyqtSignal(int)

    lcdwidget = None

    xively_host = "api.xively.com"
    xively_agent = "Tinkerforge Starter Kit Weather Station Demo"
    xively_channel = "Enter Feed ID here"
    xively_api_key = "Enter API Key here"

    xively_items = {}
    xively_headers = None
    xively_params = ""
    xively_update_rate = 5  # in minutes

    text_agent = None
    text_channel = None
    text_api_key = None
    number_update_rate = None

    save_button = None

    xively_timer = None

    error_message = None

    label_upload_active = None

    last_upload = None

    def __init__(self, parent, app):
        super(QWidget, self).__init__()

        self.lcdwidget = LCDWidget(self, app)
        self.lcdwidget.hide()

        self.text_agent = QLineEdit(self)
        self.text_agent.setText(self.xively_agent)

        self.text_channel = QLineEdit(self)
        self.text_channel.setText(self.xively_channel)

        self.text_api_key = QLineEdit(self)
        self.text_api_key.setText(self.xively_api_key)

        self.number_update_rate = QSpinBox(self)
        self.number_update_rate.setRange(1, 1440)
        self.number_update_rate.setSuffix(' min')
        self.number_update_rate.setValue(self.xively_update_rate)

        layout1 = QHBoxLayout()
        layout2 = QVBoxLayout()

        layout1.addStretch()
        layout1.addLayout(layout2)
        layout1.addStretch()

        layout2.addSpacerItem(QSpacerItem(LCDWidget.FIXED_WIDGTH, 0))

        label = QLabel(self)
        label.setText(
            "Project: <b>Connect to Xively</b>. This project uploads the measured values to Xively. Please find documentation how to configure it and program sources in Python <a href=\"http://www.tinkerforge.com/en/doc/Kits/WeatherStation/WeatherStation.html#connect-to-xively\">here</a>.<br>"
        )
        label.setTextFormat(Qt.RichText)
        label.setTextInteractionFlags(Qt.TextBrowserInteraction)
        label.setOpenExternalLinks(True)
        label.setWordWrap(True)
        label.setAlignment(Qt.AlignJustify)

        layout2.addSpacing(10)
        layout2.addWidget(label)
        layout2.addSpacing(10)

        layout3a = QHBoxLayout()
        label = QLabel("Agent Description:")
        label.setMinimumWidth(150)
        layout3a.addWidget(label)
        layout3a.addWidget(self.text_agent, 1)

        layout2.addLayout(layout3a)
        layout2.addSpacing(10)

        layout3b = QHBoxLayout()
        label = QLabel("Feed:")
        label.setMinimumWidth(150)
        layout3b.addWidget(label)
        layout3b.addWidget(self.text_channel, 1)

        layout2.addLayout(layout3b)
        layout2.addSpacing(10)

        layout3c = QHBoxLayout()
        label = QLabel("API Key:")
        label.setMinimumWidth(150)
        layout3c.addWidget(label)
        layout3c.addWidget(self.text_api_key, 1)

        layout2.addLayout(layout3c)
        layout2.addSpacing(10)

        layout3d = QHBoxLayout()
        label = QLabel("Update Rate:")
        label.setMinimumWidth(150)
        layout3d.addWidget(label)
        layout3d.addWidget(self.number_update_rate, 1)

        layout2.addLayout(layout3d)
        layout2.addSpacing(10)

        self.label_upload_active = QLabel("Not Active", self)
        self.label_upload_active.setMinimumWidth(150)
        font = QFont()
        font.setPixelSize(20)
        self.label_upload_active.setFont(font)
        self.set_active_label(False)

        self.save_button = QPushButton("Save/Activate")

        layout4 = QHBoxLayout()
        layout4.addWidget(self.label_upload_active)
        layout4.addWidget(self.save_button, 1)

        layout2.addLayout(layout4)
        layout2.addStretch()

        self.setLayout(layout1)

        self.qtcb_update_illuminance.connect(self.update_illuminance_data_slot)
        self.qtcb_update_air_pressure.connect(
            self.update_air_pressure_data_slot)
        self.qtcb_update_temperature.connect(self.update_temperature_data_slot)
        self.qtcb_update_humidity.connect(self.update_humidity_data_slot)
        self.qtcb_button_pressed.connect(self.button_pressed_slot)
        self.save_button.clicked.connect(self.save_configuration)

        self.lcdwidget.clear(self)

        self.error_message = QErrorMessage(self)

    def set_active_label(self, value):
        palette = self.label_upload_active.palette()
        if value:
            palette.setColor(self.foregroundRole(), Qt.darkGreen)
            self.label_upload_active.setText("Active")
        else:
            palette.setColor(self.foregroundRole(), Qt.red)
            self.label_upload_active.setText("Not Active")

        self.label_upload_active.setPalette(palette)

    def save_configuration(self):
        try:
            self.xively_agent = str(self.text_agent.text()).decode('ascii')
            self.xively_channel = str(self.text_channel.text()).decode('ascii')
            self.xively_api_key = str(self.text_api_key.text()).decode('ascii')
        except:
            self.error_message.showMessage(
                'Agent, Feed and API Key can only contain ASCII characters')
            return

        self.xively_update_rate = self.number_update_rate.value()

        self.xively_headers = {
            "Content-Type": "application/x-www-form-urlencoded",
            "X-ApiKey": self.xively_api_key,
            "User-Agent": self.xively_agent,
        }
        self.xively_params = "/v2/feeds/" + self.xively_channel

        if self.xively_timer is None:
            self.xively_timer = QTimer(self)
            self.xively_timer.timeout.connect(self.update_xively)
            self.xively_timer.start(self.xively_update_rate * 60 * 1000)

        self.set_active_label(True)
        self.update_xively()

    def write_lcd(self):
        if self.last_upload == None:
            tmp = "Last: Never"
        else:
            tmp = "Last: " + self.last_upload

        self.lcdwidget.write_line(0, 0, "Xively Upload", self)
        self.lcdwidget.write_line(2, 0, tmp, self)

    def update_xively(self):
        if len(self.xively_items) == 0:
            return

        stream_items = []
        for identifier, value in self.xively_items.items():
            stream_items.append({
                'id': identifier,
                'current_value': value[0],
                'min_value': value[1],
                'max_value': value[2]
            })

        data = {'version': '1.0.0', 'datastreams': stream_items}
        self.xively_items = {}
        body = json.dumps(data)

        try:
            http = httplib.HTTPSConnection(self.xively_host)
            http.request('PUT', self.xively_params, body, self.xively_headers)
            response = http.getresponse()
            http.close()

            if response.status != 200:
                self.error_message.showMessage(
                    'Could not upload to xively -> Response:' +
                    str(response.status) + ': ' + response.reason +
                    '. Check your configuration.')
                self.xively_timer.stop()
                self.xively_timer = None
                self.set_active_label(False)
                return
        except Exception as e:
            self.error_message.showMessage('HTTP error: ' + str(e))
            self.xively_timer.stop()
            self.xively_timer = None
            self.set_active_label(False)
            return

        # set upload time if upload was a success
        self.last_upload = time.strftime("%H:%M:%S")

    def put(self, identifier, value):
        self.write_lcd()
        try:
            _, min_value, max_value = self.xively_items[identifier]
            if value < min_value:
                min_value = value
            if value > max_value:
                max_value = value
            self.xively_items[identifier] = (value, min_value, max_value)
        except:
            self.xively_items[identifier] = (value, value, value)

    def update_illuminance_data_slot(self, illuminance):
        self.put('AmbientLight', illuminance)

    def update_illuminance(self, illuminance):
        self.qtcb_update_illuminance.emit(illuminance)

    def update_humidity_data_slot(self, humidity):
        self.put('Humidity', humidity)

    def update_humidity(self, humidity):
        self.qtcb_update_humidity.emit(humidity)

    def update_air_pressure_data_slot(self, air_pressure):
        self.put('AirPressure', air_pressure)

    def update_air_pressure(self, air_pressure):
        self.qtcb_update_air_pressure.emit(air_pressure)

    def update_temperature_data_slot(self, temperature):
        self.put('Temperature', temperature)

    def update_temperature(self, temperature):
        self.qtcb_update_temperature.emit(temperature)

    def button_pressed_slot(self, button):
        pass

    def button_pressed(self, button):
        self.qtcb_button_pressed.emit(button)
Example #12
0
class MusicView(preferences.Group):
    def __init__(self, page):
        super(MusicView, self).__init__(page)
        
        layout = QGridLayout()
        self.setLayout(layout)
        
        self.newerFilesOnly = QCheckBox(toggled=self.changed)
        layout.addWidget(self.newerFilesOnly, 0, 0, 1, 3)
        
        self.magnifierSizeLabel = QLabel()
        self.magnifierSizeSlider = QSlider(Qt.Horizontal, valueChanged=self.changed)
        self.magnifierSizeSlider.setSingleStep(50)
        self.magnifierSizeSlider.setRange(*popplerview.MagnifierSettings.sizeRange)
        self.magnifierSizeSpinBox = QSpinBox()
        self.magnifierSizeSpinBox.setRange(*popplerview.MagnifierSettings.sizeRange)
        self.magnifierSizeSpinBox.valueChanged.connect(self.magnifierSizeSlider.setValue)
        self.magnifierSizeSlider.valueChanged.connect(self.magnifierSizeSpinBox.setValue)
        layout.addWidget(self.magnifierSizeLabel, 1, 0)
        layout.addWidget(self.magnifierSizeSlider, 1, 1)
        layout.addWidget(self.magnifierSizeSpinBox, 1, 2)
        
        self.magnifierScaleLabel = QLabel()
        self.magnifierScaleSlider = QSlider(Qt.Horizontal, valueChanged=self.changed)
        self.magnifierScaleSlider.setSingleStep(50)
        self.magnifierScaleSlider.setRange(*popplerview.MagnifierSettings.scaleRange)
        self.magnifierScaleSpinBox = QSpinBox()
        self.magnifierScaleSpinBox.setRange(*popplerview.MagnifierSettings.scaleRange)
        self.magnifierScaleSpinBox.valueChanged.connect(self.magnifierScaleSlider.setValue)
        self.magnifierScaleSlider.valueChanged.connect(self.magnifierScaleSpinBox.setValue)
        layout.addWidget(self.magnifierScaleLabel, 2, 0)
        layout.addWidget(self.magnifierScaleSlider, 2, 1)
        layout.addWidget(self.magnifierScaleSpinBox, 2, 2)
        
        self.enableKineticScrolling = QCheckBox(toggled=self.changed)
        layout.addWidget(self.enableKineticScrolling)
        self.showScrollbars = QCheckBox(toggled=self.changed)
        layout.addWidget(self.showScrollbars)
        app.translateUI(self)
        
    def translateUI(self):
        self.setTitle(_("Music View"))
        self.newerFilesOnly.setText(_("Only load updated PDF documents"))
        self.newerFilesOnly.setToolTip(_(
            "If checked, Frescobaldi will not open PDF documents that are not\n"
            "up-to-date (i.e. the source file has been modified later)."))
        self.magnifierSizeLabel.setText(_("Magnifier Size:"))
        self.magnifierSizeLabel.setToolTip(_(
            "Size of the magnifier glass (Ctrl+Click in the Music View)."))
        # L10N: as in "400 pixels", appended after number in spinbox, note the leading space
        self.magnifierSizeSpinBox.setSuffix(_(" pixels"))
        self.magnifierScaleLabel.setText(_("Magnifier Scale:"))
        self.magnifierScaleLabel.setToolTip(_(
            "Magnification of the magnifier."))
        self.magnifierScaleSpinBox.setSuffix(_("percent unit sign", "%"))
        # L10N: "Kinetic Scrolling" is a checkbox label, as in "Enable Kinetic Scrolling"
        self.enableKineticScrolling.setText(_("Kinetic Scrolling"))
        self.showScrollbars.setText(_("Show Scrollbars"))
            
    def loadSettings(self):
        s = popplerview.MagnifierSettings.load()
        self.magnifierSizeSlider.setValue(s.size)
        self.magnifierScaleSlider.setValue(s.scale)
        
        s = QSettings()
        s.beginGroup("musicview")
        newerFilesOnly = s.value("newer_files_only", True, bool)
        self.newerFilesOnly.setChecked(newerFilesOnly)
        kineticScrollingActive = s.value("kinetic_scrolling", True, bool)
        self.enableKineticScrolling.setChecked(kineticScrollingActive)
        showScrollbars = s.value("show_scrollbars", True, bool)
        self.showScrollbars.setChecked(showScrollbars)
    
    def saveSettings(self):
        s = popplerview.MagnifierSettings()
        s.size = self.magnifierSizeSlider.value()
        s.scale = self.magnifierScaleSlider.value()
        s.save()

        s = QSettings()
        s.beginGroup("musicview")
        s.setValue("newer_files_only", self.newerFilesOnly.isChecked())
        s.setValue("kinetic_scrolling", self.enableKineticScrolling.isChecked())
        s.setValue("show_scrollbars", self.showScrollbars.isChecked())
class YPipeWidget(QWidget):
	
	def __init__(self, leftFlow = 0, rightFlow = 0, maxFlow = 100, parent = None):
		super(YPipeWidget, self).__init__(parent)

		self.leftSpinBox = QSpinBox(self)
		self.leftSpinBox.setRange(0, maxFlow)
		self.leftSpinBox.setValue(leftFlow)
		self.leftSpinBox.setSuffix(" l/s")
		self.leftSpinBox.setAlignment(Qt.AlignRight|Qt.AlignVCenter)
		self.connect(self.leftSpinBox, SIGNAL("valueChanged(int)"), self.valueChanged)

		self.rightSpinBox = QSpinBox(self)
		self.rightSpinBox.setRange(0, maxFlow)
		self.rightSpinBox.setValue(rightFlow)
		self.rightSpinBox.setSuffix(" l/s")
		self.rightSpinBox.setAlignment(Qt.AlignRight|Qt.AlignVCenter)
		self.connect(self.rightSpinBox, SIGNAL("valueChanged(int)"), self.valueChanged)

		self.label = QLabel(self)
		self.label.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken)
		self.label.setAlignment(Qt.AlignCenter)
		fm = QFontMetricsF(self.font())
		self.label.setMinimumWidth(fm.width(" 999 l/s "))

		self.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding))

		self.setMinimumSize(self.minimumSizeHint())
		self.valueChanged()

	def valueChanged(self):
		a = self.leftSpinBox.value()
		b = self.rightSpinBox.value()
		self.label.setText("{0}".format(a + b))
		self.emit(SIGNAL("valueChanged"), a, b)
		self.update()

	def values(self):
		return self.leftSpinBox.value(), self.rightSpinBox.value()

	def minimumSizeHint(self):
		return QSize(self.leftSpinBox.width() * 3, self.leftSpinBox.height())

	def resizeEvent(self, event = None):
		fm = QFontMetricsF(self.font())
		x = (self.width() - self.label.width()) / 2
		y = self.height() - (fm.height() * 1.5)
		self.label.move(x, y)

		y = self.height() / 60.0
		x = (self.width() / 4.0) - self.leftSpinBox.width()
		self.leftSpinBox.move(x, y)

		x = self.width() - (self.width() / 4.0)
		self.rightSpinBox.move(x, y)

	def paintEvent(self, event = None):
		
		LogicalSize = 100.0

		def logicalFromPhysical(length, side):
			return (length / side) * LogicalSize

		fm = QFontMetricsF(self.font())
		ymargin = ((LogicalSize / 30.0) + logicalFromPhysical(self.leftSpinBox.height(), self.height()))
		ymax = (LogicalSize - logicalFromPhysical(fm.height() * 2, self.height()))
		width = LogicalSize / 4.0
		
		cx, cy = LogicalSize / 2.0, LogicalSize / 3.0
		ax, ay = cx - (2 * width), ymargin
		bx, by = cx - width, ay
		dx, dy = cx + width, ay
		ex, ey = cx + (2 * width), ymargin
		fx, fy = cx + (width / 2), cx + (LogicalSize / 24.0)
		gx, gy = fx, ymax
		hx, hy = cx - (width / 2), ymax
		ix, iy = hx, fy

		painter = QPainter(self)
		painter.setRenderHint(QPainter.Antialiasing)
		side = min(self.width(), self.height())
		painter.setViewport((self.width() - side) / 2, (self.height() - side) / 2, side, side)
		painter.setWindow(0, 0, LogicalSize, LogicalSize)

		painter.setPen(Qt.NoPen)

		gradient = QLinearGradient(QPointF(0, 0), QPointF(0, 100))
		gradient.setColorAt(0, Qt.white)
		a = self.leftSpinBox.value()
		gradient.setColorAt(1, (Qt.red if a != 0 else Qt.white))
		painter.setBrush(QBrush(gradient))
		painter.drawPolygon(QPolygon([ax, ay, bx, by, cx, cy, ix, iy]))

		gradient = QLinearGradient(QPointF(0, 0), QPointF(0, 100))
		gradient.setColorAt(0, Qt.white)
		b = self.rightSpinBox.value()
		gradient.setColorAt(1, (Qt.blue if b != 0 else Qt.white))
		painter.setBrush(QBrush(gradient))
		painter.drawPolygon(QPolygon([cx, cy, dx, dy, ex, ey, fx, fy]))

		if (a + b) == 0:
			color = QColor(Qt.white)
		else:
			ashare = (a / (a + b)) * 255.0
			bshare = 255.0 - ashare
			color = QColor(ashare, 0, bshare)

		gradient = QLinearGradient(QPointF(0, 0), QPointF(0, 100))
		gradient.setColorAt(0, Qt.white)
		gradient.setColorAt(1, color)
		painter.setBrush(QBrush(gradient))
		painter.drawPolygon(QPolygon([cx, cy, fx, fy, gx, gy, hx, hy, ix, iy]))

		painter.setPen(Qt.black)
		painter.drawPolyline(QPolygon([ax, ay, ix, iy, hx, hy]))
		painter.drawPolyline(QPolygon([gx, gy, fx, fy, ex, ey]))
		painter.drawPolyline(QPolygon([bx, by, cx, cy, dx, dy]))
class EditorConfiguration(QWidget):

    def __init__(self, parent):
        super(EditorConfiguration, self).__init__()
        self._preferences = parent
        vbox = QVBoxLayout(self)

        #Indentation
        groupBoxFeatures = QGroupBox(
            translations.TR_PREFERENCES_EDITOR_CONFIG_FEATURES)
        formFeatures = QGridLayout(groupBoxFeatures)
        formFeatures.addWidget(QLabel(
            translations.TR_PREFERENCES_EDITOR_CONFIG_INDENTATION),
            1, 0, Qt.AlignRight)
        self._spin = QSpinBox()
        self._spin.setAlignment(Qt.AlignRight)
        self._spin.setMinimum(1)
        self._spin.setValue(settings.INDENT)
        formFeatures.addWidget(self._spin, 1, 1, alignment=Qt.AlignTop)
        self._checkUseTabs = QCheckBox(
            translations.TR_PREFERENCES_EDITOR_CONFIG_USE_TABS)
        self._checkUseTabs.setChecked(settings.USE_TABS)
        self.connect(self._checkUseTabs, SIGNAL("stateChanged(int)"),
            self._change_tab_spaces)
        formFeatures.addWidget(self._checkUseTabs, 1, 2, alignment=Qt.AlignTop)
        if settings.USE_TABS:
            self._spin.setSuffix(
                translations.TR_PREFERENCES_EDITOR_CONFIG_TAB_SIZE)
        else:
            self._spin.setSuffix(
                translations.TR_PREFERENCES_EDITOR_CONFIG_SPACES)
        #Margin Line
        formFeatures.addWidget(QLabel(
            translations.TR_PREFERENCES_EDITOR_CONFIG_MARGIN_LINE), 2, 0,
            Qt.AlignRight)
        self._spinMargin = QSpinBox()
        self._spinMargin.setMaximum(200)
        self._spinMargin.setValue(settings.MARGIN_LINE)
        formFeatures.addWidget(self._spinMargin, 2, 1, alignment=Qt.AlignTop)
        self._checkShowMargin = QCheckBox(
            translations.TR_PREFERENCES_EDITOR_CONFIG_SHOW_MARGIN_LINE)
        self._checkShowMargin.setChecked(settings.SHOW_MARGIN_LINE)
        formFeatures.addWidget(self._checkShowMargin, 2, 2,
            alignment=Qt.AlignTop)
        #End of line
        self._checkEndOfLine = QCheckBox(
            translations.TR_PREFERENCES_EDITOR_CONFIG_END_OF_LINE)
        self._checkEndOfLine.setChecked(settings.USE_PLATFORM_END_OF_LINE)
        formFeatures.addWidget(self._checkEndOfLine, 3, 1,
            alignment=Qt.AlignTop)
        #Find Errors
        self._checkHighlightLine = QCheckBox(
            translations.TR_PREFERENCES_EDITOR_CONFIG_ERROR_HIGHLIGHTING)
        self._checkHighlightLine.setChecked(settings.UNDERLINE_NOT_BACKGROUND)
        formFeatures.addWidget(self._checkHighlightLine, 4, 1, 1, 2,
            alignment=Qt.AlignTop)
        self._checkErrors = QCheckBox(
            translations.TR_PREFERENCES_EDITOR_CONFIG_FIND_ERRORS)
        self._checkErrors.setChecked(settings.FIND_ERRORS)
        formFeatures.addWidget(self._checkErrors, 5, 1, 1, 2,
            alignment=Qt.AlignTop)
        self.connect(self._checkErrors, SIGNAL("stateChanged(int)"),
            self._disable_show_errors)
        self._showErrorsOnLine = QCheckBox(
            translations.TR_PREFERENCES_EDITOR_CONFIG_SHOW_TOOLTIP_ERRORS)
        self._showErrorsOnLine.setChecked(settings.ERRORS_HIGHLIGHT_LINE)
        self.connect(self._showErrorsOnLine, SIGNAL("stateChanged(int)"),
            self._enable_errors_inline)
        formFeatures.addWidget(self._showErrorsOnLine, 6, 2, 1, 1, Qt.AlignTop)
        #Find Check Style
        self._checkStyle = QCheckBox(
            translations.TR_PREFERENCES_EDITOR_CONFIG_SHOW_PEP8)
        self._checkStyle.setChecked(settings.CHECK_STYLE)
        formFeatures.addWidget(self._checkStyle, 7, 1, 1, 2,
            alignment=Qt.AlignTop)
        self.connect(self._checkStyle, SIGNAL("stateChanged(int)"),
            self._disable_check_style)
        self._checkStyleOnLine = QCheckBox(
            translations.TR_PREFERENCES_EDITOR_CONFIG_SHOW_TOOLTIP_PEP8)
        self._checkStyleOnLine.setChecked(settings.CHECK_HIGHLIGHT_LINE)
        self.connect(self._checkStyleOnLine, SIGNAL("stateChanged(int)"),
            self._enable_check_inline)
        formFeatures.addWidget(self._checkStyleOnLine, 8, 2, 1, 1, Qt.AlignTop)
        # Python3 Migration
        self._showMigrationTips = QCheckBox(
            translations.TR_PREFERENCES_EDITOR_CONFIG_SHOW_MIGRATION)
        self._showMigrationTips.setChecked(settings.SHOW_MIGRATION_TIPS)
        formFeatures.addWidget(self._showMigrationTips, 9, 1, 1, 2,
            Qt.AlignTop)
        #Center On Scroll
        self._checkCenterScroll = QCheckBox(
            translations.TR_PREFERENCES_EDITOR_CONFIG_CENTER_SCROLL)
        self._checkCenterScroll.setChecked(settings.CENTER_ON_SCROLL)
        formFeatures.addWidget(self._checkCenterScroll, 10, 1, 1, 2,
            alignment=Qt.AlignTop)
        #Remove Trailing Spaces add Last empty line automatically
        self._checkTrailing = QCheckBox(
            translations.TR_PREFERENCES_EDITOR_CONFIG_REMOVE_TRAILING)
        self._checkTrailing.setChecked(settings.REMOVE_TRAILING_SPACES)
        formFeatures.addWidget(self._checkTrailing, 11, 1, 1, 2,
            alignment=Qt.AlignTop)
        #Show Tabs and Spaces
        self._checkShowSpaces = QCheckBox(
            translations.TR_PREFERENCES_EDITOR_CONFIG_SHOW_TABS_AND_SPACES)
        self._checkShowSpaces.setChecked(settings.SHOW_TABS_AND_SPACES)
        formFeatures.addWidget(self._checkShowSpaces, 12, 1, 1, 2,
            alignment=Qt.AlignTop)
        self._allowWordWrap = QCheckBox(
            translations.TR_PREFERENCES_EDITOR_CONFIG_WORD_WRAP)
        self._allowWordWrap.setChecked(settings.ALLOW_WORD_WRAP)
        formFeatures.addWidget(self._allowWordWrap, 13, 1, 1, 2,
            alignment=Qt.AlignTop)
        self._checkForDocstrings = QCheckBox(
            translations.TR_PREFERENCES_EDITOR_CONFIG_CHECK_FOR_DOCSTRINGS)
        self._checkForDocstrings.setChecked(settings.CHECK_FOR_DOCSTRINGS)
        formFeatures.addWidget(self._checkForDocstrings, 14, 1, 1, 2,
            alignment=Qt.AlignTop)

        vbox.addWidget(groupBoxFeatures)
        vbox.addItem(QSpacerItem(0, 10, QSizePolicy.Expanding,
            QSizePolicy.Expanding))

        self.connect(self._preferences, SIGNAL("savePreferences()"), self.save)

    def _enable_check_inline(self, val):
        if val == Qt.Checked:
            self._checkStyle.setChecked(True)

    def _enable_errors_inline(self, val):
        if val == Qt.Checked:
            self._checkErrors.setChecked(True)

    def _disable_check_style(self, val):
        if val == Qt.Unchecked:
            self._checkStyleOnLine.setChecked(False)

    def _disable_show_errors(self, val):
        if val == Qt.Unchecked:
            self._showErrorsOnLine.setChecked(False)

    def _change_tab_spaces(self, val):
        if val == Qt.Unchecked:
            self._spin.setSuffix(
                translations.TR_PREFERENCES_EDITOR_CONFIG_SPACES)
        else:
            self._spin.setSuffix(
                translations.TR_PREFERENCES_EDITOR_CONFIG_TAB_SIZE)

    def save(self):
        qsettings = IDE.ninja_settings()
        qsettings.setValue('preferences/editor/indent', self._spin.value())
        settings.INDENT = self._spin.value()
        endOfLine = self._checkEndOfLine.isChecked()
        qsettings.setValue('preferences/editor/platformEndOfLine', endOfLine)
        settings.USE_PLATFORM_END_OF_LINE = endOfLine
        margin_line = self._spinMargin.value()
        qsettings.setValue('preferences/editor/marginLine', margin_line)
        settings.MARGIN_LINE = margin_line
        settings.pep8mod_update_margin_line_length(margin_line)
        qsettings.setValue('preferences/editor/showMarginLine',
            self._checkShowMargin.isChecked())
        settings.SHOW_MARGIN_LINE = self._checkShowMargin.isChecked()
        settings.UNDERLINE_NOT_BACKGROUND = \
            self._checkHighlightLine.isChecked()
        qsettings.setValue('preferences/editor/errorsUnderlineBackground',
            settings.UNDERLINE_NOT_BACKGROUND)
        qsettings.setValue('preferences/editor/errors',
            self._checkErrors.isChecked())
        settings.FIND_ERRORS = self._checkErrors.isChecked()
        qsettings.setValue('preferences/editor/errorsInLine',
            self._showErrorsOnLine.isChecked())
        settings.ERRORS_HIGHLIGHT_LINE = self._showErrorsOnLine.isChecked()
        qsettings.setValue('preferences/editor/checkStyle',
            self._checkStyle.isChecked())
        settings.CHECK_STYLE = self._checkStyle.isChecked()
        qsettings.setValue('preferences/editor/showMigrationTips',
            self._showMigrationTips.isChecked())
        settings.SHOW_MIGRATION_TIPS = self._showMigrationTips.isChecked()
        qsettings.setValue('preferences/editor/checkStyleInline',
            self._checkStyleOnLine.isChecked())
        settings.CHECK_HIGHLIGHT_LINE = self._checkStyleOnLine.isChecked()
        qsettings.setValue('preferences/editor/centerOnScroll',
            self._checkCenterScroll.isChecked())
        settings.CENTER_ON_SCROLL = self._checkCenterScroll.isChecked()
        qsettings.setValue('preferences/editor/removeTrailingSpaces',
            self._checkTrailing.isChecked())
        settings.REMOVE_TRAILING_SPACES = self._checkTrailing.isChecked()
        qsettings.setValue('preferences/editor/showTabsAndSpaces',
            self._checkShowSpaces.isChecked())
        settings.SHOW_TABS_AND_SPACES = self._checkShowSpaces.isChecked()
        qsettings.setValue('preferences/editor/useTabs',
            self._checkUseTabs.isChecked())
        settings.USE_TABS = self._checkUseTabs.isChecked()
        qsettings.setValue('preferences/editor/allowWordWrap',
            self._allowWordWrap.isChecked())
        settings.ALLOW_WORD_WRAP = self._allowWordWrap.isChecked()
        qsettings.setValue('preferences/editor/checkForDocstrings',
            self._checkForDocstrings.isChecked())
        settings.CHECK_FOR_DOCSTRINGS = self._checkForDocstrings.isChecked()
Example #15
0
class CNSViewerWidget(QWidget):
    def __init__(self, path_to_df=None, df=None, *args, **kwargs):
        super().__init__(*args, **kwargs)
        #Apply QThreading to this step for larger cns files.
        if df is None:
            self.df = read_cns(path_to_df)
        else:
            self.df = df
        self.orig_df = self.df.copy()  #Make copy.
        # self.df.reset_index(inplace=True)
        self.max_rows = 10
        self.render_ui()
        self.map_events()
        self.refresh()
        self.jupyter_notebook_widget.pushVariables({
            "df": self.df,
            "orig_df": self.orig_df,
            "viewer": self.df_widget,
            "refresh": self.refresh,
            "display": self.display
        })

    def display(self, obj):
        try:
            html = obj._repr_html_()
        except:
            html = str(obj)
        self.df_widget.setHtml(html)

    def render_ui(self):
        """Builds the UI"""
        self.tab_widget = QTabWidget()

        #Filter Ops tab
        self.filter_ops_widget = CNSFilterOpsWidget(columns=self.df.columns)
        commands_widget = QWidget()
        self.command_label = QLabel("Command:")
        self.command_text_area = LNTextEdit()
        self.command_text_area.edit.setReadOnly(True)
        self.command_show_button = QPushButton("Apply")
        self.command_editable_checkbox = QCheckBox("Editable")
        self.command_editable_checkbox.setChecked(False)
        commands_widget_layout = QGridLayout()
        commands_widget_layout.addWidget(self.filter_ops_widget, 0, 0, 2, 2,
                                         Qt.AlignTop)
        commands_widget_layout.addWidget(self.command_label, 2, 0, 1, 1,
                                         Qt.AlignLeft | Qt.AlignTop)
        commands_widget_layout.addWidget(self.command_text_area, 3, 0, 2, 2,
                                         Qt.AlignTop)
        commands_widget_layout.addWidget(self.command_editable_checkbox, 5, 0,
                                         1, 0, Qt.AlignLeft)
        commands_widget_layout.addWidget(self.command_show_button, 5, 1, 1, 1,
                                         Qt.AlignRight)
        commands_widget.setLayout(commands_widget_layout)

        # self.tab_widget.addTab(self.filter_ops_widget, "n00b Mode")

        #Commands Tab
        self.tab_widget.addTab(commands_widget, "Raw Commands")

        ipython_filter_widget = QWidget()
        self.jupyter_notebook_widget = QIPythonWidget()
        ipython_filter_widget_layout = QVBoxLayout()
        ipython_filter_widget_layout.addWidget(self.jupyter_notebook_widget)
        ipython_filter_widget.setLayout(ipython_filter_widget_layout)
        self.tab_widget.addTab(ipython_filter_widget, "Jupyter Mode")

        self.view_combobox = QComboBox()
        modes = ["Show First", "Show Last", "All", "Describe", "Filtered"]
        for mode in modes:
            self.view_combobox.addItem(mode)

        self.max_rows_spinbox = QSpinBox()
        #Map the change event to refresh the dataframe.
        self.max_rows_spinbox.setMinimum(0)
        self.max_rows_spinbox.setMaximum(self.df.shape[0])
        self.max_rows_spinbox.setValue(self.max_rows)
        self.max_rows_spinbox.setSuffix(" rows")

        self.refresh_button = QPushButton("Refresh")

        self.df_widget = QTextEdit()
        self.df_widget.setReadOnly(True)

        self.save_button = QPushButton("Save File")

        df_layout = QGridLayout()
        df_layout.addWidget(self.view_combobox, 0, 0)
        df_layout.addWidget(self.max_rows_spinbox, 0, 1)
        df_layout.addWidget(self.refresh_button, 0, 2)
        df_layout.addWidget(self.df_widget, 1, 0, 4, 10)

        layout = QGridLayout()
        layout.addWidget(self.tab_widget, 0, 0, 3, 1,
                         Qt.AlignLeft | Qt.AlignTop)
        layout.addLayout(df_layout, 0, 1, 7, 7)
        layout.addWidget(self.save_button, 3, 0, 1, 1, Qt.AlignLeft)
        self.setLayout(layout)

    def map_events(self):
        self.refresh_button.clicked.connect(self.refresh)
        self.view_combobox.currentIndexChanged.connect(self.toggle_max_rows)
        self.command_show_button.clicked.connect(self.exec_command)
        self.filter_ops_widget.add_signal.connect(self.add_filter_op)
        self.command_editable_checkbox.stateChanged.connect(
            self.toggle_command_area)

    def toggle_command_area(self):
        self.command_text_area.edit.setReadOnly(not (
            self.command_editable_checkbox.isChecked()))

    def add_filter_op(self):
        command = self.filter_ops_widget.get_command_string()
        existing_commands = str(
            self.command_text_area.edit.toPlainText()).strip()
        if existing_commands != "":
            command = "\n{}".format(command)
        self.command_text_area.edit.appendPlainText(command)
        self.filter_ops_widget.reset()

    def exec_command(self):
        #Reset df to original.
        self.df = self.orig_df.copy()
        command = str(self.command_text_area.getText())
        try:
            exec(command)
        except Exception as e:
            print("Failed to execute!")
            print(repr(e))
        self.view_combobox.setCurrentIndex(4)
        self.refresh()

    def toggle_max_rows(self):
        mode = str(self.view_combobox.currentText()).lower()
        if mode in ["show first", "show last"]:
            self.max_rows_spinbox.setEnabled(True)
        else:
            self.max_rows_spinbox.setEnabled(False)

    def refresh(self):
        mode = str(self.view_combobox.currentText()).lower()
        if mode == "show first":
            self.max_rows = self.max_rows_spinbox.value()
            self.df_widget.setHtml(self.df.head(n=self.max_rows)._repr_html_())
        elif mode == "show last":
            self.max_rows = self.max_rows_spinbox.value()
            self.df_widget.setHtml(self.df.tail(n=self.max_rows)._repr_html_())
        elif mode == "describe":
            self.df_widget.setHtml(self.df.describe()._repr_html_())
        elif mode == "filtered":
            self.df_widget.setHtml(self.df._repr_html_())
        else:
            self.df_widget.setHtml(self.df._repr_html_())
Example #16
0
class TabLaTeX(Panel_simple):
    titre = u"Tableaux LaTeX" # Donner un titre a chaque module

    def __init__(self, *args, **kw):
        Panel_simple.__init__(self, *args, **kw)

        self.sizer = QVBoxLayout()

        self.entree = LigneCommande(self, longueur = 500, action = self.generer_code)
        self.sizer.addWidget(self.entree)

        self.sizer_type = QHBoxLayout()
        self.type_tableau = QComboBox(self)
        self.type_tableau.addItems([u"Tableau de variations", u"Tableau de signes",
                                    u"Tableau de valeurs"])
        self.type_tableau.setCurrentIndex(self._param_.mode)
        self.sizer_type.addWidget(QLabel(u"Type de tableau :", self))
        self.sizer_type.addWidget(self.type_tableau)
        self.sizer_type.addSpacing(15)

        self.utiliser_cellspace = QCheckBox(u"Utiliser le paquetage cellspace.", self)
        self.utiliser_cellspace.setChecked(self._param_.utiliser_cellspace)
        self.utiliser_cellspace.setToolTip(u"Le paquetage cellspace évite que "
                "certains objets (comme les fractions) touchent les bordures du tableaux.")
        self.sizer_type.addSpacing(10)
        self.sizer_type.addWidget(self.utiliser_cellspace)

        self.derivee = QCheckBox(u"Dérivée.", self)
        self.derivee.setChecked(self._param_.derivee)
        self.derivee.setToolTip(u"Afficher une ligne indiquant le signe de la dérivée.")
        self.sizer_type.addSpacing(10)
        self.sizer_type.addWidget(self.derivee)

        self.limites = QCheckBox(u"Limites.", self)
        self.limites.setChecked(self._param_.limites)
        self.limites.setToolTip(u"Afficher les limites dans le tableau de variations.")
        self.sizer_type.addSpacing(10)
        self.sizer_type.addWidget(self.limites)

        self.decimales_tabvar = QSpinBox()
        self.decimales_tabvar.setRange(-1, 20)
        self.decimales_tabvar.setSuffix(u" décimales")
        self.decimales_tabvar.setSpecialValueText(u"Valeurs exactes")
        self.decimales_tabvar.setValue(self._param_.decimales_tabvar)
        ##self.decimales_tabvar.setAccelerated(True)
        aide = u"Nombre de décimales pour l'affichage des extrema, ou valeur exacte."
        self.decimales_tabvar.setToolTip(aide)
        self.sizer_type.addSpacing(10)
        self.sizer_type.addWidget(self.decimales_tabvar)

        self.decimales_tabval = QSpinBox()
        self.decimales_tabval.setRange(0, 20)
        self.decimales_tabval.setSuffix(u" décimales")
        self.decimales_tabval.setValue(self._param_.decimales_tabval)
        ##self.decimales_tabval.setAccelerated(True)
        aide = u"Nombre de décimales pour les valeurs du tableau."
        self.decimales_tabval.setToolTip(aide)
        self.sizer_type.addSpacing(10)
        self.sizer_type.addWidget(self.decimales_tabval)

        self.sizer_type.addSpacing(15)
        self.lbl_formatage = lbl = QLabel(u"Formatage des résultats :")
        self.sizer_type.addWidget(lbl)
        self.formatage_images = QLineEdit()
        ##self.formatage_images.setMinimumWidth(200)
        self.formatage_images.setText(self._param_.formatage_images)
        aide = u"Formatage à appliquer au résultat (VAL est la valeur du résultat)."
        lbl.setToolTip(aide)
        self.formatage_images.setToolTip(aide)
        self.sizer_type.addSpacing(10)
        self.sizer_type.addWidget(self.formatage_images)

        self.sizer_type.addStretch()

        self.sizer.addLayout(self.sizer_type)

        box = QGroupBox(u"Code LaTeX permettant de de générer le tableau", self)
        self.bsizer = QVBoxLayout()
        box.setLayout(self.bsizer)

        self.code_tableau = QTextEdit(self)
        self.code_tableau.setMinimumSize(700, 200)
        self.code_tableau.setReadOnly(True)
        self.bsizer.addWidget(self.code_tableau)

        self.copier_code = QPushButton(u"Copier dans le presse-papier", self)
        self.bsizer.addWidget(self.copier_code)

        txt = u"Pensez à rajouter dans l'entête de votre fichier LaTeX la ligne suivante :"
        self.bsizer.addWidget(QLabel(txt, self))

        self.sizer_entete = QHBoxLayout()
        self.code_entete = QLineEdit(self)
        self.code_entete.setMinimumWidth(200)
        self.code_entete.setReadOnly(True)
        self.code_entete.setText(u"\\usepackage{tabvar}")
        self.sizer_entete.addWidget(self.code_entete)
        self.copier_entete = QPushButton(u"Copier cette ligne", self)
        self.sizer_entete.addWidget(self.copier_entete)

        self.bsizer.addLayout(self.sizer_entete)

        self.sizer.addWidget(box)


        self.cb = QCheckBox(u"Copier automatiquement le code LaTeX dans le presse-papier.", self)
        self.cb.setChecked(self._param_.copie_automatique)
        self.sizer.addWidget(self.cb)

        self.setLayout(self.sizer)
        self.adjustSize()

        self.type_tableau.currentIndexChanged.connect(self.EvtChoix)
        self.EvtChoix()

        def copier_code():
            return self.vers_presse_papier(self.code_tableau.toPlainText())
        self.copier_code.clicked.connect(copier_code)

        def copier_entete():
            return self.vers_presse_papier(self.code_entete.text())
        self.copier_entete.clicked.connect(copier_entete)

        def regler_mode_copie():
            self._param_.copie_automatique = self.cb.isChecked()
            if self._param_.copie_automatique:
                copier_code()
        self.cb.stateChanged.connect(regler_mode_copie)

        def regler_cellspace():
            self._param_.utiliser_cellspace = self.utiliser_cellspace.isChecked()
            if self._param_.utiliser_cellspace:
                self.code_entete.setText(u"\\usepackage{cellspace}")
            else:
                self.code_entete.setText(u"")
            self.valider()
        self.utiliser_cellspace.stateChanged.connect(regler_cellspace)

        def regler_parametres(event=None):
            self._param_.derivee = self.derivee.isChecked()
            self._param_.limites = self.limites.isChecked()
            self._param_.formatage_images = self.formatage_images.text()
            self.valider()

        def regler_decimales(event=None):
            try:
                self.focus_widget = app.focusWidget()
                self._param_.decimales_tabvar = self.decimales_tabvar.value()
                self._param_.decimales_tabval = self.decimales_tabval.value()
                self.valider()
            finally:
                self.focus_widget = self.entree

        self.derivee.stateChanged.connect(regler_parametres)
        self.limites.stateChanged.connect(regler_parametres)
        self.formatage_images.editingFinished.connect(regler_parametres)
        self.decimales_tabvar.valueChanged.connect(regler_decimales)
        self.decimales_tabval.valueChanged.connect(regler_decimales)

        self.focus_widget = self.entree


    def activer(self):
        Panel_simple.activer(self)
        # Actions à effectuer lorsque l'onglet devient actif
        self.entree.setFocus()


    def generer_code(self, commande, **kw):
        if not commande.strip():
            return
        # Utilisé pour la sauvegarde automatique:x+3

        self.modifie = True
        try:
            if self._param_.mode == 0:
                code_latex = tabvar(commande, derivee=self._param_.derivee,
                                    limites=self._param_.limites,
                                    decimales=self._param_.decimales_tabvar,
                                    approche=(self._param_.decimales_tabvar != -1))
            elif self._param_.mode == 1:
                code_latex = tabsign(commande, cellspace=self._param_.utiliser_cellspace)
            elif self._param_.mode == 2:
                code_latex = tabval(commande,
                    formatage_antecedents=self._param_.formatage_antecedents,
                    formatage_images=self._param_.formatage_images,
                    precision=10**-self._param_.decimales_tabval)
            else:
                warning("Type de tableau non reconnu.")

            self.code_tableau.setText(code_latex)
            if self._param_.copie_automatique:
                self.vers_presse_papier(texte = code_latex)
            self.focus_widget.setFocus()
            self.message(u"Le code LaTeX a bien été généré.")
        except BaseException, erreur:
            self.message(u"Impossible de générer le code LaTeX. " + message(erreur))
            self.code_tableau.setText(u"<i><b>Erreur.</b> Impossible de générer le code LaTeX.</i>")
            self.entree.setFocus()
            if param.debug:
                raise
    def initSettingTab(self):
        # ##Setting Tab###
        setting_tab = QWidget()
        setting_tab_layout = QVBoxLayout()
        self.tabWidget.addTab(setting_tab, "Settings")

        # Task Box
        task_box = QGroupBox()
        task_box.setTitle(QString("Task properties"))
        task_layout = QGridLayout()

        # Name
        name = QLabel("Name:")
        name_value = QLineEdit() 
        name_value.setText(self.task.hittypename)
        name_value.setEnabled(False)
        clickable(name_value).connect(self.enable)
        task_layout.addWidget(name, 0, 1)
        task_layout.addWidget(name_value, 0, 2, 1, 3)

        # Description
        description = QLabel("Description:")
        description_value = QLineEdit() 
        description_value.setText(self.task.description)
        description_value.setEnabled(False)
        clickable(description_value).connect(self.enable)
        task_layout.addWidget(description, 1, 1)
        task_layout.addWidget(description_value, 1, 2, 1, 3)

        # Keywords
        keywords = QLabel("Keywords:")
        keywords_value = QLineEdit()
        keywords_value.setText(','.join(self.task.keywords))
        keywords_value.setEnabled(False)
        clickable(keywords_value).connect(self.enable)
        task_layout.addWidget(keywords, 2, 1)
        task_layout.addWidget(keywords_value, 2, 2, 1, 3)

        # Qualification
        qualification = QLabel("Qualification [%]:")
        qualification_value = QSpinBox()
        qualification_value.setSuffix('%')
        qualification_value.setValue(int(self.task.qualification))
        qualification_value.setEnabled(False)
        clickable(qualification_value).connect(self.enable)
        task_layout.addWidget(qualification, 3, 1)
        task_layout.addWidget(qualification_value, 3, 4)

        # Assignments
        assignments = QLabel("Assignments:")
        assignments_value = QSpinBox()
        assignments_value.setSuffix('')
        assignments_value.setValue(int(self.task.assignments))
        assignments_value.setEnabled(False)
        clickable(assignments_value).connect(self.enable)
        task_layout.addWidget(assignments, 4, 1)
        task_layout.addWidget(assignments_value, 4, 4)

        # Duration
        duration = QLabel("Duration [min]:") 
        duration_value = QSpinBox()
        duration_value.setSuffix('min')
        duration_value.setValue(int(self.task.duration))
        duration_value.setEnabled(False)
        clickable(duration_value).connect(self.enable)
        task_layout.addWidget(duration, 5, 1)
        task_layout.addWidget(duration_value, 5, 4)

        # Reward
        reward = QLabel("Reward [0.01$]:")
        reward_value = QDoubleSpinBox()
        reward_value.setRange(0.01, 0.5)
        reward_value.setSingleStep(0.01)
        reward_value.setSuffix('$')
        reward_value.setValue(self.task.reward)
        reward_value.setEnabled(False)
        clickable(reward_value).connect(self.enable)
        task_layout.addWidget(reward, 6, 1)
        task_layout.addWidget(reward_value, 6, 4)

        # Lifetime
        lifetime = QLabel("Lifetime [d]:")
        lifetime_value = QSpinBox()
        lifetime_value.setSuffix('d')
        lifetime_value.setValue(self.task.lifetime)
        lifetime_value.setEnabled(False)
        clickable(lifetime_value).connect(self.enable)
        task_layout.addWidget(lifetime, 7, 1)
        task_layout.addWidget(lifetime_value, 7, 4)

        # sandbox
        sandbox = QCheckBox("Sandbox")
        sandbox.setChecked(self.task.sandbox)
        task_layout.addWidget(sandbox, 8, 1)
        task_box.setLayout(task_layout)
        task_layout.setColumnMinimumWidth(1, 120)

        # Image Storage Box
        storage_box = QGroupBox()
        storage_box.setTitle(QString("Image Storage"))
        storage_layout = QGridLayout()

        # Host URL
        host_url = QLabel("Host-URL:")
        host_url_value = QLineEdit()
        host_url_value.setText(self.task.host_url)
        host_url_value.setEnabled(False)
        clickable(host_url_value).connect(self.enable)

        # Dropbox Path
        dropbox_path = QLabel("Dropbox-Path:")
        dropbox_path_value = QLineEdit()
        dropbox_path_value.setText(self.task.dropbox_path)
        dropbox_path_value.setEnabled(False)
        clickable(dropbox_path_value).connect(self.enable)

        # Dropbox or S3
        usingS3 = QRadioButton("S3")
        usingS3.setChecked(self.task.usingS3)
        usingS3.setEnabled(False)
        usingDropbox = QRadioButton("Dropbox")
        usingDropbox.setChecked(self.task.usingDropbox)

        storage_layout.addWidget(host_url, 0, 1)
        storage_layout.addWidget(host_url_value, 0, 2, 1, 3)
        storage_layout.addWidget(dropbox_path, 1, 1)
        storage_layout.addWidget(dropbox_path_value, 1, 2, 1, 3)

        # Add Layouts
        save_button = QPushButton("Save Settings")
        setting_tab_layout.addWidget(task_box)
        setting_tab_layout.addWidget(storage_box)
        setting_tab.setLayout(setting_tab_layout)
        save_button.clicked.connect(self.SaveSettings)

        storage_layout.addWidget(usingS3, 2, 1)
        storage_layout.addWidget(usingDropbox, 3, 1)
        storage_layout.addWidget(save_button, 3, 4)

        # storage_layout.addStretch(1)
        storage_box.setLayout(storage_layout)
Example #18
0
class MusicView(preferences.Group):
    def __init__(self, page):
        super(MusicView, self).__init__(page)

        layout = QGridLayout()
        self.setLayout(layout)

        self.newerFilesOnly = QCheckBox(toggled=self.changed)
        layout.addWidget(self.newerFilesOnly, 0, 0, 1, 3)

        self.magnifierSizeLabel = QLabel()
        self.magnifierSizeSlider = QSlider(Qt.Horizontal,
                                           valueChanged=self.changed)
        self.magnifierSizeSlider.setSingleStep(50)
        self.magnifierSizeSlider.setRange(
            *popplerview.MagnifierSettings.sizeRange)
        self.magnifierSizeSpinBox = QSpinBox()
        self.magnifierSizeSpinBox.setRange(
            *popplerview.MagnifierSettings.sizeRange)
        self.magnifierSizeSpinBox.valueChanged.connect(
            self.magnifierSizeSlider.setValue)
        self.magnifierSizeSlider.valueChanged.connect(
            self.magnifierSizeSpinBox.setValue)
        layout.addWidget(self.magnifierSizeLabel, 1, 0)
        layout.addWidget(self.magnifierSizeSlider, 1, 1)
        layout.addWidget(self.magnifierSizeSpinBox, 1, 2)

        self.magnifierScaleLabel = QLabel()
        self.magnifierScaleSlider = QSlider(Qt.Horizontal,
                                            valueChanged=self.changed)
        self.magnifierScaleSlider.setSingleStep(50)
        self.magnifierScaleSlider.setRange(
            *popplerview.MagnifierSettings.scaleRange)
        self.magnifierScaleSpinBox = QSpinBox()
        self.magnifierScaleSpinBox.setRange(
            *popplerview.MagnifierSettings.scaleRange)
        self.magnifierScaleSpinBox.valueChanged.connect(
            self.magnifierScaleSlider.setValue)
        self.magnifierScaleSlider.valueChanged.connect(
            self.magnifierScaleSpinBox.setValue)
        layout.addWidget(self.magnifierScaleLabel, 2, 0)
        layout.addWidget(self.magnifierScaleSlider, 2, 1)
        layout.addWidget(self.magnifierScaleSpinBox, 2, 2)

        self.enableKineticScrolling = QCheckBox(toggled=self.changed)
        layout.addWidget(self.enableKineticScrolling)
        self.showScrollbars = QCheckBox(toggled=self.changed)
        layout.addWidget(self.showScrollbars)
        app.translateUI(self)

    def translateUI(self):
        self.setTitle(_("Music View"))
        self.newerFilesOnly.setText(_("Only load updated PDF documents"))
        self.newerFilesOnly.setToolTip(
            _("If checked, Frescobaldi will not open PDF documents that are not\n"
              "up-to-date (i.e. the source file has been modified later)."))
        self.magnifierSizeLabel.setText(_("Magnifier Size:"))
        self.magnifierSizeLabel.setToolTip(
            _("Size of the magnifier glass (Ctrl+Click in the Music View)."))
        # L10N: as in "400 pixels", appended after number in spinbox, note the leading space
        self.magnifierSizeSpinBox.setSuffix(_(" pixels"))
        self.magnifierScaleLabel.setText(_("Magnifier Scale:"))
        self.magnifierScaleLabel.setToolTip(
            _("Magnification of the magnifier."))
        self.magnifierScaleSpinBox.setSuffix(_("percent unit sign", "%"))
        # L10N: "Kinetic Scrolling" is a checkbox label, as in "Enable Kinetic Scrolling"
        self.enableKineticScrolling.setText(_("Kinetic Scrolling"))
        self.showScrollbars.setText(_("Show Scrollbars"))

    def loadSettings(self):
        s = popplerview.MagnifierSettings.load()
        self.magnifierSizeSlider.setValue(s.size)
        self.magnifierScaleSlider.setValue(s.scale)

        s = QSettings()
        s.beginGroup("musicview")
        newerFilesOnly = s.value("newer_files_only", True, bool)
        self.newerFilesOnly.setChecked(newerFilesOnly)
        kineticScrollingActive = s.value("kinetic_scrolling", True, bool)
        self.enableKineticScrolling.setChecked(kineticScrollingActive)
        showScrollbars = s.value("show_scrollbars", True, bool)
        self.showScrollbars.setChecked(showScrollbars)

    def saveSettings(self):
        s = popplerview.MagnifierSettings()
        s.size = self.magnifierSizeSlider.value()
        s.scale = self.magnifierScaleSlider.value()
        s.save()

        s = QSettings()
        s.beginGroup("musicview")
        s.setValue("newer_files_only", self.newerFilesOnly.isChecked())
        s.setValue("kinetic_scrolling",
                   self.enableKineticScrolling.isChecked())
        s.setValue("show_scrollbars", self.showScrollbars.isChecked())
        def initGui():
            def setData():
                buttonPath.setText(self.data["path"])
                radioVisual.setChecked(self.data["isVisual"])
                radioAnalytic.setChecked(not self.data["isVisual"])
                chkBoxSquare.setChecked(self.data["isSquare"])
                d1 = self.data["date1"]
                d2 = self.data["date2"]
                date1.setDate(d1)
                date2.setDate(d2)
                date1.setMaximumDate(d2.addDays(-1))
                date2.setMinimumDate(d1.addDays(+1))
                spinDay.setValue(d1.daysTo(d2))

            def connect():
                buttonOK.clicked.connect(self.onOK)
                buttonPath.clicked.connect(self.onPath)
                date1.dateChanged.connect(self.onDateChanged1)
                date2.dateChanged.connect(self.onDateChanged2)
                spinDay.valueChanged.connect(self.onValueChanged)

            windowTitle = "Setting download images Planet Labs"
            self.setWindowTitle(windowTitle)
            self.setWindowIcon(icon)

            grpImage = QGroupBox("Images", self)
            radioVisual = QRadioButton("Visual", grpImage)
            radioVisual.setObjectName("rbVisual")
            radioAnalytic = QRadioButton("Analytic", grpImage)
            chkBoxSquare = QCheckBox("Square thumbnail", grpImage)
            chkBoxSquare.setObjectName("cbBoxSquare")
            buttonPath = QPushButton(self.titleSelectDirectory, grpImage)
            buttonPath.setObjectName("pbPath")

            layoutRadioButtons = QHBoxLayout()
            for item in (radioVisual, radioAnalytic):
                layoutRadioButtons.addWidget(item)

            layoutImage = QVBoxLayout(grpImage)
            layoutImage.addLayout(layoutRadioButtons)
            layoutImage.addWidget(chkBoxSquare)
            layoutImage.addWidget(buttonPath)

            grpDateSearch = QGroupBox("Dates for search", self)
            date1 = QDateEdit(grpDateSearch)
            date1.setObjectName("deDate1")
            date2 = QDateEdit(grpDateSearch)
            date2.setObjectName("deDate2")
            for item in [date1, date2]:
                item.setCalendarPopup(True)
                format = item.displayFormat().replace("yy", "yyyy")
                item.setDisplayFormat(format)
            spinDay = QSpinBox(grpDateSearch)
            spinDay.setObjectName("sbDay")
            spinDay.setSingleStep(1)
            spinDay.setSuffix(" Days")
            spinDay.setRange(1, 1000 * 360)

            layoutDate = QHBoxLayout(grpDateSearch)
            layoutDate.addWidget(QLabel("From", grpDateSearch))
            layoutDate.addWidget(date1)
            layoutDate.addWidget(QLabel("To", grpDateSearch))
            layoutDate.addWidget(date2)
            layoutDate.addWidget(spinDay)

            buttonOK = QPushButton("OK", self)

            layout = QVBoxLayout(self)
            layout.addWidget(grpImage)
            layout.addWidget(grpDateSearch)
            layout.addWidget(buttonOK)

            self.resize(5 * len(windowTitle) + 200, 30)

            if not self.data is None:
                setData()
            else:
                radioVisual.setChecked(True)
                radioAnalytic.setChecked(False)
                chkBoxSquare.setChecked(False)
                d2 = QDate.currentDate()
                d1 = d2.addMonths(-1)
                date1.setDate(d1)
                date2.setDate(d2)
                date1.setMaximumDate(d2.addDays(-1))
                date2.setMinimumDate(d1.addDays(+1))
                spinDay.setValue(d1.daysTo(d2))

            connect()
class ProjectXively(QWidget):

    qtcb_update_illuminance = pyqtSignal(float)
    qtcb_update_air_pressure = pyqtSignal(float)
    qtcb_update_temperature = pyqtSignal(float)
    qtcb_update_humidity = pyqtSignal(float)
    qtcb_button_pressed = pyqtSignal(int)

    lcdwidget = None

    xively_host = "api.xively.com"
    xively_agent = "Tinkerforge Starter Kit Weather Station Demo"
    xively_channel = "Enter Feed ID here"
    xively_api_key = "Enter API Key here"

    xively_items = {}
    xively_headers = None
    xively_params = ""
    xively_update_rate = 5 # in minutes

    text_agent = None
    text_channel = None
    text_api_key = None
    number_update_rate = None

    save_button = None

    xively_timer = None

    error_message = None

    label_upload_active = None

    last_upload = None

    def __init__(self, parent, app):
        super(QWidget, self).__init__()

        self.lcdwidget = LCDWidget(self, app)
        self.lcdwidget.hide()

        self.text_agent = QLineEdit(self)
        self.text_agent.setText(self.xively_agent)
        
        self.text_channel = QLineEdit(self)
        self.text_channel.setText(self.xively_channel)
        
        self.text_api_key = QLineEdit(self)
        self.text_api_key.setText(self.xively_api_key)
        
        self.number_update_rate = QSpinBox(self)
        self.number_update_rate.setRange(1, 1440)
        self.number_update_rate.setSuffix(' min')
        self.number_update_rate.setValue(self.xively_update_rate)

        layout1 = QHBoxLayout()
        layout2 = QVBoxLayout()
        
        layout1.addStretch()
        layout1.addLayout(layout2)
        layout1.addStretch()
        
        layout2.addSpacerItem(QSpacerItem(LCDWidget.FIXED_WIDGTH, 0))

        label = QLabel(self)
        label.setText("Project: <b>Connect to Xively</b>. This project uploads the measured values to Xively. Please find documentation how to configure it and program sources in Python <a href=\"http://www.tinkerforge.com/en/doc/Kits/WeatherStation/WeatherStation.html#connect-to-xively\">here</a>.<br>")
        label.setTextFormat(Qt.RichText)
        label.setTextInteractionFlags(Qt.TextBrowserInteraction)
        label.setOpenExternalLinks(True)
        label.setWordWrap(True)
        label.setAlignment(Qt.AlignJustify)

        layout2.addSpacing(10)
        layout2.addWidget(label)
        layout2.addSpacing(10)

        layout3a = QHBoxLayout()
        label = QLabel("Agent Description:")
        label.setMinimumWidth(150)
        layout3a.addWidget(label)
        layout3a.addWidget(self.text_agent, 1)

        layout2.addLayout(layout3a)
        layout2.addSpacing(10)

        layout3b = QHBoxLayout()
        label = QLabel("Feed:")
        label.setMinimumWidth(150)
        layout3b.addWidget(label)
        layout3b.addWidget(self.text_channel, 1)

        layout2.addLayout(layout3b)
        layout2.addSpacing(10)

        layout3c = QHBoxLayout()
        label = QLabel("API Key:")
        label.setMinimumWidth(150)
        layout3c.addWidget(label)
        layout3c.addWidget(self.text_api_key, 1)

        layout2.addLayout(layout3c)
        layout2.addSpacing(10)

        layout3d = QHBoxLayout()
        label = QLabel("Update Rate:")
        label.setMinimumWidth(150)
        layout3d.addWidget(label)
        layout3d.addWidget(self.number_update_rate, 1)

        layout2.addLayout(layout3d)
        layout2.addSpacing(10)

        self.label_upload_active = QLabel("Not Active", self)
        self.label_upload_active.setMinimumWidth(150)
        font = QFont()
        font.setPixelSize(20)
        self.label_upload_active.setFont(font)
        self.set_active_label(False)

        self.save_button = QPushButton("Save/Activate")

        layout4 = QHBoxLayout()
        layout4.addWidget(self.label_upload_active)
        layout4.addWidget(self.save_button, 1)

        layout2.addLayout(layout4)
        layout2.addStretch()

        self.setLayout(layout1)

        self.qtcb_update_illuminance.connect(self.update_illuminance_data_slot)
        self.qtcb_update_air_pressure.connect(self.update_air_pressure_data_slot)
        self.qtcb_update_temperature.connect(self.update_temperature_data_slot)
        self.qtcb_update_humidity.connect(self.update_humidity_data_slot)
        self.qtcb_button_pressed.connect(self.button_pressed_slot)
        self.save_button.clicked.connect(self.save_configuration)

        self.lcdwidget.clear(self)

        self.error_message = QErrorMessage(self)

    def set_active_label(self, value):
        palette = self.label_upload_active.palette()
        if value:
            palette.setColor(self.foregroundRole(), Qt.darkGreen)
            self.label_upload_active.setText("Active")
        else:
            palette.setColor(self.foregroundRole(), Qt.red)
            self.label_upload_active.setText("Not Active")

        self.label_upload_active.setPalette(palette)

    def save_configuration(self):
        try:
            self.xively_agent = str(self.text_agent.text()).decode('ascii')
            self.xively_channel = str(self.text_channel.text()).decode('ascii')
            self.xively_api_key = str(self.text_api_key.text()).decode('ascii')
        except:
            self.error_message.showMessage('Agent, Feed and API Key can only contain ASCII characters')
            return

        self.xively_update_rate = self.number_update_rate.value()

        self.xively_headers = {
            "Content-Type"  : "application/x-www-form-urlencoded",
            "X-ApiKey"      : self.xively_api_key,
            "User-Agent"    : self.xively_agent,
        }
        self.xively_params = "/v2/feeds/" + self.xively_channel

        if self.xively_timer is None:
            self.xively_timer = QTimer(self)
            self.xively_timer.timeout.connect(self.update_xively)
            self.xively_timer.start(self.xively_update_rate*60*1000)

        self.set_active_label(True)
        self.update_xively()

    def write_lcd(self):
        if self.last_upload == None:
            tmp = "Last: Never"
        else:
            tmp = "Last: " + self.last_upload

        self.lcdwidget.write_line(0, 0, "Xively Upload", self)
        self.lcdwidget.write_line(2, 0, tmp, self)

    def update_xively(self):
        if len(self.xively_items) == 0:
            return

        stream_items = []
        for identifier, value in self.xively_items.items():
            stream_items.append({'id': identifier,
                                 'current_value': value[0],
                                 'min_value': value[1],
                                 'max_value': value[2]})

        data = {'version': '1.0.0',
                    'datastreams': stream_items}
        self.xively_items = {}
        body = json.dumps(data)

        try:
            http = httplib.HTTPSConnection(self.xively_host)
            http.request('PUT', self.xively_params, body, self.xively_headers)
            response = http.getresponse()
            http.close()

            if response.status != 200:
                self.error_message.showMessage('Could not upload to xively -> Response:' +
                          str(response.status) + ': ' + response.reason + '. Check your configuration.')
                self.xively_timer.stop()
                self.xively_timer = None
                self.set_active_label(False)
                return
        except Exception as e:
            self.error_message.showMessage('HTTP error: ' + str(e))
            self.xively_timer.stop()
            self.xively_timer = None
            self.set_active_label(False)
            return

        # set upload time if upload was a success
        self.last_upload = time.strftime("%H:%M:%S")


    def put(self, identifier, value):
        self.write_lcd()
        try:
            _, min_value, max_value = self.xively_items[identifier]
            if value < min_value:
                min_value = value
            if value > max_value:
                max_value = value
            self.xively_items[identifier] = (value, min_value, max_value)
        except:
            self.xively_items[identifier] = (value, value, value)

    def update_illuminance_data_slot(self, illuminance):
        self.put('AmbientLight', illuminance/10.0)

    def update_illuminance(self, illuminance):
        self.qtcb_update_illuminance.emit(illuminance)

    def update_humidity_data_slot(self, humidity):
        self.put('Humidity', humidity/10.0)
    
    def update_humidity(self, humidity):
        self.qtcb_update_humidity.emit(humidity)

    def update_air_pressure_data_slot(self, air_pressure):
        self.put('AirPressure', air_pressure/1000.0)
    
    def update_air_pressure(self, air_pressure):
        self.qtcb_update_air_pressure.emit(air_pressure)

    def update_temperature_data_slot(self, temperature):
        self.put('Temperature', temperature/100.0)

    def update_temperature(self, temperature):
        self.qtcb_update_temperature.emit(temperature)

    def button_pressed_slot(self, button):
        pass

    def button_pressed(self, button):
        self.qtcb_button_pressed.emit(button)
Example #21
0
class ProprietesAffichage(QWidget):
    def __init__(self, parent):
        QWidget.__init__(self, parent)
        self.parent = parent
        self.panel = self.parent.parent.panel
        self.canvas = self.panel.canvas
        self.islabel = self.parent.parent.islabel
        self.objets = parent.objets
        self.sizer = QVBoxLayout()

        self.changements = {} # ce dictionnaire contiendra tous les styles modifiés
        encadre = QHBoxLayout()

        if not self.islabel:
            proprietes = {'fixe': u'Objet fixe', 'visible': u'Objet visible', 'trace': u'Laisser une trace'}
            for propriete, titre in proprietes.items():
                self.add_checkbox(encadre, propriete, titre)
            encadre.addStretch()


        encadre1 = QVBoxLayout()
        if not self.islabel:
            ligne = QHBoxLayout()
            if len(self.objets) == 1:
                self.etiquette = etiquette = QLineEdit()
                etiquette.setText(self.objets[0].legende)
                etiquette.setMinimumWidth(200)
                etiquette.editingFinished.connect(self.EvtEtiquette)
                ligne.addWidget(etiquette)
            if [objet for objet in self.objets if objet.etiquette is not None]:
                editer = QPushButton(u"Style")
                editer.clicked.connect(self.EvtLabelStyle)
                ligne.addWidget(editer)
            encadre1.addLayout(ligne)

            objets = [objet for objet in self.objets if objet.mode_affichage is not None]
            if objets:
                mode = objets[0].mode_affichage
                legende = QHBoxLayout()
                self.radios = OrderedDict((
                        (NOM, QRadioButton("Nom")),
                        (TEXTE, QRadioButton(u"Texte")),
                        (FORMULE, QRadioButton(u"Formule")),
                        (RIEN, QRadioButton(u"Aucun")),
                              ))
                if all(objet.mode_affichage == mode for objet in objets):
                    self.radios[mode].setChecked(True)

                for mode, radio in self.radios.iteritems():
                    radio.toggled.connect(partial(self.EvtMode, mode))
                    legende.addWidget(radio)

                legende.addStretch()
                encadre1.addWidget(QLabel(u"Afficher : "))
                encadre1.addLayout(legende)



        encadre2 = QVBoxLayout()

        objets = [objet for objet in self.objets if objet.style("style") is not None]
        # on ne peut regler les styles simultanement que pour des objets de meme categorie
        categorie = objets and objets[0].style("categorie") or None

        if objets and categorie and all(objet.style("categorie") == categorie for objet in objets):
            choix = QHBoxLayout()
            choix.addWidget(QLabel(u"Style de l'objet : "))

            #categorie = objets[0].style("categorie") or "lignes"
            self.liste_styles = getattr(param, "styles_de_" + categorie, [])
            self.style = QComboBox()
            self.style.addItems(self.liste_styles)
            self.style.currentIndexChanged.connect(self.EvtStyle)

            style = objets[0].style("style")
            if style in self.liste_styles and all(objet.style("style") == style for objet in objets):
                self.style.setCurrentIndex(self.liste_styles.index(style)) # on sélectionne le style actuel
            choix.addWidget(self.style)
            choix.addStretch()
            encadre2.addLayout(choix)


        objets = [objet for objet in self.objets if objet.style("hachures") is not None]
        if objets:
            choix = QHBoxLayout()
            choix.addWidget(QLabel(u"Style des hâchures : "))

            self.types_de_hachures = getattr(param, "types_de_hachures", [])
            self.hachures = QComboBox()
            self.hachures.addItems(self.types_de_hachures)
            self.hachures.currentIndexChanged.connect(self.EvtHachures)

            hachures = objets[0].style("hachures")
            if hachures in self.types_de_hachures and all(objet.style("hachures") == hachures for objet in objets):
                self.hachures.setCurrentIndex(self.types_de_hachures.index(hachures)) # on sélectionne les hachures actuelles
            choix.addWidget(self.hachures)
            choix.addStretch()
            encadre2.addLayout(choix)


        objets = [objet for objet in self.objets if objet.style("famille") is not None]
        categorie = objets and objets[0].style("categorie") or None

        if objets and categorie and all(objet.style("categorie") == categorie for objet in objets):
            choix = QHBoxLayout()
            choix.addWidget(QLabel("Police : "))

            #categorie = self.objet.style("categorie") or "lignes"
            self.liste_familles = getattr(param, "familles_de_" + categorie, [])
            self.famille = QComboBox()
            self.famille.addItems(self.liste_familles)
            self.famille.currentIndexChanged.connect(self.EvtFamille)

            famille = objets[0].style("famille")
            if famille in self.liste_familles and all(objet.style("famille") == famille for objet in objets):
                self.famille.setCurrentIndex(self.liste_familles.index(famille)) # on sélectionne la famille actuelle

            choix.addWidget(self.famille)
            choix.addStretch()
            encadre2.addLayout(choix)


        objets = [objet for objet in self.objets if objet.style("couleur") is not None]
        if objets:
            couleur = objets[0].style("couleur")
            choix = QHBoxLayout()
            choix.addWidget(QLabel(u"Couleur de l'objet : "))
            if all(objet.style("couleur") == couleur for objet in objets):
                # conversion du format matplotlib au format Qt
                r, g, b = colorConverter.to_rgb(couleur)
                couleur = QColor(int(255*r), int(255*g), int(255*b))
            else:
                couleur = None
            b = ColorSelecter(self, color=couleur)
            b.colorSelected.connect(self.OnSelectColour)
            choix.addWidget(b)
            choix.addStretch()
            encadre2.addLayout(choix)


        objets = [objet for objet in self.objets if objet.style("epaisseur") is not None]
        if objets:
            epaiss = objets[0].style("epaisseur")
            epaisseur = QHBoxLayout()
            epaisseur.addWidget(QLabel(u"Epaisseur (en 10e de pixels) : "))
            self.epaisseur = QSpinBox()
            self.epaisseur.setMinimumWidth(30)
            self.epaisseur.setRange(1, 10000)
            if all(objet.style("epaisseur") == epaiss for objet in objets):
                self.epaisseur.setValue(10*epaiss)
            else:
                self.epaisseur.setSpecialValueText(' ')
                print(u'FIXME: cas non géré.')
            self.epaisseur.valueChanged.connect(self.EvtEpaisseur)
            epaisseur.addWidget(self.epaisseur)
            epaisseur.addStretch()
            encadre2.addLayout(epaisseur)


        objets = [objet for objet in self.objets if objet.style("taille") is not None]
        if objets:
            tail = objets[0].style("taille")
            taille = QHBoxLayout()
            taille.addWidget(QLabel(u"Taille (en 10e de pixels) : "))
            self.taille = QSpinBox()
            self.taille.setMinimumWidth(30)
            self.taille.setRange(1,10000)
            if all(objet.style("taille") == tail for objet in objets):
                self.taille.setValue(10*tail)
            else:
                self.taille.setSpecialValueText(' ')
                print(u'FIXME: cas non géré.')
            self.taille.valueChanged.connect(self.EvtTaille)
            taille.addWidget(self.taille)
            taille.addStretch()
            encadre2.addLayout(taille)


        objets = [objet for objet in self.objets if objet.style("position") is not None]
        if objets:
            pos = objets[0].style("position")
            position = QHBoxLayout()
            position.addWidget(QLabel(u"Position de la flêche : "))
            self.position = QSpinBox()
            self.position.setMinimumWidth(30)
            self.position.setRange(0, 100)
            if all(objet.style("position") == pos for objet in objets):
                self.position.setValue(100*pos)
            else:
                self.position.setSpecialValueText(' ')
                print(u'FIXME: cas non géré.')
            self.position.valueChanged.connect(self.EvtPosition)
            position.addWidget(self.position)
            position.addStretch()
            encadre2.addLayout(position)



        objets = [objet for objet in self.objets if objet.style("angle") is not None]
        if objets:
            ang = objets[0].style("angle")
            angle = QHBoxLayout()
            angle.addWidget(QLabel(u"Angle (en degré) : "))
            self.angle = QSpinBox()
            self.angle.setMinimumWidth(30)
            self.angle.setRange(-180, 180)
            self.angle.setSpecialValueText('auto')
            self.angle.setSuffix(u'°');
            self.angle.setWrapping(True)
            if all(objet.style("angle") == ang for objet in objets):
                self.angle.setValue(ang if ang != 'auto' else -180)
            else:
                self.angle.setSpecialValueText(' ')
                print(u'FIXME: cas non géré.')
            self.angle.valueChanged.connect(self.EvtAngle)
            angle.addWidget(self.angle)
            angle.addStretch()
            encadre2.addLayout(angle)

        self.add_checkbox(encadre, 'double_fleche', u"Flêche double")

        objets = [objet for objet in self.objets if objet.style("codage") is not None]
        # on ne peut regler les codages simultanement que pour des objets de meme categorie
        categorie = objets and objets[0].style("categorie") or None


        if objets and categorie and all(objet.style("categorie") == categorie for objet in objets):
            choix = QHBoxLayout()
            choix.addWidget(QLabel("Codage : "))

            #categorie = objets[0].style("categorie") or "lignes"
            self.liste_codages = getattr(param, "codage_des_" + categorie, [])
            self.codage = QComboBox()
            self.codage.addItems(self.liste_codages)
            self.codage.currentIndexChanged.connect(self.EvtCodage)

            codage = objets[0].style("codage")
            if codage in self.liste_codages and all(objet.style("codage") == codage for objet in objets):
                self.codage.setCurrentIndex(self.liste_codages.index(codage)) # on sélectionne le codage actuel
            choix.addWidget(self.codage)
            encadre2.addLayout(choix)


        boutons = QHBoxLayout()
        ok = QPushButton('OK')
        ok.clicked.connect(self.EvtOk)
        boutons.addWidget(ok)

        appliquer = QPushButton(u"Appliquer")
        appliquer.clicked.connect(self.EvtAppliquer)
        boutons.addWidget(appliquer)

        if not self.islabel:
            supprimer = QPushButton(u"Supprimer")
            supprimer.clicked.connect(self.EvtSupprimer)
            boutons.addWidget(supprimer)

        annuler = QPushButton(u"Annuler")
        annuler.clicked.connect(self.EvtAnnuler)
        boutons.addWidget(annuler)

        if encadre.count(): # ne pas afficher une rubrique vide !
            encadre_box = QGroupBox(u"Mode d'affichage")
            encadre_box.setLayout(encadre)
            self.sizer.addWidget(encadre_box)
        if encadre1.count():
            encadre1_box = QGroupBox(u"Etiquette")
            encadre1_box.setLayout(encadre1)
            self.sizer.addWidget(encadre1_box)
        if encadre2.count():
            encadre2_box = QGroupBox(u"Styles")
            encadre2_box.setLayout(encadre2)
            self.sizer.addWidget(encadre2_box)
        self.sizer.addLayout(boutons)
        self.setLayout(self.sizer)
        ##self.parent.parent.dim1 = self.sizer.CalcMin().Get()


    def add_checkbox(self, layout, propriete, titre):
        objets = [objet for objet in self.objets if objet.style(propriete) is not None]
        if objets:
            cb = QCheckBox(titre)
            cb.setTristate(True)
            layout.addWidget(cb)
            verifies = [objet.style(propriete) is True for objet in objets]
            if not any(verifies):
                etat = Qt.Unchecked
            elif all(verifies):
                etat = Qt.Checked
            else:
                etat = Qt.PartiallyChecked
            cb.setCheckState(etat)
            cb.stateChanged.connect(partial(self.checked, propriete=propriete))
            cb.stateChanged.connect(partial(cb.setTristate, False))


    def EvtMode(self, valeur):
        self.changements["mode"] = valeur

    def checked(self, state, propriete):
        # Bug avec Qt 4.8.1 - En cochant la case la première fois, on obtient
        # Qt.PartiallyChecked, et non Qt.Checked. Si ensuite, on décoche et on
        # recoche, on obtient bien Qt.Checked.
        self.changements[propriete] = (state != Qt.Unchecked)

    def EvtEtiquette(self):
        self.changements["label"] = self.etiquette.text()

    def OnSelectColour(self, color):
        # conversion du format Qt au format matplotlib
        r, g, b, a = color.getRgb()
        self.changements["couleur"] = (r/255, g/255, b/255, a/255)

    def EvtStyle(self, index):
        self.changements["style"] = self.liste_styles[index]

    def EvtHachures(self, index):
        self.changements["hachures"] = self.types_de_hachures[index]

    def EvtCodage(self, index):
        self.changements["codage"] = self.liste_codages[index]

    def EvtFamille(self, index):
        self.changements["famille"] = self.liste_familles[index]

    def EvtOk(self):
        self.EvtAppliquer()
        self.EvtAnnuler()

    def EvtAppliquer(self):
        with self.canvas.geler_affichage(actualiser=True, sablier=True):
            try:
                for objet in self.objets:
                    changements = self.changements.copy()
                    mode = changements.pop('mode', None)
                    label = changements.pop('label', None)
                    for key in changements.copy():
                        if objet.style(key) is None: # le style n'a pas de sens pour l'objet
                            changements.pop(key)
                    if mode is not None or label is not None:
                        self.canvas.executer(u"%s.label(%s, %s)" %(objet.nom, repr(label), mode))
                        if mode is None:
                            mode = objet.etiquette.style("mode")
                            self.changements["mode"] = mode
                            self.radios[mode].setChecked(True)

                    if self.islabel:
                        self.canvas.executer(u"%s.etiquette.style(**%s)" %(objet.parent.nom, changements))
                    else:
                        self.canvas.executer(u"%s.style(**%s)" %(objet.nom, changements))
            except:
                print_error()


    def EvtSupprimer(self):
        with self.canvas.geler_affichage(actualiser=True, sablier=True):
            for objet in self.objets:
                self.canvas.executer(u"del %s" %objet.nom)
        self.EvtAnnuler()

    def EvtAnnuler(self):
        # Ce qui suit corrige un genre de bug bizarre de wx:
        # quand une fenêtre de sélection de couleur a été affichée,
        # la fenêtre principale passe au second plan à la fermeture de la fenêtre de propriétés ?!?
        # (ce qui est très désagréable dès qu'un dossier est ouvert dans l'explorateur, par exemple !)
        # -> à supprimer avec Qt ?
        self.parent.parent.fenetre_principale.raise_()
        self.parent.parent.close() # fermeture de la frame

    def EvtLabelStyle(self):
        win = Proprietes(self.parent, [objet.etiquette for objet in self.objets
                                       if objet.etiquette is not None], True)
        win.show()


    def EvtEpaisseur(self):
        self.changements["epaisseur"] = self.epaisseur.value()/10

    def EvtTaille(self):
        self.changements["taille"] = self.taille.value()/10

    def EvtAngle(self):
        angle = self.angle.value()
        self.changements["angle"] = (angle if angle != -180 else 'auto')

    def EvtPosition(self):
        self.changements["position"] = self.position.value()/100
Example #22
0
    def add_device_to_tree(self, device):
        # check if device is already added
        if len(device['uid']) > 0:
            for row in range(self.model_devices.rowCount()):
                existing_name = self.model_devices.item(row, 0).text()
                exisitng_uid = self.tree_devices.indexWidget(
                    self.model_devices.item(row, 1).index()).text()

                if device['name'] == existing_name and device[
                        'uid'] == exisitng_uid:
                    EventLogger.info(
                        'Ignoring duplicate device "{0}" with UID "{1}"'.
                        format(device['name'], device['uid']))
                    return

        # add device
        name_item = QStandardItem(device['name'])
        uid_item = QStandardItem('')

        self.model_devices.appendRow([name_item, uid_item])

        edit_uid = QLineEdit()
        edit_uid.setPlaceholderText('Enter UID')
        edit_uid.setValidator(
            QRegExpValidator(QRegExp(
                '^[{0}]{{1,6}}$'.format(BASE58))))  # FIXME: use stricter logic
        edit_uid.setText(device['uid'])

        self.tree_devices.setIndexWidget(uid_item.index(), edit_uid)

        value_specs = device_specs[device['name']]['values']
        parent_item = QStandardItem('Values')

        name_item.appendRow([parent_item, QStandardItem('')])
        self.tree_devices.expand(parent_item.index())

        # add values
        for value_spec in value_specs:
            value_name_item = QStandardItem(value_spec['name'])
            value_interval_item = QStandardItem('')

            parent_item.appendRow([value_name_item, value_interval_item])

            spinbox_interval = QSpinBox()
            spinbox_interval.setRange(0, (1 << 31) - 1)
            spinbox_interval.setSingleStep(1)
            spinbox_interval.setValue(
                device['values'][value_spec['name']]['interval'])
            spinbox_interval.setSuffix(' seconds')

            self.tree_devices.setIndexWidget(value_interval_item.index(),
                                             spinbox_interval)

            if value_spec['subvalues'] != None:
                for subvalue_name in value_spec['subvalues']:
                    subvalue_name_item = QStandardItem(subvalue_name)
                    subvalue_check_item = QStandardItem('')

                    value_name_item.appendRow(
                        [subvalue_name_item, subvalue_check_item])

                    check_subvalue = QCheckBox()
                    check_subvalue.setChecked(device['values'][
                        value_spec['name']]['subvalues'][subvalue_name])

                    self.tree_devices.setIndexWidget(
                        subvalue_check_item.index(), check_subvalue)

        self.tree_devices.expand(name_item.index())

        # add options
        option_specs = device_specs[device['name']]['options']

        if option_specs != None:
            parent_item = QStandardItem('Options')

            name_item.appendRow([parent_item, QStandardItem('')])

            for option_spec in option_specs:
                option_name_item = QStandardItem(option_spec['name'])
                option_widget_item = QStandardItem('')

                parent_item.appendRow([option_name_item, option_widget_item])

                if option_spec['type'] == 'choice':
                    widget_option_value = QComboBox()

                    for option_value_spec in option_spec['values']:
                        widget_option_value.addItem(
                            option_value_spec[0].decode('utf-8'),
                            option_value_spec[1])

                    widget_option_value.setCurrentIndex(
                        widget_option_value.findText(device['options'][
                            option_spec['name']]['value'].decode('utf-8')))
                elif option_spec['type'] == 'int':
                    widget_option_value = QSpinBox()
                    widget_option_value.setRange(option_spec['minimum'],
                                                 option_spec['maximum'])
                    widget_option_value.setSuffix(option_spec['suffix'])
                    widget_option_value.setValue(
                        device['options'][option_spec['name']]['value'])
                elif option_spec['type'] == 'bool':
                    widget_option_value = QCheckBox()
                    widget_option_value.setChecked(
                        device['options'][option_spec['name']]['value'])

                self.tree_devices.setIndexWidget(option_widget_item.index(),
                                                 widget_option_value)
Example #23
0
    def add_device_to_tree(self, device):
        # check if device is already added
        if len(device['uid']) > 0:
            for row in range(self.model_devices.rowCount()):
                existing_name = self.model_devices.item(row, 0).text()
                exisitng_uid = self.tree_devices.indexWidget(self.model_devices.item(row, 1).index()).text()

                if device['name'] == existing_name and device['uid'] == exisitng_uid:
                    EventLogger.info('Ignoring duplicate device "{0}" with UID "{1}"'
                                     .format(device['name'], device['uid']))
                    return

        # add device
        name_item = QStandardItem(device['name'])
        uid_item = QStandardItem('')

        self.model_devices.appendRow([name_item, uid_item])

        edit_uid = QLineEdit()
        edit_uid.setPlaceholderText('Enter UID')
        edit_uid.setValidator(QRegExpValidator(QRegExp('^[{0}]{{1,6}}$'.format(BASE58)))) # FIXME: use stricter logic
        edit_uid.setText(device['uid'])

        self.tree_devices.setIndexWidget(uid_item.index(), edit_uid)

        value_specs = device_specs[device['name']]['values']
        parent_item = QStandardItem('Values')

        name_item.appendRow([parent_item, QStandardItem('')])
        self.tree_devices.expand(parent_item.index())

        # add values
        for value_spec in value_specs:
            value_name_item = QStandardItem(value_spec['name'])
            value_interval_item = QStandardItem('')

            parent_item.appendRow([value_name_item, value_interval_item])

            spinbox_interval = QSpinBox()
            spinbox_interval.setRange(0, (1 << 31) - 1)
            spinbox_interval.setSingleStep(1)
            spinbox_interval.setValue(device['values'][value_spec['name']]['interval'])
            spinbox_interval.setSuffix(' seconds')

            self.tree_devices.setIndexWidget(value_interval_item.index(), spinbox_interval)

            if value_spec['subvalues'] != None:
                for subvalue_name in value_spec['subvalues']:
                    subvalue_name_item = QStandardItem(subvalue_name)
                    subvalue_check_item = QStandardItem('')

                    value_name_item.appendRow([subvalue_name_item, subvalue_check_item])

                    check_subvalue = QCheckBox()
                    check_subvalue.setChecked(device['values'][value_spec['name']]['subvalues'][subvalue_name])

                    self.tree_devices.setIndexWidget(subvalue_check_item.index(), check_subvalue)

        self.tree_devices.expand(name_item.index())

        # add options
        option_specs = device_specs[device['name']]['options']

        if option_specs != None:
            parent_item = QStandardItem('Options')

            name_item.appendRow([parent_item, QStandardItem('')])

            for option_spec in option_specs:
                option_name_item = QStandardItem(option_spec['name'])
                option_widget_item = QStandardItem('')

                parent_item.appendRow([option_name_item, option_widget_item])

                if option_spec['type'] == 'choice':
                    widget_option_value = QComboBox()

                    for option_value_spec in option_spec['values']:
                        widget_option_value.addItem(option_value_spec[0].decode('utf-8'), option_value_spec[1])

                    widget_option_value.setCurrentIndex(widget_option_value.findText(device['options'][option_spec['name']]['value'].decode('utf-8')))
                elif option_spec['type'] == 'int':
                    widget_option_value = QSpinBox()
                    widget_option_value.setRange(option_spec['minimum'], option_spec['maximum'])
                    widget_option_value.setSuffix(option_spec['suffix'])
                    widget_option_value.setValue(device['options'][option_spec['name']]['value'])
                elif option_spec['type'] == 'bool':
                    widget_option_value = QCheckBox()
                    widget_option_value.setChecked(device['options'][option_spec['name']]['value'])

                self.tree_devices.setIndexWidget(option_widget_item.index(), widget_option_value)
class Window(QMainWindow):

    def __init__(self, parent=None):
        super(Window, self).__init__(parent)
        self.image = QImage()
        self.dirty = False
        self.filename = None
        self.mirroredvertically = False
        self.mirroredhorizontally = False
        self.printer = None
        self.create_widgets()
        self.create_actions()
        self.load_settings()
        self.setWindowTitle("Image Changer")
        self.updateFileMenu()
        QTimer.singleShot(0, self.loadInitialFile)


    def create_widgets(self):
        self.imageLabel = QLabel()
        self.imageLabel.setMinimumSize(200, 200)
        self.imageLabel.setAlignment(Qt.AlignCenter)
        self.imageLabel.setContextMenuPolicy(Qt.ActionsContextMenu)
        self.setCentralWidget(self.imageLabel)

        logDockWidget = QDockWidget("Log", self)
        logDockWidget.setObjectName("LogDockWidget")
        logDockWidget.setAllowedAreas(Qt.LeftDockWidgetArea|
                                      Qt.RightDockWidgetArea)
        self.listWidget = QListWidget()
        logDockWidget.setWidget(self.listWidget)
        self.addDockWidget(Qt.RightDockWidgetArea, logDockWidget)

        self.sizeLabel = QLabel()
        self.sizeLabel.setFrameStyle(QFrame.StyledPanel|QFrame.Sunken)
        status = self.statusBar()
        status.setSizeGripEnabled(False)
        status.addPermanentWidget(self.sizeLabel)
        status.showMessage("Ready", 5000)


    def create_actions(self):
        fileNewAction = self.createAction("&New...", self.fileNew,
                QKeySequence.New, "filenew", "Create an image file")
        fileOpenAction = self.createAction("&Open...", self.fileOpen,
                QKeySequence.Open, "fileopen",
                "Open an existing image file")
        fileSaveAction = self.createAction("&Save", self.fileSave,
                QKeySequence.Save, "filesave", "Save the image")
        fileSaveAsAction = self.createAction("Save &As...",
                self.fileSaveAs, icon="filesaveas",
                tip="Save the image using a new name")
        filePrintAction = self.createAction("&Print", self.filePrint,
                QKeySequence.Print, "fileprint", "Print the image")
        fileQuitAction = self.createAction("&Quit", self.close,
                "Ctrl+Q", "filequit", "Close the application")
        editInvertAction = self.createAction("&Invert", None, "Ctrl+I",
                "editinvert", "Invert the image's colors", True)
        editInvertAction.toggled.connect(self.editInvert)
        editSwapRedAndBlueAction = self.createAction("Sw&ap Red and Blue",
                None, "Ctrl+A", "editswap",
                "Swap the image's red and blue color components", True)
        editSwapRedAndBlueAction.toggled.connect(self.editSwapRedAndBlue)
        editZoomAction = self.createAction("&Zoom...", self.editZoom,
                "Alt+Z", "editzoom", "Zoom the image")
        editResizeAction = self.createAction("&Resize...",
                self.editResize, "Ctrl+R", "editresize",
                "Resize the image")
        mirrorGroup = QActionGroup(self)
        editUnMirrorAction = self.createAction("&Unmirror", None, "Ctrl+U",
                "editunmirror", "Unmirror the image", True)
        editUnMirrorAction.toggled.connect(self.editUnMirror)
        mirrorGroup.addAction(editUnMirrorAction)
        editMirrorHorizontalAction = self.createAction(
                "Mirror &Horizontally", None, "Ctrl+H", "editmirrorhoriz",
                "Horizontally mirror the image", True)
        editMirrorHorizontalAction.toggled.connect(
                self.editMirrorHorizontal)
        mirrorGroup.addAction(editMirrorHorizontalAction)
        editMirrorVerticalAction = self.createAction( "Mirror &Vertically",
                None, "Ctrl+V", "editmirrorvert",
                "Vertically mirror the image", True)
        editMirrorVerticalAction.toggled.connect(self.editMirrorVertical)
        mirrorGroup.addAction(editMirrorVerticalAction)
        editUnMirrorAction.setChecked(True)
        helpAboutAction = self.createAction("&About Image Changer",
                self.helpAbout)
        helpHelpAction = self.createAction("&Help", self.helpHelp,
                QKeySequence.HelpContents)

        self.fileMenu = self.menuBar().addMenu("&File")
        self.fileMenuActions = (fileNewAction, fileOpenAction,
                fileSaveAction, fileSaveAsAction, None, filePrintAction,
                fileQuitAction)
        self.fileMenu.aboutToShow.connect(self.updateFileMenu)
        editMenu = self.menuBar().addMenu("&Edit")
        self.addActions(editMenu, (editInvertAction,
                editSwapRedAndBlueAction, editZoomAction,
                editResizeAction))
        mirrorMenu = editMenu.addMenu(QIcon(":/editmirror.png"),
                                      "&Mirror")
        self.addActions(mirrorMenu, (editUnMirrorAction,
                editMirrorHorizontalAction, editMirrorVerticalAction))
        helpMenu = self.menuBar().addMenu("&Help")
        self.addActions(helpMenu, (helpAboutAction, helpHelpAction))

        fileToolbar = self.addToolBar("File")
        fileToolbar.setObjectName("FileToolBar")
        self.addActions(fileToolbar, (fileNewAction, fileOpenAction,
                                      fileSaveAsAction))
        editToolbar = self.addToolBar("Edit")
        editToolbar.setObjectName("EditToolBar")
        self.addActions(editToolbar, (editInvertAction,
                editSwapRedAndBlueAction, editUnMirrorAction,
                editMirrorVerticalAction, editMirrorHorizontalAction))
        self.zoomSpinBox = QSpinBox()
        self.zoomSpinBox.setRange(1, 400)
        self.zoomSpinBox.setSuffix(" %")
        self.zoomSpinBox.setValue(100)
        self.zoomSpinBox.setToolTip("Zoom the image")
        self.zoomSpinBox.setStatusTip(self.zoomSpinBox.toolTip())
        self.zoomSpinBox.setFocusPolicy(Qt.NoFocus)
        self.zoomSpinBox.valueChanged.connect(self.showImage)
        editToolbar.addWidget(self.zoomSpinBox)

        self.addActions(self.imageLabel, (editInvertAction,
                editSwapRedAndBlueAction, editUnMirrorAction,
                editMirrorVerticalAction, editMirrorHorizontalAction))

        self.resetableActions = ((editInvertAction, False),
                                 (editSwapRedAndBlueAction, False),
                                 (editUnMirrorAction, True))


    def load_settings(self):
        settings = QSettings()
        self.recentFiles = settings.value("RecentFiles").toStringList()
        self.restoreGeometry(
                settings.value("MainWindow/Geometry").toByteArray())
        self.restoreState(settings.value("MainWindow/State").toByteArray())


    def createAction(self, text, slot=None, shortcut=None, icon=None,
                     tip=None, checkable=False):
        action = QAction(text, self)
        if icon is not None:
            action.setIcon(QIcon(":/{0}.png".format(icon)))
        if shortcut is not None:
            action.setShortcut(shortcut)
        if tip is not None:
            action.setToolTip(tip)
            action.setStatusTip(tip)
        if slot is not None:
            action.triggered.connect(slot)
        if checkable:
            action.setCheckable(True)
        return action


    def addActions(self, target, actions):
        for action in actions:
            if action is None:
                target.addSeparator()
            else:
                target.addAction(action)


    def closeEvent(self, event):
        if self.okToContinue():
            settings = QSettings()
            filename = (QVariant(QString(self.filename)) 
                        if self.filename is not None else QVariant())
            settings.setValue("LastFile", filename)
            recentFiles = (QVariant(self.recentFiles)
                           if self.recentFiles else QVariant())
            settings.setValue("RecentFiles", recentFiles)
            settings.setValue("MainWindow/Geometry", QVariant(
                              self.saveGeometry()))
            settings.setValue("MainWindow/State", QVariant(
                              self.saveState()))
        else:
            event.ignore()


    def okToContinue(self):
        if self.dirty:
            reply = QMessageBox.question(self,
                    "Image Changer - Unsaved Changes",
                    "Save unsaved changes?",
                    QMessageBox.Yes|QMessageBox.No|QMessageBox.Cancel)
            if reply == QMessageBox.Cancel:
                return False
            elif reply == QMessageBox.Yes:
                return self.fileSave()
        return True


    def loadInitialFile(self):
        settings = QSettings()
        fname = unicode(settings.value("LastFile").toString())
        if fname and QFile.exists(fname):
            self.loadFile(fname)


    def updateStatus(self, message):
        self.statusBar().showMessage(message, 5000)
        self.listWidget.addItem(message)
        if self.filename is not None:
            self.setWindowTitle("Image Changer - {0}[*]".format(
                                os.path.basename(self.filename)))
        elif not self.image.isNull():
            self.setWindowTitle("Image Changer - Unnamed[*]")
        else:
            self.setWindowTitle("Image Changer[*]")
        self.setWindowModified(self.dirty)


    def updateFileMenu(self):
        self.fileMenu.clear()
        self.addActions(self.fileMenu, self.fileMenuActions[:-1])
        current = (QString(self.filename)
                   if self.filename is not None else None)
        recentFiles = []
        for fname in self.recentFiles:
            if fname != current and QFile.exists(fname):
                recentFiles.append(fname)
        if recentFiles:
            self.fileMenu.addSeparator()
            for i, fname in enumerate(recentFiles):
                action = QAction(QIcon(":/icon.png"),
                        "&{0} {1}".format(i + 1, QFileInfo(
                        fname).fileName()), self)
                action.setData(QVariant(fname))
                action.triggered.connect(self.loadFile)
                self.fileMenu.addAction(action)
        self.fileMenu.addSeparator()
        self.fileMenu.addAction(self.fileMenuActions[-1])


    def fileNew(self):
        if not self.okToContinue():
            return
        dialog = newimagedlg.NewImageDlg(self)
        if dialog.exec_():
            self.addRecentFile(self.filename)
            self.image = QImage()
            for action, check in self.resetableActions:
                action.setChecked(check)
            self.image = dialog.image()
            self.filename = None
            self.dirty = True
            self.showImage()
            self.sizeLabel.setText("{0} x {1}".format(self.image.width(),
                                                      self.image.height()))
            self.updateStatus("Created new image")


    def fileOpen(self):
        if not self.okToContinue():
            return
        dir = (os.path.dirname(self.filename)
               if self.filename is not None else ".")
        formats = (["*.{0}".format(unicode(format).lower())
                for format in QImageReader.supportedImageFormats()])
        fname = unicode(QFileDialog.getOpenFileName(self,
                "Image Changer - Choose Image", dir,
                "Image files ({0})".format(" ".join(formats))))
        if fname:
            self.loadFile(fname)


    def loadFile(self, fname=None):
        if fname is None:
            action = self.sender()
            if isinstance(action, QAction):
                fname = unicode(action.data().toString())
                if not self.okToContinue():
                    return
            else:
                return
        if fname:
            self.filename = None
            image = QImage(fname)
            if image.isNull():
                message = "Failed to read {0}".format(fname)
            else:
                self.addRecentFile(fname)
                self.image = QImage()
                for action, check in self.resetableActions:
                    action.setChecked(check)
                self.image = image
                self.filename = fname
                self.showImage()
                self.dirty = False
                self.sizeLabel.setText("{0} x {1}".format(
                                       image.width(), image.height()))
                message = "Loaded {0}".format(os.path.basename(fname))
            self.updateStatus(message)


    def addRecentFile(self, fname):
        if fname is None:
            return
        if not self.recentFiles.contains(fname):
            self.recentFiles.prepend(QString(fname))
            while self.recentFiles.count() > 9:
                self.recentFiles.takeLast()


    def fileSave(self):
        if self.image.isNull():
            return True
        if self.filename is None:
            return self.fileSaveAs()
        else:
            if self.image.save(self.filename, None):
                self.updateStatus("Saved as {0}".format(self.filename))
                self.dirty = False
                return True
            else:
                self.updateStatus("Failed to save {0}".format(
                                  self.filename))
                return False


    def fileSaveAs(self):
        if self.image.isNull():
            return True
        fname = self.filename if self.filename is not None else "."
        formats = (["*.{0}".format(unicode(format).lower())
                for format in QImageWriter.supportedImageFormats()])
        fname = unicode(QFileDialog.getSaveFileName(self,
                "Image Changer - Save Image", fname,
                "Image files ({0})".format(" ".join(formats))))
        if fname:
            if "." not in fname:
                fname += ".png"
            self.addRecentFile(fname)
            self.filename = fname
            return self.fileSave()
        return False


    def filePrint(self):
        if self.image.isNull():
            return
        if self.printer is None:
            self.printer = QPrinter(QPrinter.HighResolution)
            self.printer.setPageSize(QPrinter.Letter)
        form = QPrintDialog(self.printer, self)
        if form.exec_():
            painter = QPainter(self.printer)
            rect = painter.viewport()
            size = self.image.size()
            size.scale(rect.size(), Qt.KeepAspectRatio)
            painter.setViewport(rect.x(), rect.y(), size.width(),
                                size.height())
            painter.drawImage(0, 0, self.image)


    def editInvert(self, on):
        if self.image.isNull():
            return
        self.image.invertPixels()
        self.showImage()
        self.dirty = True
        self.updateStatus("Inverted" if on else "Uninverted")


    def editSwapRedAndBlue(self, on):
        if self.image.isNull():
            return
        self.image = self.image.rgbSwapped()
        self.showImage()
        self.dirty = True
        self.updateStatus(("Swapped Red and Blue"
                           if on else "Unswapped Red and Blue"))


    def editUnMirror(self, on):
        if self.image.isNull():
            return
        if self.mirroredhorizontally:
            self.editMirrorHorizontal(False)
        if self.mirroredvertically:
            self.editMirrorVertical(False)


    def editMirrorHorizontal(self, on):
        if self.image.isNull():
            return
        self.image = self.image.mirrored(True, False)
        self.showImage()
        self.mirroredhorizontally = not self.mirroredhorizontally
        self.dirty = True
        self.updateStatus(("Mirrored Horizontally"
                           if on else "Unmirrored Horizontally"))


    def editMirrorVertical(self, on):
        if self.image.isNull():
            return
        self.image = self.image.mirrored(False, True)
        self.showImage()
        self.mirroredvertically = not self.mirroredvertically
        self.dirty = True
        self.updateStatus(("Mirrored Vertically"
                           if on else "Unmirrored Vertically"))


    def editZoom(self):
        if self.image.isNull():
            return
        percent, ok = QInputDialog.getInteger(self,
                "Image Changer - Zoom", "Percent:",
                self.zoomSpinBox.value(), 1, 400)
        if ok:
            self.zoomSpinBox.setValue(percent)


    def editResize(self):
        if self.image.isNull():
            return
        form = resizedlg.ResizeDlg(self.image.width(),
                                   self.image.height(), self)
        if form.exec_():
            width, height = form.result()
            if (width == self.image.width() and
                height == self.image.height()):
                self.statusBar().showMessage("Resized to the same size",
                                             5000)
            else:
                self.image = self.image.scaled(width, height)
                self.showImage()
                self.dirty = True
                size = "{0} x {1}".format(self.image.width(),
                                          self.image.height())
                self.sizeLabel.setText(size)
                self.updateStatus("Resized to {0}".format(size))


    def showImage(self, percent=None):
        if self.image.isNull():
            return
        if percent is None:
            percent = self.zoomSpinBox.value()
        factor = percent / 100.0
        width = self.image.width() * factor
        height = self.image.height() * factor
        image = self.image.scaled(width, height, Qt.KeepAspectRatio)
        self.imageLabel.setPixmap(QPixmap.fromImage(image))


    def helpAbout(self):
        QMessageBox.about(self, "About Image Changer",
                """<b>Image Changer</b> v {0}
                <p>Copyright &copy; 2008 Qtrac Ltd. 
                All rights reserved.
                <p>This application can be used to perform
                simple image manipulations.
                <p>Python {1} - Qt {2} - PyQt {3} on {4}""".format(
                __version__, platform.python_version(),
                QT_VERSION_STR, PYQT_VERSION_STR,
                platform.system()))


    def helpHelp(self):
        form = helpform.HelpForm("index.html", self)
        form.show()
Example #25
0
class ScreenShot(QWidget):
    def __init__(self):
        super(ScreenShot, self).__init__()

        self.initUI()

    def initUI(self):
        self.originalPixmap = QPixmap()

        self.screenshotLabel = QLabel("screenshotlabel", self)
        self.screenshotLabel.setSizePolicy(QSizePolicy.Expanding,
                                           QSizePolicy.Expanding)
        self.screenshotLabel.setAlignment(Qt.AlignCenter)

        self.screenGeometry = QApplication.desktop().screenGeometry(
        )  # Qrect()
        print self.screenGeometry, self.screenGeometry.width()
        self.screenshotLabel.setMinimumSize(self.screenGeometry.width() / 8,
                                            self.screenGeometry.height() / 8)

        mainlayout = QVBoxLayout(self)
        mainlayout.addWidget(self.screenshotLabel)

        self.optionsGroupBox = QGroupBox(u"选项", self)

        self.hideThisWindowCheckBox = QCheckBox(u"隐藏这个窗口",
                                                self.optionsGroupBox)
        self.optionsGroupBoxLayout = QGridLayout(self.optionsGroupBox)

        mainlayout.addWidget(self.optionsGroupBox)
        self.delaySpinBox = QSpinBox(self.optionsGroupBox)
        self.delaySpinBox.setSuffix(u"s")
        self.delaySpinBox.setMaximum(60)

        self.optionsGroupBoxLayout.addWidget(QLabel(u"截屏延时:", self), 0, 0)
        self.optionsGroupBoxLayout.addWidget(self.delaySpinBox, 0, 1)
        self.optionsGroupBoxLayout.addWidget(self.hideThisWindowCheckBox, 1, 0)

        buttonLayout = QHBoxLayout()

        self.newScreenshotButton = QPushButton(u"新截图", self)
        self.newScreenshotButton.clicked.connect(self.__newScreenshot)
        buttonLayout.addWidget(self.newScreenshotButton)

        saveScreenshotButton = QPushButton(u"保存截图", self)
        buttonLayout.addWidget(saveScreenshotButton)

        quitScreenshotButton = QPushButton(u"退出截图", self)
        quitScreenshotButton.setShortcut("Ctrl+Q")
        buttonLayout.addWidget(saveScreenshotButton)
        buttonLayout.addStretch()
        mainlayout.addLayout(buttonLayout)
        quitScreenshotButton.clicked.connect(self.close)

        saveScreenshotButton.clicked.connect(self.__saveScreenshot)
        self.delaySpinBox.valueChanged.connect(self.__updateCheckBox)
        self.delaySpinBox.setValue(5)
        self.setWindowTitle(u"截图")
        self.resize(300, 200)

    def resizeEvent(self, QResizeEvent):
        scaledSize = self.originalPixmap.size()
        scaledSize.scale(self.screenshotLabel.size(), Qt.KeepAspectRatio)
        if (not self.screenshotLabel.pixmap()) or (
                scaledSize != self.screenshotLabel.pixmap().size()):
            self.__updateScreenshotLabel()

    def __newScreenshot(self):
        if self.hideThisWindowCheckBox.isChecked():
            self.hide()

        self.newScreenshotButton.setDisabled(True)

        QTimer.singleShot(self.delaySpinBox.value() * 1000, self.__shootScreen)

    def __saveScreenshot(self):
        format = "png"
        initialPath = QDesktopServices.storageLocation(
            QDesktopServices.PicturesLocation)
        # initialPath = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation);
        if initialPath.isEmpty():
            initialPath = QDir.currentPath()
        initialPath += "/untitled." + format

        fileDialog = QtGui.QFileDialog(self, u"存储为", initialPath)
        fileDialog.setAcceptMode(QtGui.QFileDialog.AcceptSave)
        fileDialog.setFileMode(QtGui.QFileDialog.AnyFile)
        fileDialog.setDirectory(initialPath)
        mimeTypes = QStringList()

        for bf in QImageWriter.supportedImageFormats():
            mimeTypes.append(QLatin1String(bf))

        # fileDialog.setMin setMimeTypeFilters(mimeTypes)
        # fileDialog.selectMimeTypeFilter("image/" + format);
        fileDialog.setDefaultSuffix(format)
        if fileDialog.accept():
            return

        fileName = fileDialog.selectedFiles().first()

        if not self.originalPixmap.save(fileName):
            QtGui.QMessageBox.Warning(
                self, u"保存错误",
                u"图像无法存储到 \"%s\"." % str(QDir.toNativeSeparators(fileName)))

    def __shootScreen(self):

        if self.delaySpinBox.value() != 0:
            QApplication.beep()

        self.originalPixmap = QPixmap.grabWindow(
            QApplication.desktop().winId())
        self.__updateScreenshotLabel()

        self.newScreenshotButton.setDisabled(False)
        if self.hideThisWindowCheckBox.isChecked():
            self.show()

    def __updateCheckBox(self):
        print "sssss"
        if self.delaySpinBox.value() == 0:
            self.hideThisWindowCheckBox.setDisabled(True)
            self.hideThisWindowCheckBox.setChecked(False)
        else:
            self.hideThisWindowCheckBox.setDisabled(False)

    def __updateScreenshotLabel(self):
        self.screenshotLabel.setPixmap(
            self.originalPixmap.scaled(self.screenshotLabel.size(),
                                       Qt.KeepAspectRatio,
                                       Qt.SmoothTransformation))
Example #26
0
class NewSensorgroupPage1(QWizardPage):
    """WizardPage to select constructor values"""
    def __init__(self, parent, project):
        QWizardPage.__init__(self, parent)
        self.setTitle(QCoreApplication.translate('DataStorageBrowser',
            'Select data import properties'))
        self.project = project
        self.mainLayout = QGridLayout()
        self.setLayout(self.mainLayout)

        tsLabel = QLabel(self)
        tsLabel.setText(QCoreApplication.translate('DataStorageBrowser', 'Time step'))
        self.mainLayout.addWidget(tsLabel, 0, 0)
        self.tsInput = QSpinBox(self)
        self.tsInput.setSuffix(' s')
        self.tsInput.setSpecialValueText('---')
        self.tsInput.setMinimum(0)
        self.tsInput.setMaximum(86400)
        self.tsInput.setValue(0)
        self.registerField('timestep', self.tsInput, 'value')
        self.mainLayout.addWidget(self.tsInput, 0, 1)

        tzLabel = QLabel(self)
        tzLabel.setText(QCoreApplication.translate('DataStorageBrowser', 'Time zone'))
        self.mainLayout.addWidget(tzLabel, 1, 0)
        self.tzInput = QSpinBox(self)
        self.tzInput.setMinimum(0)
        self.tzInput.setMaximum(23)
        self.tzInput.setSuffix(' h')
        self.tzInput.setValue(0)
        self.registerField('timezone', self.tzInput, 'value')
        self.mainLayout.addWidget(self.tzInput, 1, 1)

        tfLabel = QLabel(self)
        tfLabel.setText(QCoreApplication.translate('DataStorageBrowser', 'Time format'))
        self.mainLayout.addWidget(tfLabel, 2, 0)
        self.tfInput = QLineEdit(self)
        self.tfInput.setText('')
        self.registerField('timeformat', self.tfInput, 'text')
        self.mainLayout.addWidget(self.tfInput, 2, 1)

        self.delimLabel = QLabel(self)
        self.delimLabel.setText(QCoreApplication.translate('DataStorageBrowser',
            'CSV separator'))
        self.mainLayout.addWidget(self.delimLabel, 3, 0)
        self.delimInput = QLineEdit(self)
        self.delimInput.setMaxLength(1)
        self.delimInput.setText(';')
        self.registerField('delim', self.delimInput, 'text')
        self.mainLayout.addWidget(self.delimInput, 3, 1)

        self.tcolLabel = QLabel(self)
        self.tcolLabel.setText(QCoreApplication.translate('DataStorageBrowser',
            'CSV time column'))
        self.mainLayout.addWidget(self.tcolLabel, 4, 0)
        self.tcolInput = QSpinBox(self)
        self.tcolInput.setMinimum(1)
        self.tcolInput.setMaximum(500)
        self.tcolInput.setValue(2)
        self.registerField('timecol', self.tcolInput, 'value')
        self.mainLayout.addWidget(self.tcolInput, 4, 1)

        self.extraLabel = QLabel(self)
        self.extraLabel.setText(QCoreApplication.translate('DataStorageBrowser',
            'CSV extra headers'))
        self.mainLayout.addWidget(self.extraLabel, 5, 0)
        self.extraInput = QLineEdit(self)
        self.extraInput.setMaxLength(200)
        self.extraInput.setText('Device;Unit;SensorType')
        self.registerField('extra_headers', self.extraInput, 'text')
        self.mainLayout.addWidget(self.extraInput, 5, 1)


    def initializePage(self):
        t = str(self.field('type').toString())
        if t == 'CSV':
            self.tfInput.setText('%d.%m.%Y %H:%M')
            for w in (self.delimLabel, self.delimInput, self.tcolLabel, self.tcolInput,
                    self.extraLabel, self.extraInput):
                w.show()
        elif t == 'Remus':
            self.tfInput.setText('%d.%m.%y %H:%M:%S')
            for w in (self.delimLabel, self.delimInput, self.tcolLabel, self.tcolInput,
                    self.extraLabel, self.extraInput):
                w.hide()
        else:
            raise SimuVis4.Errors.NotImplementedError


    def validatePage(self):
        return True
Example #27
0
class CodePastingDialog(QDialog):

    def __init__(self, parent=None, code=''):
        super(CodePastingDialog, self).__init__(parent)
        self.setWindowTitle(self.tr("Enviar a Pastebin"))
        self.setMinimumSize(700, 500)
        self._parent = parent
        container = QVBoxLayout(self)

        # Thread
        self.thread = code_pasting.Thread()
        self.connect(self.thread, SIGNAL("finished()"),
                     self._paste_result)
        # Campos
        fields_box = QGridLayout()
        fields_box.addWidget(QLabel(self.tr("Expirar después de:")), 0, 0)
        self._spin_expire = QSpinBox()
        self._spin_expire.setSuffix(self.tr(" Días"))
        self._spin_expire.setMinimum(1)
        fields_box.addWidget(self._spin_expire, 0, 1)
        fields_box.addWidget(QLabel(self.tr("Acceso:")), 1, 0)
        self._combo_access = QComboBox()
        self._combo_access.addItems([self.tr("Público"), self.tr("Privado")])
        fields_box.addWidget(self._combo_access, 1, 1)
        fields_box.addWidget(QLabel(self.tr("Nombre:")), 2, 0)
        self._line_filename = QLineEdit()
        place_holder_text = parent.get_active_editor().filename
        self._line_filename.setPlaceholderText(place_holder_text)
        fields_box.addWidget(self._line_filename, 2, 1)
        fields_box.addWidget(QLabel(self.tr("Descripción:")), 3, 0)

        # Editor
        self._code_editor = QPlainTextEdit()
        self._set_editor_style(self._code_editor)
        self._code_editor.setPlainText(code)

        hbox = QHBoxLayout()
        hbox.addItem(QSpacerItem(0, 1, QSizePolicy.Expanding))
        btn_paste = QPushButton(self.tr("Enviar"))
        hbox.addWidget(btn_paste)
        btn_cancel = QPushButton(self.tr("Cancelar"))
        hbox.addWidget(btn_cancel)

        container.addLayout(fields_box)
        container.addWidget(self._code_editor)
        container.addLayout(hbox)

        # Loading widget
        self.loading_widget = loading_widget.LoadingWidget(self)
        self.loading_widget.hide()

        # Conexiones
        self.connect(btn_cancel, SIGNAL("clicked()"), self.close)
        self.connect(btn_paste, SIGNAL("clicked()"), self._emit_data)

    def _emit_data(self):
        code = self._code_editor.toPlainText()
        expire = str(self._spin_expire.value()) + 'D'
        paste_name = self._line_filename.text()
        if not paste_name:
            paste_name = self._parent.get_active_editor().filename
        self.loading_widget.show()
        self.thread.paste(code, paste_name, expire)

    def _paste_result(self):
        self.loading_widget.hide()
        result = self.thread.result
        if result is None:
            QMessageBox.critical(self, self.tr("Error!"),
                                 self.tr("No hay código"))
            return
        QMessageBox.information(self, self.tr("URL"),
                                str(result))
        self.close()

    def _set_editor_style(self, editor):
        style = 'QPlainTextEdit {color: #E2E2E5; background-color: #0E0F12; }'
        editor.setStyleSheet(style)

    def resizeEvent(self, event):
        super(CodePastingDialog, self).resizeEvent(event)
        self.loading_widget.resize(event.size())
Example #28
0
class EditorConfiguration(QWidget):
    def __init__(self, parent):
        super(EditorConfiguration, self).__init__()
        self._preferences = parent
        vbox = QVBoxLayout(self)

        #Indentation
        groupBoxFeatures = QGroupBox(
            translations.TR_PREFERENCES_EDITOR_CONFIG_FEATURES)
        formFeatures = QGridLayout(groupBoxFeatures)
        formFeatures.addWidget(
            QLabel(translations.TR_PREFERENCES_EDITOR_CONFIG_INDENTATION), 1,
            0, Qt.AlignRight)
        self._spin = QSpinBox()
        self._spin.setAlignment(Qt.AlignRight)
        self._spin.setMinimum(1)
        self._spin.setValue(settings.INDENT)
        formFeatures.addWidget(self._spin, 1, 1, alignment=Qt.AlignTop)
        self._checkUseTabs = QCheckBox(
            translations.TR_PREFERENCES_EDITOR_CONFIG_USE_TABS)
        self._checkUseTabs.setChecked(settings.USE_TABS)
        self.connect(self._checkUseTabs, SIGNAL("stateChanged(int)"),
                     self._change_tab_spaces)
        formFeatures.addWidget(self._checkUseTabs, 1, 2, alignment=Qt.AlignTop)
        if settings.USE_TABS:
            self._spin.setSuffix(
                translations.TR_PREFERENCES_EDITOR_CONFIG_TAB_SIZE)
        else:
            self._spin.setSuffix(
                translations.TR_PREFERENCES_EDITOR_CONFIG_SPACES)
        #Margin Line
        formFeatures.addWidget(
            QLabel(translations.TR_PREFERENCES_EDITOR_CONFIG_MARGIN_LINE), 2,
            0, Qt.AlignRight)
        self._spinMargin = QSpinBox()
        self._spinMargin.setMaximum(200)
        self._spinMargin.setValue(settings.MARGIN_LINE)
        formFeatures.addWidget(self._spinMargin, 2, 1, alignment=Qt.AlignTop)
        self._checkShowMargin = QCheckBox(
            translations.TR_PREFERENCES_EDITOR_CONFIG_SHOW_MARGIN_LINE)
        self._checkShowMargin.setChecked(settings.SHOW_MARGIN_LINE)
        formFeatures.addWidget(self._checkShowMargin,
                               2,
                               2,
                               alignment=Qt.AlignTop)
        #End of line
        self._checkEndOfLine = QCheckBox(
            translations.TR_PREFERENCES_EDITOR_CONFIG_END_OF_LINE)
        self._checkEndOfLine.setChecked(settings.USE_PLATFORM_END_OF_LINE)
        formFeatures.addWidget(self._checkEndOfLine,
                               3,
                               1,
                               alignment=Qt.AlignTop)
        #Find Errors
        self._checkHighlightLine = QCheckBox(
            translations.TR_PREFERENCES_EDITOR_CONFIG_ERROR_HIGHLIGHTING)
        self._checkHighlightLine.setChecked(settings.UNDERLINE_NOT_BACKGROUND)
        formFeatures.addWidget(self._checkHighlightLine,
                               4,
                               1,
                               1,
                               2,
                               alignment=Qt.AlignTop)
        self._checkErrors = QCheckBox(
            translations.TR_PREFERENCES_EDITOR_CONFIG_FIND_ERRORS)
        self._checkErrors.setChecked(settings.FIND_ERRORS)
        formFeatures.addWidget(self._checkErrors,
                               5,
                               1,
                               1,
                               2,
                               alignment=Qt.AlignTop)
        self.connect(self._checkErrors, SIGNAL("stateChanged(int)"),
                     self._disable_show_errors)
        self._showErrorsOnLine = QCheckBox(
            translations.TR_PREFERENCES_EDITOR_CONFIG_SHOW_TOOLTIP_ERRORS)
        self._showErrorsOnLine.setChecked(settings.ERRORS_HIGHLIGHT_LINE)
        self.connect(self._showErrorsOnLine, SIGNAL("stateChanged(int)"),
                     self._enable_errors_inline)
        formFeatures.addWidget(self._showErrorsOnLine, 6, 2, 1, 1, Qt.AlignTop)
        #Find Check Style
        self._checkStyle = QCheckBox(
            translations.TR_PREFERENCES_EDITOR_CONFIG_SHOW_PEP8)
        self._checkStyle.setChecked(settings.CHECK_STYLE)
        formFeatures.addWidget(self._checkStyle,
                               7,
                               1,
                               1,
                               2,
                               alignment=Qt.AlignTop)
        self.connect(self._checkStyle, SIGNAL("stateChanged(int)"),
                     self._disable_check_style)
        self._checkStyleOnLine = QCheckBox(
            translations.TR_PREFERENCES_EDITOR_CONFIG_SHOW_TOOLTIP_PEP8)
        self._checkStyleOnLine.setChecked(settings.CHECK_HIGHLIGHT_LINE)
        self.connect(self._checkStyleOnLine, SIGNAL("stateChanged(int)"),
                     self._enable_check_inline)
        formFeatures.addWidget(self._checkStyleOnLine, 8, 2, 1, 1, Qt.AlignTop)
        # Python3 Migration
        self._showMigrationTips = QCheckBox(
            translations.TR_PREFERENCES_EDITOR_CONFIG_SHOW_MIGRATION)
        self._showMigrationTips.setChecked(settings.SHOW_MIGRATION_TIPS)
        formFeatures.addWidget(self._showMigrationTips, 9, 1, 1, 2,
                               Qt.AlignTop)
        #Center On Scroll
        self._checkCenterScroll = QCheckBox(
            translations.TR_PREFERENCES_EDITOR_CONFIG_CENTER_SCROLL)
        self._checkCenterScroll.setChecked(settings.CENTER_ON_SCROLL)
        formFeatures.addWidget(self._checkCenterScroll,
                               10,
                               1,
                               1,
                               2,
                               alignment=Qt.AlignTop)
        #Remove Trailing Spaces add Last empty line automatically
        self._checkTrailing = QCheckBox(
            translations.TR_PREFERENCES_EDITOR_CONFIG_REMOVE_TRAILING)
        self._checkTrailing.setChecked(settings.REMOVE_TRAILING_SPACES)
        formFeatures.addWidget(self._checkTrailing,
                               11,
                               1,
                               1,
                               2,
                               alignment=Qt.AlignTop)
        #Show Tabs and Spaces
        self._checkShowSpaces = QCheckBox(
            translations.TR_PREFERENCES_EDITOR_CONFIG_SHOW_TABS_AND_SPACES)
        self._checkShowSpaces.setChecked(settings.SHOW_TABS_AND_SPACES)
        formFeatures.addWidget(self._checkShowSpaces,
                               12,
                               1,
                               1,
                               2,
                               alignment=Qt.AlignTop)
        self._allowWordWrap = QCheckBox(
            translations.TR_PREFERENCES_EDITOR_CONFIG_WORD_WRAP)
        self._allowWordWrap.setChecked(settings.ALLOW_WORD_WRAP)
        formFeatures.addWidget(self._allowWordWrap,
                               13,
                               1,
                               1,
                               2,
                               alignment=Qt.AlignTop)
        self._checkForDocstrings = QCheckBox(
            translations.TR_PREFERENCES_EDITOR_CONFIG_CHECK_FOR_DOCSTRINGS)
        self._checkForDocstrings.setChecked(settings.CHECK_FOR_DOCSTRINGS)
        formFeatures.addWidget(self._checkForDocstrings,
                               14,
                               1,
                               1,
                               2,
                               alignment=Qt.AlignTop)

        vbox.addWidget(groupBoxFeatures)
        vbox.addItem(
            QSpacerItem(0, 10, QSizePolicy.Expanding, QSizePolicy.Expanding))

        self.connect(self._preferences, SIGNAL("savePreferences()"), self.save)

    def _enable_check_inline(self, val):
        if val == Qt.Checked:
            self._checkStyle.setChecked(True)

    def _enable_errors_inline(self, val):
        if val == Qt.Checked:
            self._checkErrors.setChecked(True)

    def _disable_check_style(self, val):
        if val == Qt.Unchecked:
            self._checkStyleOnLine.setChecked(False)

    def _disable_show_errors(self, val):
        if val == Qt.Unchecked:
            self._showErrorsOnLine.setChecked(False)

    def _change_tab_spaces(self, val):
        if val == Qt.Unchecked:
            self._spin.setSuffix(
                translations.TR_PREFERENCES_EDITOR_CONFIG_SPACES)
        else:
            self._spin.setSuffix(
                translations.TR_PREFERENCES_EDITOR_CONFIG_TAB_SIZE)

    def save(self):
        qsettings = IDE.ninja_settings()
        qsettings.setValue('preferences/editor/indent', self._spin.value())
        settings.INDENT = self._spin.value()
        endOfLine = self._checkEndOfLine.isChecked()
        qsettings.setValue('preferences/editor/platformEndOfLine', endOfLine)
        settings.USE_PLATFORM_END_OF_LINE = endOfLine
        margin_line = self._spinMargin.value()
        qsettings.setValue('preferences/editor/marginLine', margin_line)
        settings.MARGIN_LINE = margin_line
        settings.pep8mod_update_margin_line_length(margin_line)
        qsettings.setValue('preferences/editor/showMarginLine',
                           self._checkShowMargin.isChecked())
        settings.SHOW_MARGIN_LINE = self._checkShowMargin.isChecked()
        settings.UNDERLINE_NOT_BACKGROUND = \
            self._checkHighlightLine.isChecked()
        qsettings.setValue('preferences/editor/errorsUnderlineBackground',
                           settings.UNDERLINE_NOT_BACKGROUND)
        qsettings.setValue('preferences/editor/errors',
                           self._checkErrors.isChecked())
        settings.FIND_ERRORS = self._checkErrors.isChecked()
        qsettings.setValue('preferences/editor/errorsInLine',
                           self._showErrorsOnLine.isChecked())
        settings.ERRORS_HIGHLIGHT_LINE = self._showErrorsOnLine.isChecked()
        qsettings.setValue('preferences/editor/checkStyle',
                           self._checkStyle.isChecked())
        settings.CHECK_STYLE = self._checkStyle.isChecked()
        qsettings.setValue('preferences/editor/showMigrationTips',
                           self._showMigrationTips.isChecked())
        settings.SHOW_MIGRATION_TIPS = self._showMigrationTips.isChecked()
        qsettings.setValue('preferences/editor/checkStyleInline',
                           self._checkStyleOnLine.isChecked())
        settings.CHECK_HIGHLIGHT_LINE = self._checkStyleOnLine.isChecked()
        qsettings.setValue('preferences/editor/centerOnScroll',
                           self._checkCenterScroll.isChecked())
        settings.CENTER_ON_SCROLL = self._checkCenterScroll.isChecked()
        qsettings.setValue('preferences/editor/removeTrailingSpaces',
                           self._checkTrailing.isChecked())
        settings.REMOVE_TRAILING_SPACES = self._checkTrailing.isChecked()
        qsettings.setValue('preferences/editor/showTabsAndSpaces',
                           self._checkShowSpaces.isChecked())
        settings.SHOW_TABS_AND_SPACES = self._checkShowSpaces.isChecked()
        qsettings.setValue('preferences/editor/useTabs',
                           self._checkUseTabs.isChecked())
        settings.USE_TABS = self._checkUseTabs.isChecked()
        qsettings.setValue('preferences/editor/allowWordWrap',
                           self._allowWordWrap.isChecked())
        settings.ALLOW_WORD_WRAP = self._allowWordWrap.isChecked()
        qsettings.setValue('preferences/editor/checkForDocstrings',
                           self._checkForDocstrings.isChecked())
        settings.CHECK_FOR_DOCSTRINGS = self._checkForDocstrings.isChecked()
Example #29
0
class MusicView(preferences.Group):
    def __init__(self, page):
        super(MusicView, self).__init__(page)
        
        layout = QGridLayout()
        self.setLayout(layout)

        self.magnifierSizeLabel = QLabel()
        self.magnifierSizeSlider = QSlider(Qt.Horizontal, valueChanged=self.changed)
        self.magnifierSizeSlider.setSingleStep(50)
        self.magnifierSizeSlider.setRange(*popplerview.MagnifierSettings.sizeRange)
        self.magnifierSizeSpinBox = QSpinBox()
        self.magnifierSizeSpinBox.setRange(*popplerview.MagnifierSettings.sizeRange)
        self.magnifierSizeSpinBox.valueChanged.connect(self.magnifierSizeSlider.setValue)
        self.magnifierSizeSlider.valueChanged.connect(self.magnifierSizeSpinBox.setValue)
        layout.addWidget(self.magnifierSizeLabel, 0, 0)
        layout.addWidget(self.magnifierSizeSlider, 0, 1)
        layout.addWidget(self.magnifierSizeSpinBox, 0, 2)
        
        self.magnifierScaleLabel = QLabel()
        self.magnifierScaleSlider = QSlider(Qt.Horizontal, valueChanged=self.changed)
        self.magnifierScaleSlider.setSingleStep(50)
        self.magnifierScaleSlider.setRange(*popplerview.MagnifierSettings.scaleRange)
        self.magnifierScaleSpinBox = QSpinBox()
        self.magnifierScaleSpinBox.setRange(*popplerview.MagnifierSettings.scaleRange)
        self.magnifierScaleSpinBox.valueChanged.connect(self.magnifierScaleSlider.setValue)
        self.magnifierScaleSlider.valueChanged.connect(self.magnifierScaleSpinBox.setValue)
        layout.addWidget(self.magnifierScaleLabel, 1, 0)
        layout.addWidget(self.magnifierScaleSlider, 1, 1)
        layout.addWidget(self.magnifierScaleSpinBox, 1, 2)
        
        self.enableKineticScrolling = QCheckBox(toggled=self.changed)
        layout.addWidget(self.enableKineticScrolling)
        self.showScrollbars = QCheckBox(toggled=self.changed)
        layout.addWidget(self.showScrollbars)
        app.translateUI(self)
        
    def translateUI(self):
        self.setTitle(_("Music View"))
        self.magnifierSizeLabel.setText(_("Magnifier Size:"))
        self.magnifierSizeLabel.setToolTip(_(
            "Size of the magnifier glass (Ctrl+Click in the Music View)."))
        # L10N: as in "400 pixels", appended after number in spinbox, note the leading space
        self.magnifierSizeSpinBox.setSuffix(_(" pixels"))
        self.magnifierScaleLabel.setText(_("Magnifier Scale:"))
        self.magnifierScaleLabel.setToolTip(_(
            "Magnification of the magnifier."))
        self.magnifierScaleSpinBox.setSuffix(_("percent unit sign", "%"))
        # L10N: "Kinetic Scrolling" is a checkbox label, as in "Enable Kinetic Scrolling"
        self.enableKineticScrolling.setText(_("Kinetic Scrolling"))
        self.showScrollbars.setText(_("Show Scrollbars"))
            
    def loadSettings(self):
        s = popplerview.MagnifierSettings.load()
        self.magnifierSizeSlider.setValue(s.size)
        self.magnifierScaleSlider.setValue(s.scale)
        
        ks = QSettings()
        kineticScrollingActive = ks.value("musicview/kinetic_scrolling", True) not in (False, "false")
        self.enableKineticScrolling.setChecked(kineticScrollingActive)
        showScrollbars = ks.value("musicview/show_scrollbars", True) not in (False, "false")
        self.showScrollbars.setChecked(showScrollbars)
    
    def saveSettings(self):
        s = popplerview.MagnifierSettings()
        s.size = self.magnifierSizeSlider.value()
        s.scale = self.magnifierScaleSlider.value()
        s.save()

        ks = QSettings()
        ks.setValue("musicview/kinetic_scrolling", self.enableKineticScrolling.isChecked())
        ks.setValue("musicview/show_scrollbars", self.showScrollbars.isChecked())
Example #30
0
class EditorGeneral(QWidget):
    """EditorGeneral widget class."""

    def __init__(self, parent):
        super(EditorGeneral, self).__init__()
        self._preferences, vbox = parent, QVBoxLayout(self)
        self.original_style = copy.copy(resources.CUSTOM_SCHEME)
        self.current_scheme, self._modified_editors = 'default', []
        self._font = settings.FONT

        groupBoxMini = QGroupBox(
            translations.TR_PREFERENCES_EDITOR_GENERAL_MINIMAP)
        groupBoxTypo = QGroupBox(
            translations.TR_PREFERENCES_EDITOR_GENERAL_TYPOGRAPHY)
        groupBoxScheme = QGroupBox(
            translations.TR_PREFERENCES_EDITOR_GENERAL_SCHEME)

        #Minimap
        formMini = QGridLayout(groupBoxMini)
        formMini.setContentsMargins(5, 15, 5, 5)
        self._checkShowMinimap = QCheckBox(
            translations.TR_PREFERENCES_EDITOR_GENERAL_ENABLE_MINIMAP)
        self._spinMaxOpacity = QSpinBox()
        self._spinMaxOpacity.setRange(0, 100)
        self._spinMaxOpacity.setSuffix("% Max.")
        self._spinMinOpacity = QSpinBox()
        self._spinMinOpacity.setRange(0, 100)
        self._spinMinOpacity.setSuffix("% Min.")
        self._spinSize = QSpinBox()
        self._spinSize.setMaximum(100)
        self._spinSize.setMinimum(0)
        self._spinSize.setSuffix(
            translations.TR_PREFERENCES_EDITOR_GENERAL_AREA_MINIMAP)
        formMini.addWidget(self._checkShowMinimap, 0, 1)
        formMini.addWidget(QLabel(
            translations.TR_PREFERENCES_EDITOR_GENERAL_SIZE_MINIMAP), 1, 0,
            Qt.AlignRight)
        formMini.addWidget(self._spinSize, 1, 1)
        formMini.addWidget(QLabel(
            translations.TR_PREFERENCES_EDITOR_GENERAL_OPACITY), 2, 0,
            Qt.AlignRight)
        formMini.addWidget(self._spinMinOpacity, 2, 1)
        formMini.addWidget(self._spinMaxOpacity, 2, 2)
        #Typo
        gridTypo = QGridLayout(groupBoxTypo)
        gridTypo.setContentsMargins(5, 15, 5, 5)
        self._btnEditorFont = QPushButton('')
        gridTypo.addWidget(QLabel(
            translations.TR_PREFERENCES_EDITOR_GENERAL_EDITOR_FONT), 0, 0,
            Qt.AlignRight)
        gridTypo.addWidget(self._btnEditorFont, 0, 1)
        #Scheme
        vboxScheme = QVBoxLayout(groupBoxScheme)
        vboxScheme.setContentsMargins(5, 15, 5, 5)
        self._listScheme = QListWidget()
        vboxScheme.addWidget(self._listScheme)
        hbox = QHBoxLayout()
        btnDownload = QPushButton(
            translations.TR_PREFERENCES_EDITOR_DOWNLOAD_SCHEME)
        btnDownload.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.connect(btnDownload, SIGNAL("clicked()"),
                     self._open_schemes_manager)
        hbox.addWidget(btnDownload)
        btnAdd = QPushButton(QIcon(":img/add"),
                             translations.TR_EDITOR_CREATE_SCHEME)
        btnAdd.setIconSize(QSize(16, 16))
        btnAdd.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.connect(btnAdd, SIGNAL("clicked()"), self._open_schemes_designer)
        btnRemove = QPushButton(QIcon(":img/delete"),
                                translations.TR_EDITOR_REMOVE_SCHEME)
        btnRemove.setIconSize(QSize(16, 16))
        btnRemove.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.connect(btnRemove, SIGNAL("clicked()"), self._remove_scheme)
        hbox.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding))
        hbox.addWidget(btnAdd)
        hbox.addWidget(btnRemove)
        vboxScheme.addLayout(hbox)

        vbox.addWidget(groupBoxMini)
        vbox.addWidget(groupBoxTypo)
        vbox.addWidget(groupBoxScheme)

        #Settings
        qsettings = IDE.ninja_settings()
        qsettings.beginGroup('preferences')
        qsettings.beginGroup('editor')
        self._checkShowMinimap.setChecked(settings.SHOW_MINIMAP)
        if settings.IS_MAC_OS:
            self._spinMinOpacity.setValue(100)
            self._spinMaxOpacity.setValue(100)
            self._spinMinOpacity.setDisabled(True)
            self._spinMaxOpacity.setDisabled(True)
        else:
            self._spinMinOpacity.setValue(settings.MINIMAP_MIN_OPACITY * 100)
            self._spinMaxOpacity.setValue(settings.MINIMAP_MAX_OPACITY * 100)
        self._spinSize.setValue(settings.SIZE_PROPORTION * 100)
        btnText = ', '.join(self._font.toString().split(',')[0:2])
        self._btnEditorFont.setText(btnText)
        self._listScheme.clear()
        self._listScheme.addItem('default')
        self._schemes = json_manager.load_editor_skins()
        for item in self._schemes:
            self._listScheme.addItem(item)
        items = self._listScheme.findItems(
            qsettings.value('scheme', defaultValue='',
                            type='QString'), Qt.MatchExactly)
        if items:
            self._listScheme.setCurrentItem(items[0])
        else:
            self._listScheme.setCurrentRow(0)
        qsettings.endGroup()
        qsettings.endGroup()

        #Signals
        self.connect(self._btnEditorFont,
                     SIGNAL("clicked()"), self._load_editor_font)
        self.connect(self._listScheme, SIGNAL("itemSelectionChanged()"),
                     self._preview_style)
        self.connect(self._preferences, SIGNAL("savePreferences()"), self.save)

    def _open_schemes_manager(self):
        ninjaide = IDE.get_service("ide")
        ninjaide.show_schemes()
        # refresh schemes

    def _open_schemes_designer(self):
        name = self._listScheme.currentItem().text()
        scheme = self._schemes.get(name, resources.COLOR_SCHEME)
        designer = preferences_editor_scheme_designer.EditorSchemeDesigner(
            scheme, self)
        designer.exec_()
        if designer.saved:
            scheme_name = designer.line_name.text()
            scheme = designer.original_style
            self._schemes[scheme_name] = scheme
            result = self._listScheme.findItems(scheme_name, Qt.MatchExactly)
            if not result:
                self._listScheme.addItem(scheme_name)

    def _remove_scheme(self):
        name = self._listScheme.currentItem().text()
        fileName = ('{0}.color'.format(
            file_manager.create_path(resources.EDITOR_SKINS, name)))
        file_manager.delete_file(fileName)
        item = self._listScheme.takeItem(self._listScheme.currentRow())
        del item

    def hideEvent(self, event):
        super(EditorGeneral, self).hideEvent(event)
        resources.CUSTOM_SCHEME = self.original_style
        for editorWidget in self._modified_editors:
            try:
                editorWidget.restyle(editorWidget.lang)
            except RuntimeError:
                print('the editor has been removed')

    def _preview_style(self):
        scheme = self._listScheme.currentItem().text()
        if scheme == self.current_scheme:
            return
        main_container = IDE.get_service('main_container')
        if not main_container:
            return
        editorWidget = main_container.get_current_editor()
        if editorWidget is not None:
            resources.CUSTOM_SCHEME = self._schemes.get(
                scheme,
                resources.COLOR_SCHEME)
            editorWidget.restyle(editorWidget.lang)
            self._modified_editors.append(editorWidget)
        self.current_scheme = scheme

    def _load_editor_font(self):
        try:
            font, ok = QFontDialog.getFont(self._font, self)
            if ok:
                self._font = font
                btnText = ', '.join(self._font.toString().split(',')[0:2])
                self._btnEditorFont.setText(btnText)
        except:
            QMessageBox.warning(
                self,
                translations.TR_PREFERENCES_EDITOR_GENERAL_FONT_MESSAGE_TITLE,
                translations.TR_PREFERENCES_EDITOR_GENERAL_FONT_MESSAGE_BODY)

    def save(self):
        qsettings = IDE.ninja_settings()
        settings.FONT = self._font
        qsettings.setValue('preferences/editor/font', settings.FONT)
        settings.SHOW_MINIMAP = self._checkShowMinimap.isChecked()
        settings.MINIMAP_MAX_OPACITY = self._spinMaxOpacity.value() / 100.0
        settings.MINIMAP_MIN_OPACITY = self._spinMinOpacity.value() / 100.0
        settings.SIZE_PROPORTION = self._spinSize.value() / 100.0
        qsettings.setValue('preferences/editor/minimapMaxOpacity',
                           settings.MINIMAP_MAX_OPACITY)
        qsettings.setValue('preferences/editor/minimapMinOpacity',
                           settings.MINIMAP_MIN_OPACITY)
        qsettings.setValue('preferences/editor/minimapSizeProportion',
                           settings.SIZE_PROPORTION)
        qsettings.setValue('preferences/editor/minimapShow',
                           settings.SHOW_MINIMAP)
        scheme = self._listScheme.currentItem().text()
        resources.CUSTOM_SCHEME = self._schemes.get(scheme,
                                                    resources.COLOR_SCHEME)
        qsettings.setValue('preferences/editor/scheme', scheme)
Example #31
0
class Indenting(preferences.Group):
    def __init__(self, page):
        super(Indenting, self).__init__(page)

        layout = QGridLayout(spacing=1)
        self.setLayout(layout)

        self.tabwidthBox = QSpinBox(minimum=1, maximum=99)
        self.tabwidthLabel = l = QLabel()
        l.setBuddy(self.tabwidthBox)

        self.nspacesBox = QSpinBox(minimum=0, maximum=99)
        self.nspacesLabel = l = QLabel()
        l.setBuddy(self.nspacesBox)

        self.dspacesBox = QSpinBox(minimum=0, maximum=99)
        self.dspacesLabel = l = QLabel()
        l.setBuddy(self.dspacesBox)

        layout.addWidget(self.tabwidthLabel, 0, 0)
        layout.addWidget(self.tabwidthBox, 0, 1)
        layout.addWidget(self.nspacesLabel, 1, 0)
        layout.addWidget(self.nspacesBox, 1, 1)
        layout.addWidget(self.dspacesLabel, 2, 0)
        layout.addWidget(self.dspacesBox, 2, 1)

        self.tabwidthBox.valueChanged.connect(page.changed)
        self.nspacesBox.valueChanged.connect(page.changed)
        self.dspacesBox.valueChanged.connect(page.changed)
        self.translateUI()

    def translateUI(self):
        self.setTitle(_("Indenting Preferences"))
        self.tabwidthLabel.setText(_("Visible Tab Width:"))
        self.tabwidthBox.setToolTip(_(
            "The visible width of a Tab character in the editor."))
        self.nspacesLabel.setText(_("Indent text with:"))
        self.nspacesBox.setToolTip(_(
            "How many spaces to use for indenting one level.\n"
            "Move to zero to use a Tab character for indenting."))
        self.nspacesBox.setSpecialValueText(_("Tab"))
        self.dspacesLabel.setText(_("Tab outside indent inserts:"))
        self.dspacesBox.setToolTip(_(
            "How many spaces to insert when Tab is pressed outside the indent, "
            "elsewhere in the document.\n"
            "Move to zero to insert a literal Tab character in this case."))
        self.nspacesBox.setSpecialValueText(_("Tab"))
        self.dspacesBox.setSpecialValueText(_("Tab"))
        # L10N: abbreviation for "n spaces" in spinbox, n >= 1, no plural forms
        prefix, suffix = _("{num} spaces").split("{num}")
        self.nspacesBox.setPrefix(prefix)
        self.nspacesBox.setSuffix(suffix)
        self.dspacesBox.setPrefix(prefix)
        self.dspacesBox.setSuffix(suffix)

    def loadSettings(self):
        s = QSettings()
        s.beginGroup("indent")
        self.tabwidthBox.setValue(s.value("tab_width", 8, int))
        self.nspacesBox.setValue(s.value("indent_spaces", 2, int))
        self.dspacesBox.setValue(s.value("document_spaces", 8, int))

    def saveSettings(self):
        s = QSettings()
        s.beginGroup("indent")
        s.setValue("tab_width", self.tabwidthBox.value())
        s.setValue("indent_spaces", self.nspacesBox.value())
        s.setValue("document_spaces", self.dspacesBox.value())
Example #32
0
class YPipeWidget(QWidget):
    def __init__(self, leftFlow=0, rightFlow=0, maxFlow=100, parent=None):
        super(YPipeWidget, self).__init__(parent)

        self.leftSpinBox = QSpinBox(self)
        self.leftSpinBox.setRange(0, maxFlow)
        self.leftSpinBox.setValue(leftFlow)
        self.leftSpinBox.setSuffix(" l/s")
        self.leftSpinBox.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
        self.connect(self.leftSpinBox, SIGNAL("valueChanged(int)"),
                     self.valueChanged)

        self.rightSpinBox = QSpinBox(self)
        self.rightSpinBox.setRange(0, maxFlow)
        self.rightSpinBox.setValue(rightFlow)
        self.rightSpinBox.setSuffix(" l/s")
        self.rightSpinBox.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
        self.connect(self.rightSpinBox, SIGNAL("valueChanged(int)"),
                     self.valueChanged)

        self.label = QLabel(self)
        self.label.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken)
        self.label.setAlignment(Qt.AlignCenter)
        fm = QFontMetricsF(self.font())
        self.label.setMinimumWidth(fm.width(" 999 l/s "))

        self.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding))
        self.setMinimumSize(self.minimumSizeHint())
        self.valueChanged()

    def valueChanged(self):
        a = self.leftSpinBox.value()
        b = self.rightSpinBox.value()
        self.label.setText("{0} l/s".format(a + b))
        self.emit(SIGNAL("valueChanged"), a, b)
        self.update()

    def values(self):
        return self.leftSpinBox.value(), self.rightSpinBox.value()

    def minimumSizeHint(self):
        return QSize(self.leftSpinBox.width() * 3,
                     self.leftSpinBox.height() * 5)

    def resizeEvent(self, event=None):
        fm = QFontMetricsF(self.font())
        x = (self.width() - self.label.width()) / 2
        y = self.height() - (fm.height() * 1.5)
        self.label.move(x, y)
        y = self.height() / 60.0
        x = (self.width() / 4.0) - self.leftSpinBox.width()
        self.leftSpinBox.move(x, y)
        x = self.width() - (self.width() / 4.0)
        self.rightSpinBox.move(x, y)

    def paintEvent(self, event=None):
        LogicalSize = 100.0

        def logicalFromPhysical(length, side):
            return (length / side) * LogicalSize

        fm = QFontMetricsF(self.font())
        ymargin = (
            (LogicalSize / 30.0) +
            logicalFromPhysical(self.leftSpinBox.height(), self.height()))
        ymax = (LogicalSize -
                logicalFromPhysical(fm.height() * 2, self.height()))
        width = LogicalSize / 4.0
        cx, cy = LogicalSize / 2.0, LogicalSize / 3.0
        ax, ay = cx - (2 * width), ymargin
        bx, by = cx - width, ay
        dx, dy = cx + width, ay
        ex, ey = cx + (2 * width), ymargin
        fx, fy = cx + (width / 2), cx + (LogicalSize / 24.0)
        gx, gy = fx, ymax
        hx, hy = cx - (width / 2), ymax
        ix, iy = hx, fy

        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)
        side = min(self.width(), self.height())
        painter.setViewport((self.width() - side) / 2,
                            (self.height() - side) / 2, side, side)
        painter.setWindow(0, 0, LogicalSize, LogicalSize)

        painter.setPen(Qt.NoPen)

        gradient = QLinearGradient(QPointF(0, 0), QPointF(0, 100))
        gradient.setColorAt(0, Qt.white)
        a = self.leftSpinBox.value()
        gradient.setColorAt(1, (Qt.red if a != 0 else Qt.white))
        painter.setBrush(QBrush(gradient))
        painter.drawPolygon(QPolygon([ax, ay, bx, by, cx, cy, ix, iy]))

        gradient = QLinearGradient(QPointF(0, 0), QPointF(0, 100))
        gradient.setColorAt(0, Qt.white)
        b = self.rightSpinBox.value()
        gradient.setColorAt(1, (Qt.blue if b != 0 else Qt.white))
        painter.setBrush(QBrush(gradient))
        painter.drawPolygon(QPolygon([cx, cy, dx, dy, ex, ey, fx, fy]))

        if (a + b) == 0:
            color = QColor(Qt.white)
        else:
            ashare = (a / (a + b)) * 255.0
            bshare = 255.0 - ashare
            color = QColor(ashare, 0, bshare)
        gradient = QLinearGradient(QPointF(0, 0), QPointF(0, 100))
        gradient.setColorAt(0, Qt.white)
        gradient.setColorAt(1, color)
        painter.setBrush(QBrush(gradient))
        painter.drawPolygon(QPolygon([cx, cy, fx, fy, gx, gy, hx, hy, ix, iy]))

        painter.setPen(Qt.black)
        painter.drawPolyline(QPolygon([ax, ay, ix, iy, hx, hy]))
        painter.drawPolyline(QPolygon([gx, gy, fx, fy, ex, ey]))
        painter.drawPolyline(QPolygon([bx, by, cx, cy, dx, dy]))
Example #33
0
class Window(QMainWindow):

  def __init__(self, parent=None):
    super(Window, self).__init__(parent)
    self.image = QImage()
    self.dirty = False
    self.filename = None
    self.dbFilename = None
    self.mirroredvertically = False
    self.mirroredhorizontally = False
    self.printer = None
    self.exampleForm= None
    self.matlPopup= None
    self.matlPropsHere= None
    self.create_widgets()
    self.create_actions()
    self.load_settings()
    self.setWindowTitle("Thermapythia")
    self.updateFileMenu()
    self.openStackupDB()
    QTimer.singleShot(0, self.loadInitialFile)


  def create_widgets(self):
    self.imageLabel = QLabel()
    self.imageLabel.setMinimumSize(200, 200)
    self.imageLabel.setAlignment(Qt.AlignCenter)
    self.imageLabel.setContextMenuPolicy(Qt.ActionsContextMenu)
    self.setCentralWidget(self.imageLabel)

    logDockWidget = QDockWidget("Log", self)
    logDockWidget.setObjectName("LogDockWidget")
    logDockWidget.setAllowedAreas(Qt.LeftDockWidgetArea|
                                  Qt.RightDockWidgetArea)
    self.listWidget = QListWidget()
    logDockWidget.setWidget(self.listWidget)
    self.addDockWidget(Qt.RightDockWidgetArea, logDockWidget)

    self.sizeLabel = QLabel()
    self.sizeLabel.setFrameStyle(QFrame.StyledPanel|QFrame.Sunken)
    status = self.statusBar()
    status.setSizeGripEnabled(False)
    status.addPermanentWidget(self.sizeLabel)
    status.showMessage("Ready", 5000)


  def create_actions(self):
    fileNewAction = self.createAction("&New...", self.fileNew,
                                      QKeySequence.New, "filenew", "Create an image file")
    fileOpenAction = self.createAction("&Open...", self.fileOpen,
                                       QKeySequence.Open, "fileopen",
                                       "Open an existing image file")
    fileSaveAction = self.createAction("&Save", self.fileSave,
                                       QKeySequence.Save, "filesave", "Save the image")
    fileSaveAsAction = self.createAction("Save &As...",
                                         self.fileSaveAs, icon="filesaveas",
                                         tip="Save the image using a new name")
    filePrintAction = self.createAction("&Print", self.filePrint,
                                        QKeySequence.Print, "fileprint", "Print the image")
    fileQuitAction = self.createAction("&Quit", self.close,
                                       "Ctrl+Q", "filequit", "Close the application")
    
    
    
    
    # createAction(String, slot, shortcut, icon, tip, checkable
    matlEditAction = self.createAction("&Materials", self.matlEdit, 
                                      None, "matls", "Edit materials")
    layerEditAction= self.createAction("&Layers", self.layerEdit, 
                                      None, "layers", "Edit layers") 
    viaEditAction= self.createAction("&Vias", self.viaEdit, 
                                      None, "vias", "Edit vias")  
    zzzEditAction= self.createAction("&Zzz", self.zzzEdit, 
                                     None, "zzz", "Edit zzz")     
    
    
    
    editInvertAction = self.createAction("&Invert", None, "Ctrl+I",
                                         "editinvert", "Invert the image's colors", True)
    editInvertAction.toggled.connect(self.editInvert)
    editSwapRedAndBlueAction = self.createAction("Sw&ap Red and Blue",
                                                 None, "Ctrl+A", "editswap",
                                                 "Swap the image's red and blue color components", True)
    editSwapRedAndBlueAction.toggled.connect(self.editSwapRedAndBlue)
    editZoomAction = self.createAction("&Zoom...", self.editZoom,
                                       "Alt+Z", "editzoom", "Zoom the image")
    mirrorGroup = QActionGroup(self)
    editUnMirrorAction = self.createAction("&Unmirror", None, "Ctrl+U",
                                           "editunmirror", "Unmirror the image", True)
    editUnMirrorAction.toggled.connect(self.editUnMirror)
    mirrorGroup.addAction(editUnMirrorAction)
    editMirrorHorizontalAction = self.createAction(
      "Mirror &Horizontally", None, "Ctrl+H", "editmirrorhoriz",
      "Horizontally mirror the image", True)
    editMirrorHorizontalAction.toggled.connect(
      self.editMirrorHorizontal)
    mirrorGroup.addAction(editMirrorHorizontalAction)
    editMirrorVerticalAction = self.createAction("Mirror &Vertically",
                                                 None, "Ctrl+V", "editmirrorvert",
                                                 "Vertically mirror the image", True)
    editMirrorVerticalAction.toggled.connect(self.editMirrorVertical)
    mirrorGroup.addAction(editMirrorVerticalAction)
    editUnMirrorAction.setChecked(True)
    helpAboutAction = self.createAction("&About Thermapythia",
                                        self.helpAbout)
    helpHelpAction = self.createAction("&Help", self.helpHelp,
                                       QKeySequence.HelpContents)

    self.fileMenu = self.menuBar().addMenu("&File")
    self.fileMenuActions = (fileNewAction, fileOpenAction,
                            fileSaveAction, fileSaveAsAction, None, filePrintAction,
                            fileQuitAction)
    self.fileMenu.aboutToShow.connect(self.updateFileMenu)
    
    stackupMenu = self.menuBar().addMenu("&Stackup")
    self.addActions(stackupMenu, (matlEditAction, layerEditAction, viaEditAction))
    
    
    editMenu = self.menuBar().addMenu("&Edit")
    self.addActions(editMenu, (editInvertAction,
                               editSwapRedAndBlueAction, editZoomAction))
    
    
    mirrorMenu = editMenu.addMenu(QIcon(":/editmirror.png"),
                                  "&Mirror")
    self.addActions(mirrorMenu, (editUnMirrorAction,
                                 editMirrorHorizontalAction, editMirrorVerticalAction))
    helpMenu = self.menuBar().addMenu("&Help")
    self.addActions(helpMenu, (helpAboutAction, helpHelpAction))

    fileToolbar = self.addToolBar("File")
    fileToolbar.setObjectName("FileToolBar")
    self.addActions(fileToolbar, (fileNewAction, fileOpenAction,
                                  fileSaveAsAction))
    
    stackupToolbar = self.addToolBar("Stackup")
    stackupToolbar.setObjectName("StackupToolBar")
    self.addActions(stackupToolbar, (matlEditAction, layerEditAction, viaEditAction))
    
    editToolbar = self.addToolBar("Edit")
    editToolbar.setObjectName("EditToolBar")
    self.addActions(editToolbar, (editInvertAction,
                                  editSwapRedAndBlueAction, editUnMirrorAction,
                                  editMirrorVerticalAction, editMirrorHorizontalAction))
    self.zoomSpinBox = QSpinBox()
    self.zoomSpinBox.setRange(1, 400)
    self.zoomSpinBox.setSuffix(" %")
    self.zoomSpinBox.setValue(100)
    self.zoomSpinBox.setToolTip("Zoom the image")
    self.zoomSpinBox.setStatusTip(self.zoomSpinBox.toolTip())
    self.zoomSpinBox.setFocusPolicy(Qt.NoFocus)
    self.zoomSpinBox.valueChanged.connect(self.showImage)
    editToolbar.addWidget(self.zoomSpinBox)

    self.addActions(self.imageLabel, (editInvertAction,
                                      editSwapRedAndBlueAction, editUnMirrorAction,
                                      editMirrorVerticalAction, editMirrorHorizontalAction))

    self.resetableActions = ((editInvertAction, False),
                             (editSwapRedAndBlueAction, False),
                             (editUnMirrorAction, True))


  def load_settings(self):
    settings = QSettings()
    self.recentFiles = settings.value("RecentFiles").toStringList()
    self.restoreGeometry(
      settings.value("MainWindow/Geometry").toByteArray())
    self.restoreState(settings.value("MainWindow/State").toByteArray())


  def createAction(self, text, slot=None, shortcut=None, icon=None,
                   tip=None, checkable=False):
    action = QAction(text, self)
    if icon is not None:
      action.setIcon(QIcon(":/{0}.png".format(icon)))
    if shortcut is not None:
      action.setShortcut(shortcut)
    if tip is not None:
      action.setToolTip(tip)
      action.setStatusTip(tip)
    if slot is not None:
      action.triggered.connect(slot)
    if checkable:
      action.setCheckable(True)
    return action


  def addActions(self, target, actions):
    for action in actions:
      if action is None:
        target.addSeparator()
      else:
        target.addAction(action)


  def closeEvent(self, event):
    if self.okToContinue():
      settings = QSettings()
      filename = (QVariant(QString(self.filename))
                  if self.filename is not None else QVariant())
      settings.setValue("LastFile", filename)
      recentFiles = (QVariant(self.recentFiles)
                     if self.recentFiles else QVariant())
      settings.setValue("RecentFiles", recentFiles)
      settings.setValue("MainWindow/Geometry", QVariant(
        self.saveGeometry()))
      settings.setValue("MainWindow/State", QVariant(
        self.saveState()))
    else:
      event.ignore()


  def okToContinue(self):
    if self.dirty:
      reply = QMessageBox.question(self,
                                   "Thermapythia - Unsaved Changes",
                                   "Save unsaved changes?",
                                   QMessageBox.Yes|QMessageBox.No|QMessageBox.Cancel)
      if reply == QMessageBox.Cancel:
        return False
      elif reply == QMessageBox.Yes:
        return self.fileSave()
    return True


  def loadInitialFile(self):
    settings = QSettings()
    fname = unicode(settings.value("LastFile").toString())
    if fname and QFile.exists(fname):
      self.loadFile(fname)


  def updateStatus(self, message):
    self.statusBar().showMessage(message, 5000)
    self.listWidget.addItem(message)
    if self.filename is not None:
      self.setWindowTitle("Thermapythia - {0}[*]".format(
        os.path.basename(self.filename)))
    elif not self.image.isNull():
      self.setWindowTitle("Thermapythia - Unnamed[*]")
    else:
      self.setWindowTitle("Thermapythia[*]")
    self.setWindowModified(self.dirty)

  def updateFileMenu(self):
    self.fileMenu.clear()
    self.addActions(self.fileMenu, self.fileMenuActions[:-1])
    current = (QString(self.filename)
               if self.filename is not None else None)
    recentFiles = []
    for fname in self.recentFiles:
      if fname != current and QFile.exists(fname):
        recentFiles.append(fname)
    if recentFiles:
      self.fileMenu.addSeparator()
      for i, fname in enumerate(recentFiles):
        action = QAction(QIcon(":/icon.png"),
                         "&{0} {1}".format(i + 1, QFileInfo(
                           fname).fileName()), self)
        action.setData(QVariant(fname))
        action.triggered.connect(self.loadFile)
        self.fileMenu.addAction(action)
    self.fileMenu.addSeparator()
    self.fileMenu.addAction(self.fileMenuActions[-1])

  def fileNew(self):
    if not self.okToContinue():
      return
    dialog = newimagedlg.NewImageDlg(self)
    if dialog.exec_():
      self.addRecentFile(self.filename)
      self.image = QImage()
      for action, check in self.resetableActions:
        action.setChecked(check)
      self.image = dialog.image()
      self.filename = None
      self.dirty = True
      self.showImage()
      self.sizeLabel.setText("{0} x {1}".format(self.image.width(),
                                                self.image.height()))
      self.updateStatus("Created new image")


  def fileOpen(self):
    if not self.okToContinue():
      return
    dir = (os.path.dirname(self.filename)
           if self.filename is not None else ".")
    formats = (["*.{0}".format(unicode(format).lower())
                for format in QImageReader.supportedImageFormats()])
    fname = unicode(QFileDialog.getOpenFileName(self,
                                                "Thermapythia - Choose Image", dir,
                                                "Image files ({0})".format(" ".join(formats))))
    if fname:
      self.loadFile(fname)


  def loadFile(self, fname=None):
    if fname is None:
      action = self.sender()
      if isinstance(action, QAction):
        fname = unicode(action.data().toString())
        if not self.okToContinue():
          return
      else:
        return
    if fname:
      self.filename = None
      image = QImage(fname)
      if image.isNull():
        message = "Failed to read {0}".format(fname)
      else:
        self.addRecentFile(fname)
        self.image = QImage()
        for action, check in self.resetableActions:
          action.setChecked(check)
        self.image = image
        self.filename = fname
        self.showImage()
        self.dirty = False
        self.sizeLabel.setText("{0} x {1}".format(
          image.width(), image.height()))
        message = "Loaded {0}".format(os.path.basename(fname))
      self.updateStatus(message)


  def addRecentFile(self, fname):
    if fname is None:
      return
    if not self.recentFiles.contains(fname):
      self.recentFiles.prepend(QString(fname))
      while self.recentFiles.count() > 9:
        self.recentFiles.takeLast()


  def fileSave(self):
    if self.image.isNull():
      return True
    if self.filename is None:
      return self.fileSaveAs()
    else:
      if self.image.save(self.filename, None):
        self.updateStatus("Saved as {0}".format(self.filename))
        self.dirty = False
        return True
      else:
        self.updateStatus("Failed to save {0}".format(
          self.filename))
        return False


  def fileSaveAs(self):
    if self.image.isNull():
      return True
    fname = self.filename if self.filename is not None else "."
    formats = (["*.{0}".format(unicode(format).lower())
                for format in QImageWriter.supportedImageFormats()])
    fname = unicode(QFileDialog.getSaveFileName(self,
                                                "Thermapythia - Save Image", fname,
                                                "Image files ({0})".format(" ".join(formats))))
    if fname:
      if "." not in fname:
        fname += ".png"
      self.addRecentFile(fname)
      self.filename = fname
      return self.fileSave()
    return False


  def filePrint(self):
    if self.image.isNull():
      return
    if self.printer is None:
      self.printer = QPrinter(QPrinter.HighResolution)
      self.printer.setPageSize(QPrinter.Letter)
    form = QPrintDialog(self.printer, self)
    if form.exec_():
      painter = QPainter(self.printer)
      rect = painter.viewport()
      size = self.image.size()
      size.scale(rect.size(), Qt.KeepAspectRatio)
      painter.setViewport(rect.x(), rect.y(), size.width(),
                          size.height())
      painter.drawImage(0, 0, self.image)
  
  
  
  #
  def openStackupDB(self):
  
    if self.dbFilename != None:
      return
    self.dbFilename = os.path.join(os.path.dirname(__file__), "stackup.db")
    create = not QFile.exists(self.dbFilename)
  
    db = QSqlDatabase.addDatabase("QSQLITE")
    db.setDatabaseName(self.dbFilename)
    if not db.open():
      QMessageBox.warning(None, "Can't open stackup database",
                          QString("Database Error: %1").arg(db.lastError().text()))
      sys.exit(1)  
    if create == False:
      self.updateStatus("Found stackup database file: " + str(self.dbFilename))
      
    self.createDatabaseTables()
      
    with open('test2.js', "r") as jsonHandle:
      jsonContents= jsonHandle.read()    
    config= yaml.load(jsonContents)    
      
    matlCount= self.countDatabaseTableRows("matl")
    if matlCount == 0:
      self.updateStatus("material editor call goes here.")
      #
      # TODO: Put the guess-what-I'm thinking Qt table editor thing here.
      #
      # self.loadDefaultMatls()
      matls = Matls.Matls(config['matl_config'])
      self.loadDefaultData('matl', matls)      
      
    viaCount= self.countDatabaseTableRows("via")
    if viaCount == 0:  
      vias = Vias.Vias(config['via_config'])
      self.loadDefaultData('via', vias)
      
    layerCount= self.countDatabaseTableRows("layer")
    if layerCount == 0:  
      layers = Layers.Layers(config['layer_config'])
      self.loadDefaultData('layer', layers)
      
    # initialize zzz new content here, perhaps
  
  def createDatabaseTables(self):
    query = QSqlQuery()
    self.updateStatus("Creating database tables")
          # "id" INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL,
    statusMatl = query.exec_("""CREATE TABLE IF NOT EXISTS "matl" (
                  "name" TEXT,
                  "type" TEXT,
                  "density" real,
                  "color" TEXT,
                  "specific_heat" real,
                  "conductivity" real,
                  "conductivityXX" real,
                  "conductivityYY" real,
                  "conductivityZZ" real,
                  "reflection_coeff" real,
                  "emissivity" real,
                  "max_height" real,
                  "thickness" real
                  );""")
    if statusMatl == False:
      self.updateStatus("Could not create material property database table 'matl'")
      self.updateStatus("Database error message: " + query.lastError().text())
    
    statusPhylayer = query.exec_("""CREATE TABLE IF NOT EXISTS "layer" (
                  "id" INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL,
                  "name" TEXT,
                  "matl" TEXT,
                  "type" TEXT,
                  "thickness" real,
                  "displaces" TEXT,
                  "coverage" real,
                  "z_bottom" real,
                  "z_top" real,
                  "adheres_to" TEXT);""")
    if statusPhylayer == False:
      self.updateStatus("Could not create material property database table 'layer'")
      self.updateStatus("Database error message: " + query.lastError().text())  
    
    statusVia = query.exec_("""CREATE TABLE IF NOT EXISTS "via" (
                  "id" INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL,
                  "name" TEXT,
                  "matl" TEXT,
                  "to" TEXT,
                  "from" TEXT);""")
    if statusVia == False:
      self.updateStatus("Could not create material property database table 'via'")
      self.updateStatus("Database error message: " + query.lastError().text())      
    
  def countDatabaseTableRows(self, tablename):
    query = QSqlQuery()
    self.updateStatus("Loading database tables")    
    query.prepare("select count(*) from " + tablename + ";")
    status = query.exec_()
    if status == False:
      self.updateStatus("Could not count entries in table '" + tablename + "'")
      self.updateStatus("Database error message: " + query.lastError().text())
    query.first()
    count, ok = query.value(0).toInt()
    # self.updateStatus("There are " + str(count) + " rows in the " + tablename + " table")
    return count

  def loadDefaultData(self, table, data):
    query = QSqlQuery()
    insertList= "', '".join(data.tableCols)
    insertList= "'" + insertList + "'"    
    colCount= len(data.tableCols)
    quest= ""
    for i in range(0, colCount):
      quest = quest + "?,"
    quest= quest[:-1]
    
    sql= "INSERT INTO " + table + "(" + insertList + ") VALUES (" + quest + ");"
    # self.updateStatus(sql)
    status= query.prepare(sql)
    if status == False:
      self.updateStatus("Could not prepare material property database table " + table)
      self.updateStatus("Database error message: " + query.lastError().text())    
    
    for row in data.propDict:
      for prop in data.tableCols:
        propval= data.propDict[row][prop]
        if data.tableColSQLTypes[prop] == 'TEXT':
          query.addBindValue(QVariant(QString(propval)))
          # self.updateStatus("Setting TEXT property " + prop + " to value " + str(propval) + " in row " + str(row))
        elif data.tableColSQLTypes[prop] == 'real':
          if (propval == '-'):
            propreal= -999.9
          else:
            propreal= float(propval)
          query.addBindValue(QVariant(propreal))
          # self.updateStatus("Setting real property " + prop + " to value " + str(propreal) + " in row " + str(row))
      status= query.exec_()
      if status == False:
        self.updateStatus("Could not load property database table " + table + " with " + str(row))
        self.updateStatus("Database error message: " + query.lastError().text())
 
 
 
  def matlEdit(self):
    self.dirty= True
    self.updateStatus("Call edit material code here")
    # This ends up in a little child window
    
    
    self.matlPopup= QLabel("<font color=green size=72><b> Material Editor </b></font>")
    # self.matlPopup.setWindowFlags(Qt.SplashScreen)
    self.matlPopup.setWindowTitle("Material edit popup")
    
    self.matlPropsHere= QLabel("<font color=red size=24><b> Data goes here </b></font>")
    # self.matlPopup.setWindowFlags(Qt.SplashScreen) 
    
    if 1 == 0:
      dataLayout= QVBoxLayout()
      dataLayout.addWidget(self.matlPopup)
      dataLayout.addWidget(self.matlPropsHere)
      self.setLayout(dataLayout)    
    
    self.matlPopup.show()
    self.matlPropsHere.show()
    
#    self.exampleForm= MatlForm()
    # First need a layout manager, and add the widget to that. 
    # Then attach the layout manager to a window.
    # addWidget(self.exampleForm)
#    self.exampleForm.show()
    
    QTimer.singleShot(5000, self.update)
    
    self.updateStatus("Created stackup db")
    
  def layerEdit(self):
    self.dirty= True
    self.updateStatus("Call edit layer code here") 
    
    # This way of doing it is modal - window doesn't go away and covers up other windows until it is dismissed.
    form= MatlForm()
    form.exec_()
    

  def viaEdit(self):
    self.dirty= True
    self.updateStatus("Call edit via code here")

  def zzzEdit(self):
    self.dirty= True
    self.updateStatus("Call code to be triggered by zzz button here")         

  def editInvert(self, on):
    if self.image.isNull():
      return
    self.image.invertPixels()
    self.showImage()
    self.dirty = True
    self.updateStatus("Inverted" if on else "Uninverted")
       

  def editSwapRedAndBlue(self, on):
    if self.image.isNull():
      return
    self.image = self.image.rgbSwapped()
    self.showImage()
    self.dirty = True
    self.updateStatus(("Swapped Red and Blue"
                       if on else "Unswapped Red and Blue"))


  def editUnMirror(self, on):
    if self.image.isNull():
      return
    if self.mirroredhorizontally:
      self.editMirrorHorizontal(False)
    if self.mirroredvertically:
      self.editMirrorVertical(False)


  def editMirrorHorizontal(self, on):
    if self.image.isNull():
      return
    self.image = self.image.mirrored(True, False)
    self.showImage()
    self.mirroredhorizontally = not self.mirroredhorizontally
    self.dirty = True
    self.updateStatus(("Mirrored Horizontally"
                       if on else "Unmirrored Horizontally"))


  def editMirrorVertical(self, on):
    if self.image.isNull():
      return
    self.image = self.image.mirrored(False, True)
    self.showImage()
    self.mirroredvertically = not self.mirroredvertically
    self.dirty = True
    self.updateStatus(("Mirrored Vertically"
                       if on else "Unmirrored Vertically"))


  def editZoom(self):
    if self.image.isNull():
      return
    percent, ok = QInputDialog.getInteger(self,
                                          "Thermapythia - Zoom", "Percent:",
                                          self.zoomSpinBox.value(), 1, 400)
    if ok:
      self.zoomSpinBox.setValue(percent)


  def showImage(self, percent=None):
    if self.image.isNull():
      return
    if percent is None:
      percent = self.zoomSpinBox.value()
    factor = percent / 100.0
    width = self.image.width() * factor
    height = self.image.height() * factor
    image = self.image.scaled(width, height, Qt.KeepAspectRatio)
    self.imageLabel.setPixmap(QPixmap.fromImage(image))


  def helpAbout(self):
    QMessageBox.about(self, "About Thermapythia",
                      """<b>Thermapythia</b> v {0}
                <p>Thermal Analyzer in Python predicts circuit board temperature
                <p>Python {1} - Qt {2} - PyQt {3} on {4}""".format(
                                                             __version__, platform.python_version(),
                                                             QT_VERSION_STR, PYQT_VERSION_STR,
                                                             platform.system()))


  def helpHelp(self):
    form = HelpForm.HelpForm("index.html", self)
    form.show()
class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        
        self._create_components()
        self._place_components()
        self._create_controller()
        
        self.setWindowTitle("Job Crawler")
    
    def _create_components(self):
        self.site_gb = QGroupBox(u"Choix des sites")
        self.param_gb = QGroupBox(u"Autres Paramètres")
        self.search_gb = QGroupBox(u"Mots-clé")
        self.log_gb = QGroupBox(u"Logs")

        self.apec_cb = QCheckBox(u"APEC")
        self.apec_cb.setDisabled(True)
        self.caoe_cb = QCheckBox(u"CAO Emploi")
        self.caoe_cb.setDisabled(True)
        self.inde_cb = QCheckBox(u"Indeed")
        self.mons_cb = QCheckBox(u"Monster Job")
        self.mons_cb.setDisabled(True)
        self.pole_cb = QCheckBox(u"Pole Enmploi")
        self.pole_cb.setDisabled(True)
        self.regi_cb = QCheckBox(u"Région Job")
        self.regi_cb.setDisabled(True)
        
        self.search_label = QLabel(u"Mots-clé de recherche")
        self.filter_label = QLabel(u"Critère de filtrage")
        self.region_label = QLabel(u"Région")
        self.daterange_label = QLabel(u"Plage de recherche")
        
        self.search_qle = QLineEdit()
        self.filter_qle = QLineEdit()
        
        self.start_button = QPushButton(u"Rechercher")
        self.stop_button = QPushButton(u"Stopper")
        self.stop_button.setDisabled(True)
        
        self.daterange_sb = QSpinBox()
        self.daterange_sb.setMaximum(40)
        self.daterange_sb.setProperty("value", 3)
        self.daterange_sb.setSuffix(u" Jours")
        
        self.region_cb = QComboBox()
        region_list = toolbox.getconfigvalue("STATIC", "regions").split(',')
        self.region_cb.addItems(region_list)
        
        self.log_te = QTextEdit()
        self.log_te.setReadOnly(True)
        self.log_te.setLineWrapMode(QTextEdit.NoWrap)
        
        self.file_menu = QMenu(u"Fichier")
        self.help_menu = QMenu(u"Aide")
        
    
    def _place_components(self):
        site_layout = QHBoxLayout()
        temp = QVBoxLayout()
        temp.addWidget(self.apec_cb)
        temp.addWidget(self.caoe_cb)
        temp.addWidget(self.inde_cb)
        site_layout.addLayout(temp)
        temp = QVBoxLayout()
        temp.addWidget(self.mons_cb)
        temp.addWidget(self.pole_cb)
        temp.addWidget(self.regi_cb)
        site_layout.addLayout(temp)
        self.site_gb.setLayout(site_layout)
        
        search_layout = QVBoxLayout()
        search_layout.addWidget(self.search_label)
        search_layout.addWidget(self.search_qle)
        search_layout.addWidget(self.filter_label)
        search_layout.addWidget(self.filter_qle)
        self.search_gb.setLayout(search_layout)
        
        param_layout = QVBoxLayout()
        param_layout.addWidget(self.daterange_label)
        param_layout.addWidget(self.daterange_sb)
        param_layout.addWidget(self.region_label)
        param_layout.addWidget(self.region_cb)
        self.param_gb.setLayout(param_layout)
        
        log_layout = QVBoxLayout()
        log_layout.addWidget(self.log_te)
        self.log_gb.setLayout(log_layout)
        
        command_layout = QHBoxLayout()
        command_layout.addWidget(self.start_button)
        command_layout.addWidget(self.stop_button)
        
        main_layout = QVBoxLayout()
        main_layout.addWidget(self.site_gb)
        main_layout.addWidget(self.search_gb)
        main_layout.addWidget(self.param_gb)
        main_layout.addWidget(self.log_gb)
        main_layout.addLayout(command_layout)
        
        centralwidget = QWidget(self)
        centralwidget.setLayout(main_layout)
        self.setCentralWidget(centralwidget)
        
        menubar = self.menuBar()
        menubar.addMenu(self.file_menu)
        menubar.addMenu(self.help_menu)
    
    def _create_controller(self):
        adminAction = QAction(u'Administration', self)        
        adminAction.setStatusTip(u'Régler les paramètres de l\'application')
        adminAction.triggered.connect(self.admin)
        
        exitAction = QAction(u'Quitter', self)        
        exitAction.setStatusTip(u'Quitter Job Crawler')
        exitAction.triggered.connect(qApp.quit)
        
        aboutAction = QAction(u'A propos', self)
        aboutAction.setStatusTip(u'Afficher la fenêtre à propos')
        aboutAction.triggered.connect(self.about)
        
        self.file_menu.addAction(adminAction)
        self.file_menu.addSeparator()
        self.file_menu.addAction(exitAction)
        
        self.help_menu.addAction(aboutAction)
        
        self.start_button.clicked.connect(self.start)
        self.stop_button.clicked.connect(self.stop)
        
        # Controller for logging
        XStream.stdout().messageWritten.connect( self.log_te.insertPlainText )
        XStream.stderr().messageWritten.connect( self.log_te.insertPlainText )
    
    def validate_fields(self):
        error = False
        error_list = u""
        
        inde = self.inde_cb.isChecked()
        apec = self.apec_cb.isChecked()
        caoe = self.caoe_cb.isChecked()
        mons = self.mons_cb.isChecked()
        pole = self.pole_cb.isChecked()
        regi = self.regi_cb.isChecked()
        
        if  not (inde or apec or caoe or mons or pole or regi):
            error = True
            error_list += u"<li>Site à requêter</li>"
            
        searchkeyword = unidecode(unicode(self.search_qle.text()))
        
        if searchkeyword == u"":
            error = True
            error_list += u"<li>Mots clé de recherche</li>"
        
        filterkeyword = unidecode(unicode(self.filter_qle.text()))
        
        if filterkeyword == u"":
            error = True
            error_list += u"<li>Critère de filtrage</li>"
        
        if error:
            message = u"Veuillez renseigner le(s) champ(s) suivant(s) :<ul>" + error_list + u"</ul>"
            QMessageBox.warning(self, u"Erreur", message)
        
        return not error
    
    def validate_admin(self):
        dbpath = toolbox.getconfigvalue("GENERAL", "dbfile")
        
        if not (dbpath != "" and os.access(os.path.dirname(dbpath), os.W_OK)):
            message = u"<p>Veuiller renseigner l'emplacement de la base de données dans l'administration (Fichier > Administration).</p>"\
                      u"<p>Si cela a déjà été fait, ce message signifie que vous n'avez pas les droits d'écriture dans ce répertoire. Veuillez déplacer la base de données et reconfigurer l'emplacement dans l'administration.</p>"
            QMessageBox.warning(self, u"Erreur", message)
            return False
        
        return True
        
    @pyqtSlot()
    def start(self):
        def run():
            self.start_button.setDisabled(True)
#             self.stop_button.setEnabled(True)
            
            logger.info(u"Début")
            
            inde = self.inde_cb.isChecked()
            apec = self.apec_cb.isChecked()
            caoe = self.caoe_cb.isChecked()
            mons = self.mons_cb.isChecked()
            pole = self.pole_cb.isChecked()
            regi = self.regi_cb.isChecked()
            
            searchkeyword = unidecode(unicode(self.search_qle.text())).split(",")
            filterkeyword = unidecode(unicode(self.filter_qle.text())).split(",")
            
            daterange = self.daterange_sb.value()
            region = str(self.region_cb.currentText())
            
            dbpath = toolbox.getconfigvalue("GENERAL", "dbfile")
            excludelist = unidecode(toolbox.getconfigvalue("GENERAL", "excludes")).split(",")
            
            c = core.core(dbpath)
            logger.info(u"Recherche d'annonces")
            c.found_annonce(searchkeyword, daterange, region, None, apec, caoe, inde, mons, pole, regi)
            logger.info(u"Tri des annonces par rapport aux mots-clé d'exclusion")
            c.exclude_annouces(excludelist)
            logger.info(u"Tri des annonces par rapport aux critères de filtrage")
            c.filter_announces(filterkeyword)
            
            logger.info(u"Fin")
            
#             self.stop_button.setDisabled(True)
            self.start_button.setEnabled(True)
        
        if self.validate_fields() and self.validate_admin():
            self.thread = threading.Thread(target=run)
            self.thread.start()
    
    @pyqtSlot()
    def stop(self):
        self.thread._Thread__stop()
        self.stop_button.setDisabled(True)
        self.start_button.setEnabled(True)
        
    @pyqtSlot()
    def about(self):
        self.aboutwindow = aboutdialog.AboutDialog(self).exec_()
    
    @pyqtSlot()
    def admin(self):
        admindialog.AdminDialog(self).exec_()
class CodePastingDialog(QDialog):
    def __init__(self, parent=None, code=''):
        super(CodePastingDialog, self).__init__(parent)
        self.setWindowTitle(self.tr("Enviar a Pastebin"))
        self.setMinimumSize(700, 500)
        self._parent = parent
        container = QVBoxLayout(self)

        # Thread
        self.thread = code_pasting.Thread()
        self.connect(self.thread, SIGNAL("finished()"), self._paste_result)
        # Campos
        fields_box = QGridLayout()
        fields_box.addWidget(QLabel(self.tr("Expirar después de:")), 0, 0)
        self._spin_expire = QSpinBox()
        self._spin_expire.setSuffix(self.tr(" Días"))
        self._spin_expire.setMinimum(1)
        fields_box.addWidget(self._spin_expire, 0, 1)
        fields_box.addWidget(QLabel(self.tr("Acceso:")), 1, 0)
        self._combo_access = QComboBox()
        self._combo_access.addItems([self.tr("Público"), self.tr("Privado")])
        fields_box.addWidget(self._combo_access, 1, 1)
        fields_box.addWidget(QLabel(self.tr("Nombre:")), 2, 0)
        self._line_filename = QLineEdit()
        place_holder_text = parent.get_active_editor().filename
        self._line_filename.setPlaceholderText(place_holder_text)
        fields_box.addWidget(self._line_filename, 2, 1)
        fields_box.addWidget(QLabel(self.tr("Descripción:")), 3, 0)

        # Editor
        self._code_editor = QPlainTextEdit()
        self._set_editor_style(self._code_editor)
        self._code_editor.setPlainText(code)

        hbox = QHBoxLayout()
        hbox.addItem(QSpacerItem(0, 1, QSizePolicy.Expanding))
        btn_paste = QPushButton(self.tr("Enviar"))
        hbox.addWidget(btn_paste)
        btn_cancel = QPushButton(self.tr("Cancelar"))
        hbox.addWidget(btn_cancel)

        container.addLayout(fields_box)
        container.addWidget(self._code_editor)
        container.addLayout(hbox)

        # Loading widget
        self.loading_widget = loading_widget.LoadingWidget(self)
        self.loading_widget.hide()

        # Conexiones
        self.connect(btn_cancel, SIGNAL("clicked()"), self.close)
        self.connect(btn_paste, SIGNAL("clicked()"), self._emit_data)

    def _emit_data(self):
        code = self._code_editor.toPlainText()
        expire = str(self._spin_expire.value()) + 'D'
        paste_name = self._line_filename.text()
        if not paste_name:
            paste_name = self._parent.get_active_editor().filename
        self.loading_widget.show()
        self.thread.paste(code, paste_name, expire)

    def _paste_result(self):
        self.loading_widget.hide()
        result = self.thread.result
        if result is None:
            QMessageBox.critical(self, self.tr("Error!"),
                                 self.tr("No hay código"))
            return
        QMessageBox.information(self, self.tr("URL"), str(result))
        self.close()

    def _set_editor_style(self, editor):
        style = 'QPlainTextEdit {color: #E2E2E5; background-color: #0E0F12; }'
        editor.setStyleSheet(style)

    def resizeEvent(self, event):
        super(CodePastingDialog, self).resizeEvent(event)
        self.loading_widget.resize(event.size())
Example #36
0
class Indenting(preferences.Group):
    def __init__(self, page):
        super(Indenting, self).__init__(page)
        
        layout = QGridLayout(spacing=1)
        self.setLayout(layout)
        
        self.tabwidthBox = QSpinBox(minimum=1, maximum=99)
        self.tabwidthLabel = l = QLabel()
        l.setBuddy(self.tabwidthBox)
        
        self.nspacesBox = QSpinBox(minimum=0, maximum=99)
        self.nspacesLabel = l = QLabel()
        l.setBuddy(self.nspacesBox)
        
        self.dspacesBox = QSpinBox(minimum=0, maximum=99)
        self.dspacesLabel = l = QLabel()
        l.setBuddy(self.dspacesBox)
        
        layout.addWidget(self.tabwidthLabel, 0, 0)
        layout.addWidget(self.tabwidthBox, 0, 1)
        layout.addWidget(self.nspacesLabel, 1, 0)
        layout.addWidget(self.nspacesBox, 1, 1)
        layout.addWidget(self.dspacesLabel, 2, 0)
        layout.addWidget(self.dspacesBox, 2, 1)
        
        self.tabwidthBox.valueChanged.connect(page.changed)
        self.nspacesBox.valueChanged.connect(page.changed)
        self.dspacesBox.valueChanged.connect(page.changed)
        self.translateUI()
        
    def translateUI(self):
        self.setTitle(_("Indenting Preferences"))
        self.tabwidthLabel.setText(_("Visible Tab Width:"))
        self.tabwidthBox.setToolTip(_(
            "The visible width of a Tab character in the editor."))
        self.nspacesLabel.setText(_("Indent text with:"))
        self.nspacesBox.setToolTip(_(
            "How many spaces to use for indenting one level.\n"
            "Move to zero to use a Tab character for indenting."))
        self.nspacesBox.setSpecialValueText(_("Tab"))
        self.dspacesLabel.setText(_("Tab ouside indent inserts:"))
        self.dspacesBox.setToolTip(_(
            "How many spaces to insert when Tab is pressed outside the indent, "
            "elsewhere in the document.\n"
            "Move to zero to insert a literal Tab character in this case."))
        self.nspacesBox.setSpecialValueText(_("Tab"))
        self.dspacesBox.setSpecialValueText(_("Tab"))
        # L10N: abbreviation for "n spaces" in spinbox, n >= 1, no plural forms
        prefix, suffix = _("{num} spaces").split("{num}")
        self.nspacesBox.setPrefix(prefix)
        self.nspacesBox.setSuffix(suffix)
        self.dspacesBox.setPrefix(prefix)
        self.dspacesBox.setSuffix(suffix)

    def loadSettings(self):
        s = QSettings()
        s.beginGroup("indent")
        self.tabwidthBox.setValue(s.value("tab_width", 8, int))
        self.nspacesBox.setValue(s.value("indent_spaces", 2, int))
        self.dspacesBox.setValue(s.value("document_spaces", 8, int))
    
    def saveSettings(self):
        s = QSettings()
        s.beginGroup("indent")
        s.setValue("tab_width", self.tabwidthBox.value())
        s.setValue("indent_spaces", self.nspacesBox.value())
        s.setValue("document_spaces", self.dspacesBox.value())
class IndustrialDualAnalogInV2(COMCUPluginBase):
    def __init__(self, *args):
        COMCUPluginBase.__init__(self, BrickletIndustrialDualAnalogInV2, *args)

        self.analog_in = self.device

        self.cbe_voltage0 = CallbackEmulator(functools.partial(self.analog_in.get_voltage, 0),
                                             functools.partial(self.cb_voltage, 0),
                                             self.increase_error_count)

        self.cbe_voltage1 = CallbackEmulator(functools.partial(self.analog_in.get_voltage, 1),
                                             functools.partial(self.cb_voltage, 1),
                                             self.increase_error_count)

        self.calibration = None

        self.sample_rate_label = QLabel('Sample Rate:')
        self.sample_rate_combo = QComboBox()
        self.sample_rate_combo.addItem('976 Hz')
        self.sample_rate_combo.addItem('488 Hz')
        self.sample_rate_combo.addItem('244 Hz')
        self.sample_rate_combo.addItem('122 Hz')
        self.sample_rate_combo.addItem('61 Hz')
        self.sample_rate_combo.addItem('4 Hz')
        self.sample_rate_combo.addItem('2 Hz')
        self.sample_rate_combo.addItem('1 Hz')

        self.current_voltage = [None, None] # float, V
        self.calibration_button = QPushButton('Calibration...')

        self.sample_rate_combo.currentIndexChanged.connect(self.sample_rate_combo_index_changed)
        self.calibration_button.clicked.connect(self.calibration_button_clicked)

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

        # Define lines
        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)

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

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

        # Define channel LED status config widgets
        self.led_config_ch0_label = QLabel('Channel 0')
        self.led_config_ch1_label = QLabel('Channel 1')
        self.led_config_label = QLabel('LED Config:')
        self.led_status_config_label = QLabel('LED Status Config:')
        self.led_status_config_ch0_min_label = QLabel('Min:')
        self.led_status_config_ch0_max_label = QLabel('Max:')
        self.led_status_config_ch1_min_label = QLabel('Min:')
        self.led_status_config_ch1_max_label = QLabel('Max:')

        self.led_config_ch0_combo = QComboBox()
        self.led_config_ch0_combo.addItem('Off')
        self.led_config_ch0_combo.addItem('On')
        self.led_config_ch0_combo.addItem('Show Heartbeat')
        self.led_config_ch0_combo.addItem('Show Channel Status')
        self.led_config_ch0_combo.currentIndexChanged.connect(self.led_config_ch0_combo_changed)

        self.led_config_ch1_combo = QComboBox()
        self.led_config_ch1_combo.addItem('Off')
        self.led_config_ch1_combo.addItem('On')
        self.led_config_ch1_combo.addItem('Show Heartbeat')
        self.led_config_ch1_combo.addItem('Show Channel Status')
        self.led_config_ch1_combo.currentIndexChanged.connect(self.led_config_ch1_combo_changed)

        self.led_status_config_ch0_combo = QComboBox()
        self.led_status_config_ch0_combo.addItem('Threshold')
        self.led_status_config_ch0_combo.addItem('Intensity')
        self.led_status_config_ch0_combo.currentIndexChanged.connect(self.led_status_config_ch0_combo_changed)

        self.led_status_config_ch1_combo = QComboBox()
        self.led_status_config_ch1_combo.addItem('Threshold')
        self.led_status_config_ch1_combo.addItem('Intensity')
        self.led_status_config_ch1_combo.currentIndexChanged.connect(self.led_status_config_ch1_combo_changed)

        self.led_status_config_ch0_min_sbox = QSpinBox()
        self.led_status_config_ch0_min_sbox.setMinimum(-35000)
        self.led_status_config_ch0_min_sbox.setMaximum(35000)
        self.led_status_config_ch0_min_sbox.setValue(0)
        self.led_status_config_ch0_min_sbox.setSingleStep(1)
        self.led_status_config_ch0_min_sbox.setSuffix(' mV')
        self.led_status_config_ch0_min_sbox.valueChanged.connect(self.led_status_config_ch0_min_sbox_changed)

        self.led_status_config_ch0_max_sbox = QSpinBox()
        self.led_status_config_ch0_max_sbox.setMinimum(-35000)
        self.led_status_config_ch0_max_sbox.setMaximum(35000)
        self.led_status_config_ch0_max_sbox.setValue(0)
        self.led_status_config_ch0_max_sbox.setSingleStep(1)
        self.led_status_config_ch0_max_sbox.setSuffix(' mV')
        self.led_status_config_ch0_max_sbox.valueChanged.connect(self.led_status_config_ch0_max_sbox_changed)

        self.led_status_config_ch1_min_sbox = QSpinBox()
        self.led_status_config_ch1_min_sbox.setMinimum(-35000)
        self.led_status_config_ch1_min_sbox.setMaximum(35000)
        self.led_status_config_ch1_min_sbox.setValue(0)
        self.led_status_config_ch1_min_sbox.setSingleStep(1)
        self.led_status_config_ch1_min_sbox.setSuffix(' mV')
        self.led_status_config_ch1_min_sbox.valueChanged.connect(self.led_status_config_ch1_min_sbox_changed)

        self.led_status_config_ch1_max_sbox = QSpinBox()
        self.led_status_config_ch1_max_sbox.setMinimum(-35000)
        self.led_status_config_ch1_max_sbox.setMaximum(35000)
        self.led_status_config_ch1_max_sbox.setValue(0)
        self.led_status_config_ch1_max_sbox.setSingleStep(1)
        self.led_status_config_ch1_max_sbox.setSuffix(' mV')
        self.led_status_config_ch1_max_sbox.valueChanged.connect(self.led_status_config_ch1_max_sbox_changed)

        # Define size policies
        h_sp = QSizePolicy()
        h_sp.setHorizontalPolicy(QSizePolicy.Expanding)

        # Set size policies
        self.sample_rate_combo.setSizePolicy(h_sp)
        self.led_config_ch0_combo.setSizePolicy(h_sp)
        self.led_config_ch1_combo.setSizePolicy(h_sp)
        self.led_status_config_ch0_combo.setSizePolicy(h_sp)
        self.led_status_config_ch1_combo.setSizePolicy(h_sp)
        self.led_status_config_ch0_min_sbox.setSizePolicy(h_sp)
        self.led_status_config_ch0_max_sbox.setSizePolicy(h_sp)
        self.led_status_config_ch1_min_sbox.setSizePolicy(h_sp)
        self.led_status_config_ch1_max_sbox.setSizePolicy(h_sp)

        # Define layouts
        hlayout = QHBoxLayout()
        vlayout = QVBoxLayout()
        glayout = QGridLayout()
        layout = QVBoxLayout(self)
        hlayout_ch0_min_max = QHBoxLayout()
        hlayout_ch1_min_max = QHBoxLayout()

        # Populate layouts
        vlayout.addWidget(self.calibration_button)
        hlayout.addWidget(self.sample_rate_label)
        hlayout.addWidget(self.sample_rate_combo)
        vlayout.addLayout(hlayout)
        vlayout.addWidget(line1)

        hlayout_ch0_min_max.addWidget(self.led_status_config_ch0_min_label)
        hlayout_ch0_min_max.addWidget(self.led_status_config_ch0_min_sbox)
        hlayout_ch0_min_max.addWidget(self.led_status_config_ch0_max_label)
        hlayout_ch0_min_max.addWidget(self.led_status_config_ch0_max_sbox)

        hlayout_ch1_min_max.addWidget(self.led_status_config_ch1_min_label)
        hlayout_ch1_min_max.addWidget(self.led_status_config_ch1_min_sbox)
        hlayout_ch1_min_max.addWidget(self.led_status_config_ch1_max_label)
        hlayout_ch1_min_max.addWidget(self.led_status_config_ch1_max_sbox)

        glayout.addWidget(self.led_config_ch0_label, 0, 1, 1, 1) # R, C, RS, CS
        glayout.addWidget(self.led_config_ch1_label, 0, 2, 1, 1)

        glayout.addWidget(line2, 1, 0, 1, 3)

        glayout.addWidget(self.led_config_label, 2, 0, 1, 1)
        glayout.addWidget(self.led_config_ch0_combo, 2, 1, 1, 1)
        glayout.addWidget(self.led_config_ch1_combo, 2, 2, 1, 1)

        glayout.addWidget(self.led_status_config_label, 3, 0, 1, 1)
        glayout.addWidget(self.led_status_config_ch0_combo, 3, 1, 1, 1)
        glayout.addWidget(self.led_status_config_ch1_combo, 3, 2, 1, 1)

        glayout.addLayout(hlayout_ch0_min_max, 4, 1, 1, 1)
        glayout.addLayout(hlayout_ch1_min_max, 4, 2, 1, 1)

        layout.addWidget(self.plot_widget)
        layout.addWidget(line)
        layout.addLayout(vlayout)
        layout.addLayout(glayout)

        self.ui_group_ch_status_ch0 = [self.led_status_config_ch0_combo,
                                       self.led_status_config_ch0_min_sbox,
                                       self.led_status_config_ch0_max_sbox]

        self.ui_group_ch_status_ch1 = [self.led_status_config_ch1_combo,
                                       self.led_status_config_ch1_min_sbox,
                                       self.led_status_config_ch1_max_sbox]

    def start(self):
        async_call(self.analog_in.get_voltage, 0, lambda x: self.cb_voltage(0, x), self.increase_error_count)
        async_call(self.analog_in.get_voltage, 1, lambda x: self.cb_voltage(1, x), self.increase_error_count)
        async_call(self.analog_in.get_sample_rate, None, self.get_sample_rate_async, self.increase_error_count)
        async_call(self.analog_in.get_channel_led_config,
                   CH_0,
                   lambda config: self.get_channel_led_config_async(CH_0, config),
                   self.increase_error_count)
        async_call(self.analog_in.get_channel_led_status_config,
                   CH_0,
                   lambda config: self.get_channel_led_status_config_async(CH_0, config),
                   self.increase_error_count)
        async_call(self.analog_in.get_channel_led_config,
                   CH_1,
                   lambda config: self.get_channel_led_config_async(CH_1, config),
                   self.increase_error_count)
        async_call(self.analog_in.get_channel_led_status_config,
                   CH_1,
                   lambda config: self.get_channel_led_status_config_async(CH_1, config),
                   self.increase_error_count)

        self.cbe_voltage0.set_period(100)
        self.cbe_voltage1.set_period(100)

        self.plot_widget.stop = False

    def stop(self):
        self.cbe_voltage0.set_period(0)
        self.cbe_voltage1.set_period(0)

        self.plot_widget.stop = True

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

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

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

        self.calibration_button.setEnabled(False)
        self.calibration.show()

    def sample_rate_combo_index_changed(self, index):
        async_call(self.analog_in.set_sample_rate, index, None, self.increase_error_count)

    def led_config_ch0_combo_changed(self, index):
        if index != self.analog_in.CHANNEL_LED_CONFIG_SHOW_CHANNEL_STATUS:
            for e in self.ui_group_ch_status_ch0:
                e.setEnabled(False)
        else:
            for e in self.ui_group_ch_status_ch0:
                e.setEnabled(True)

        self.analog_in.set_channel_led_config(CH_0, index)

    def led_config_ch1_combo_changed(self, index):
        if index != self.analog_in.CHANNEL_LED_CONFIG_SHOW_CHANNEL_STATUS:
            for e in self.ui_group_ch_status_ch1:
                e.setEnabled(False)
        else:
            for e in self.ui_group_ch_status_ch1:
                e.setEnabled(True)

        self.analog_in.set_channel_led_config(CH_1, index)

    def led_status_config_ch0_combo_changed(self, index):
        self.analog_in.set_channel_led_status_config(CH_0,
                                                     self.led_status_config_ch0_min_sbox.value(),
                                                     self.led_status_config_ch0_max_sbox.value(),
                                                     index)

    def led_status_config_ch1_combo_changed(self, index):
        self.analog_in.set_channel_led_status_config(CH_1,
                                                     self.led_status_config_ch1_min_sbox.value(),
                                                     self.led_status_config_ch1_max_sbox.value(),
                                                     index)

    def led_status_config_ch0_min_sbox_changed(self, value):
        QObject.sender(self).blockSignals(True)

        self.analog_in.set_channel_led_status_config(CH_0,
                                                     self.led_status_config_ch0_min_sbox.value(),
                                                     self.led_status_config_ch0_max_sbox.value(),
                                                     self.led_status_config_ch0_combo.currentIndex())

        QObject.sender(self).blockSignals(False)

    def led_status_config_ch0_max_sbox_changed(self, value):
        QObject.sender(self).blockSignals(True)

        self.analog_in.set_channel_led_status_config(CH_0,
                                                     self.led_status_config_ch0_min_sbox.value(),
                                                     self.led_status_config_ch0_max_sbox.value(),
                                                     self.led_status_config_ch0_combo.currentIndex())

        QObject.sender(self).blockSignals(False)

    def led_status_config_ch1_min_sbox_changed(self, value):
        QObject.sender(self).blockSignals(True)


        self.analog_in.set_channel_led_status_config(CH_1,
                                                     self.led_status_config_ch1_min_sbox.value(),
                                                     self.led_status_config_ch1_max_sbox.value(),
                                                     self.led_status_config_ch1_combo.currentIndex())

        QObject.sender(self).blockSignals(False)

    def led_status_config_ch1_max_sbox_changed(self, value):
        QObject.sender(self).blockSignals(True)

        self.analog_in.set_channel_led_status_config(CH_1,
                                                     self.led_status_config_ch1_min_sbox.value(),
                                                     self.led_status_config_ch1_max_sbox.value(),
                                                     self.led_status_config_ch1_combo.currentIndex())

        QObject.sender(self).blockSignals(False)

    def get_voltage_value0(self):
        return self.voltage_value[0]

    def get_voltage_value1(self):
        return self.voltage_value[1]

    def get_sample_rate_async(self, rate):
        self.sample_rate_combo.blockSignals(True)

        self.sample_rate_combo.setCurrentIndex(rate)

        self.sample_rate_combo.blockSignals(False)

    def get_channel_led_config_async(self, channel, config):
        self.led_config_ch0_combo.blockSignals(True)
        self.led_config_ch1_combo.blockSignals(True)

        if channel == CH_0:
            self.led_config_ch0_combo.setCurrentIndex(config)
        elif channel == CH_1:
            self.led_config_ch1_combo.setCurrentIndex(config)

        self.led_config_ch0_combo.blockSignals(False)
        self.led_config_ch1_combo.blockSignals(False)

    def get_channel_led_status_config_async(self, channel, config):
        self.led_status_config_ch0_combo.blockSignals(True)
        self.led_status_config_ch1_combo.blockSignals(True)

        if channel == CH_0:
            self.led_status_config_ch0_combo.setCurrentIndex(config.config)
            self.led_status_config_ch0_max_sbox.setValue(config.max)
            self.led_status_config_ch0_min_sbox.setValue(config.min)
        elif channel == CH_1:
            self.led_status_config_ch1_combo.setCurrentIndex(config.config)
            self.led_status_config_ch1_max_sbox.setValue(config.max)
            self.led_status_config_ch1_min_sbox.setValue(config.min)

        self.led_status_config_ch0_combo.blockSignals(False)
        self.led_status_config_ch1_combo.blockSignals(False)

    def cb_voltage(self, sensor, voltage):
        self.current_voltage[sensor] = voltage / 1000.0
Example #38
0
class Window(QMainWindow):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)
        self.image = QImage()
        self.dirty = False
        self.filename = None
        self.mirroredvertically = False
        self.mirroredhorizontally = False
        self.printer = None
        self.create_widgets()
        self.create_actions()
        self.load_settings()
        self.setWindowTitle("Image Changer")
        self.updateFileMenu()
        QTimer.singleShot(0, self.loadInitialFile)

    def create_widgets(self):
        self.imageLabel = QLabel()
        self.imageLabel.setMinimumSize(200, 200)
        self.imageLabel.setAlignment(Qt.AlignCenter)
        self.imageLabel.setContextMenuPolicy(Qt.ActionsContextMenu)
        self.setCentralWidget(self.imageLabel)

        logDockWidget = QDockWidget("Log", self)
        logDockWidget.setObjectName("LogDockWidget")
        logDockWidget.setAllowedAreas(Qt.LeftDockWidgetArea
                                      | Qt.RightDockWidgetArea)
        self.listWidget = QListWidget()
        logDockWidget.setWidget(self.listWidget)
        self.addDockWidget(Qt.RightDockWidgetArea, logDockWidget)

        self.sizeLabel = QLabel()
        self.sizeLabel.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken)
        status = self.statusBar()
        status.setSizeGripEnabled(False)
        status.addPermanentWidget(self.sizeLabel)
        status.showMessage("Ready", 5000)

    def create_actions(self):
        fileNewAction = self.createAction("&New...", self.fileNew,
                                          QKeySequence.New, "filenew",
                                          "Create an image file")
        fileOpenAction = self.createAction("&Open...", self.fileOpen,
                                           QKeySequence.Open, "fileopen",
                                           "Open an existing image file")
        fileSaveAction = self.createAction("&Save", self.fileSave,
                                           QKeySequence.Save, "filesave",
                                           "Save the image")
        fileSaveAsAction = self.createAction(
            "Save &As...",
            self.fileSaveAs,
            icon="filesaveas",
            tip="Save the image using a new name")
        filePrintAction = self.createAction("&Print", self.filePrint,
                                            QKeySequence.Print, "fileprint",
                                            "Print the image")
        fileQuitAction = self.createAction("&Quit", self.close, "Ctrl+Q",
                                           "filequit", "Close the application")
        editInvertAction = self.createAction("&Invert", None, "Ctrl+I",
                                             "editinvert",
                                             "Invert the image's colors", True)
        editInvertAction.toggled.connect(self.editInvert)
        editSwapRedAndBlueAction = self.createAction(
            "Sw&ap Red and Blue", None, "Ctrl+A", "editswap",
            "Swap the image's red and blue color components", True)
        editSwapRedAndBlueAction.toggled.connect(self.editSwapRedAndBlue)
        editZoomAction = self.createAction("&Zoom...", self.editZoom, "Alt+Z",
                                           "editzoom", "Zoom the image")
        mirrorGroup = QActionGroup(self)
        editUnMirrorAction = self.createAction("&Unmirror", None, "Ctrl+U",
                                               "editunmirror",
                                               "Unmirror the image", True)
        editUnMirrorAction.toggled.connect(self.editUnMirror)
        mirrorGroup.addAction(editUnMirrorAction)
        editMirrorHorizontalAction = self.createAction(
            "Mirror &Horizontally", None, "Ctrl+H", "editmirrorhoriz",
            "Horizontally mirror the image", True)
        editMirrorHorizontalAction.toggled.connect(self.editMirrorHorizontal)
        mirrorGroup.addAction(editMirrorHorizontalAction)
        editMirrorVerticalAction = self.createAction(
            "Mirror &Vertically", None, "Ctrl+V", "editmirrorvert",
            "Vertically mirror the image", True)
        editMirrorVerticalAction.toggled.connect(self.editMirrorVertical)
        mirrorGroup.addAction(editMirrorVerticalAction)
        editUnMirrorAction.setChecked(True)
        helpAboutAction = self.createAction("&About Image Changer",
                                            self.helpAbout)
        helpHelpAction = self.createAction("&Help", self.helpHelp,
                                           QKeySequence.HelpContents)

        self.fileMenu = self.menuBar().addMenu("&File")
        self.fileMenuActions = (fileNewAction, fileOpenAction, fileSaveAction,
                                fileSaveAsAction, None, filePrintAction,
                                fileQuitAction)
        self.fileMenu.aboutToShow.connect(self.updateFileMenu)
        editMenu = self.menuBar().addMenu("&Edit")
        self.addActions(
            editMenu,
            (editInvertAction, editSwapRedAndBlueAction, editZoomAction))
        mirrorMenu = editMenu.addMenu(QIcon(":/editmirror.png"), "&Mirror")
        self.addActions(mirrorMenu,
                        (editUnMirrorAction, editMirrorHorizontalAction,
                         editMirrorVerticalAction))
        helpMenu = self.menuBar().addMenu("&Help")
        self.addActions(helpMenu, (helpAboutAction, helpHelpAction))

        fileToolbar = self.addToolBar("File")
        fileToolbar.setObjectName("FileToolBar")
        self.addActions(fileToolbar,
                        (fileNewAction, fileOpenAction, fileSaveAsAction))
        editToolbar = self.addToolBar("Edit")
        editToolbar.setObjectName("EditToolBar")
        self.addActions(
            editToolbar,
            (editInvertAction, editSwapRedAndBlueAction, editUnMirrorAction,
             editMirrorVerticalAction, editMirrorHorizontalAction))
        self.zoomSpinBox = QSpinBox()
        self.zoomSpinBox.setRange(1, 400)
        self.zoomSpinBox.setSuffix(" %")
        self.zoomSpinBox.setValue(100)
        self.zoomSpinBox.setToolTip("Zoom the image")
        self.zoomSpinBox.setStatusTip(self.zoomSpinBox.toolTip())
        self.zoomSpinBox.setFocusPolicy(Qt.NoFocus)
        self.zoomSpinBox.valueChanged.connect(self.showImage)
        editToolbar.addWidget(self.zoomSpinBox)

        self.addActions(
            self.imageLabel,
            (editInvertAction, editSwapRedAndBlueAction, editUnMirrorAction,
             editMirrorVerticalAction, editMirrorHorizontalAction))

        self.resetableActions = ((editInvertAction,
                                  False), (editSwapRedAndBlueAction, False),
                                 (editUnMirrorAction, True))

    def load_settings(self):
        settings = QSettings()
        self.recentFiles = settings.value("RecentFiles").toStringList()
        self.restoreGeometry(
            settings.value("MainWindow/Geometry").toByteArray())
        self.restoreState(settings.value("MainWindow/State").toByteArray())

    def createAction(self,
                     text,
                     slot=None,
                     shortcut=None,
                     icon=None,
                     tip=None,
                     checkable=False):
        action = QAction(text, self)
        if icon is not None:
            action.setIcon(QIcon(":/{0}.png".format(icon)))
        if shortcut is not None:
            action.setShortcut(shortcut)
        if tip is not None:
            action.setToolTip(tip)
            action.setStatusTip(tip)
        if slot is not None:
            action.triggered.connect(slot)
        if checkable:
            action.setCheckable(True)
        return action

    def addActions(self, target, actions):
        for action in actions:
            if action is None:
                target.addSeparator()
            else:
                target.addAction(action)

    def closeEvent(self, event):
        if self.okToContinue():
            settings = QSettings()
            filename = (QVariant(QString(self.filename))
                        if self.filename is not None else QVariant())
            settings.setValue("LastFile", filename)
            recentFiles = (QVariant(self.recentFiles)
                           if self.recentFiles else QVariant())
            settings.setValue("RecentFiles", recentFiles)
            settings.setValue("MainWindow/Geometry",
                              QVariant(self.saveGeometry()))
            settings.setValue("MainWindow/State", QVariant(self.saveState()))
        else:
            event.ignore()

    def okToContinue(self):
        if self.dirty:
            reply = QMessageBox.question(
                self, "Image Changer - Unsaved Changes",
                "Save unsaved changes?",
                QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel)
            if reply == QMessageBox.Cancel:
                return False
            elif reply == QMessageBox.Yes:
                return self.fileSave()
        return True

    def loadInitialFile(self):
        settings = QSettings()
        fname = unicode(settings.value("LastFile").toString())
        if fname and QFile.exists(fname):
            self.loadFile(fname)

    def updateStatus(self, message):
        self.statusBar().showMessage(message, 5000)
        self.listWidget.addItem(message)
        if self.filename is not None:
            self.setWindowTitle("Image Changer - {0}[*]".format(
                os.path.basename(self.filename)))
        elif not self.image.isNull():
            self.setWindowTitle("Image Changer - Unnamed[*]")
        else:
            self.setWindowTitle("Image Changer[*]")
        self.setWindowModified(self.dirty)

    def updateFileMenu(self):
        self.fileMenu.clear()
        self.addActions(self.fileMenu, self.fileMenuActions[:-1])
        current = (QString(self.filename)
                   if self.filename is not None else None)
        recentFiles = []
        for fname in self.recentFiles:
            if fname != current and QFile.exists(fname):
                recentFiles.append(fname)
        if recentFiles:
            self.fileMenu.addSeparator()
            for i, fname in enumerate(recentFiles):
                action = QAction(
                    QIcon(":/icon.png"),
                    "&{0} {1}".format(i + 1,
                                      QFileInfo(fname).fileName()), self)
                action.setData(QVariant(fname))
                action.triggered.connect(self.loadFile)
                self.fileMenu.addAction(action)
        self.fileMenu.addSeparator()
        self.fileMenu.addAction(self.fileMenuActions[-1])

    def fileNew(self):
        if not self.okToContinue():
            return
        dialog = newimagedlg.NewImageDlg(self)
        if dialog.exec_():
            self.addRecentFile(self.filename)
            self.image = QImage()
            for action, check in self.resetableActions:
                action.setChecked(check)
            self.image = dialog.image()
            self.filename = None
            self.dirty = True
            self.showImage()
            self.sizeLabel.setText("{0} x {1}".format(self.image.width(),
                                                      self.image.height()))
            self.updateStatus("Created new image")

    def fileOpen(self):
        if not self.okToContinue():
            return
        dir = (os.path.dirname(self.filename)
               if self.filename is not None else ".")
        formats = ([
            "*.{0}".format(unicode(format).lower())
            for format in QImageReader.supportedImageFormats()
        ])
        fname = unicode(
            QFileDialog.getOpenFileName(
                self, "Image Changer - Choose Image", dir,
                "Image files ({0})".format(" ".join(formats))))
        if fname:
            self.loadFile(fname)

    def loadFile(self, fname=None):
        if fname is None:
            action = self.sender()
            if isinstance(action, QAction):
                fname = unicode(action.data().toString())
                if not self.okToContinue():
                    return
            else:
                return
        if fname:
            self.filename = None
            image = QImage(fname)
            if image.isNull():
                message = "Failed to read {0}".format(fname)
            else:
                self.addRecentFile(fname)
                self.image = QImage()
                for action, check in self.resetableActions:
                    action.setChecked(check)
                self.image = image
                self.filename = fname
                self.showImage()
                self.dirty = False
                self.sizeLabel.setText("{0} x {1}".format(
                    image.width(), image.height()))
                message = "Loaded {0}".format(os.path.basename(fname))
            self.updateStatus(message)

    def addRecentFile(self, fname):
        if fname is None:
            return
        if not self.recentFiles.contains(fname):
            self.recentFiles.prepend(QString(fname))
            while self.recentFiles.count() > 9:
                self.recentFiles.takeLast()

    def fileSave(self):
        if self.image.isNull():
            return True
        if self.filename is None:
            return self.fileSaveAs()
        else:
            if self.image.save(self.filename, None):
                self.updateStatus("Saved as {0}".format(self.filename))
                self.dirty = False
                return True
            else:
                self.updateStatus("Failed to save {0}".format(self.filename))
                return False

    def fileSaveAs(self):
        if self.image.isNull():
            return True
        fname = self.filename if self.filename is not None else "."
        formats = ([
            "*.{0}".format(unicode(format).lower())
            for format in QImageWriter.supportedImageFormats()
        ])
        fname = unicode(
            QFileDialog.getSaveFileName(
                self, "Image Changer - Save Image", fname,
                "Image files ({0})".format(" ".join(formats))))
        if fname:
            if "." not in fname:
                fname += ".png"
            self.addRecentFile(fname)
            self.filename = fname
            return self.fileSave()
        return False

    def filePrint(self):
        if self.image.isNull():
            return
        if self.printer is None:
            self.printer = QPrinter(QPrinter.HighResolution)
            self.printer.setPageSize(QPrinter.Letter)
        form = QPrintDialog(self.printer, self)
        if form.exec_():
            painter = QPainter(self.printer)
            rect = painter.viewport()
            size = self.image.size()
            size.scale(rect.size(), Qt.KeepAspectRatio)
            painter.setViewport(rect.x(), rect.y(), size.width(),
                                size.height())
            painter.drawImage(0, 0, self.image)

    def editInvert(self, on):
        if self.image.isNull():
            return
        self.image.invertPixels()
        self.showImage()
        self.dirty = True
        self.updateStatus("Inverted" if on else "Uninverted")

    def editSwapRedAndBlue(self, on):
        if self.image.isNull():
            return
        self.image = self.image.rgbSwapped()
        self.showImage()
        self.dirty = True
        self.updateStatus(
            ("Swapped Red and Blue" if on else "Unswapped Red and Blue"))

    def editUnMirror(self, on):
        if self.image.isNull():
            return
        if self.mirroredhorizontally:
            self.editMirrorHorizontal(False)
        if self.mirroredvertically:
            self.editMirrorVertical(False)

    def editMirrorHorizontal(self, on):
        if self.image.isNull():
            return
        self.image = self.image.mirrored(True, False)
        self.showImage()
        self.mirroredhorizontally = not self.mirroredhorizontally
        self.dirty = True
        self.updateStatus(
            ("Mirrored Horizontally" if on else "Unmirrored Horizontally"))

    def editMirrorVertical(self, on):
        if self.image.isNull():
            return
        self.image = self.image.mirrored(False, True)
        self.showImage()
        self.mirroredvertically = not self.mirroredvertically
        self.dirty = True
        self.updateStatus(
            ("Mirrored Vertically" if on else "Unmirrored Vertically"))

    def editZoom(self):
        if self.image.isNull():
            return
        percent, ok = QInputDialog.getInteger(self, "Image Changer - Zoom",
                                              "Percent:",
                                              self.zoomSpinBox.value(), 1, 400)
        if ok:
            self.zoomSpinBox.setValue(percent)

    def showImage(self, percent=None):
        if self.image.isNull():
            return
        if percent is None:
            percent = self.zoomSpinBox.value()
        factor = percent / 100.0
        width = self.image.width() * factor
        height = self.image.height() * factor
        image = self.image.scaled(width, height, Qt.KeepAspectRatio)
        self.imageLabel.setPixmap(QPixmap.fromImage(image))

    def helpAbout(self):
        QMessageBox.about(
            self, "About Image Changer", """<b>Image Changer</b> v {0}
                <p>Copyright &copy; 2008-14 Qtrac Ltd. 
                All rights reserved.
                <p>This application can be used to perform
                simple image manipulations.
                <p>Python {1} - Qt {2} - PyQt {3} on {4}""".format(
                __version__, platform.python_version(), QT_VERSION_STR,
                PYQT_VERSION_STR, platform.system()))

    def helpHelp(self):
        form = helpform.HelpForm("index.html", self)
        form.show()
Example #39
0
class Img2GifWidget(QDialog):
    AppName = u"GIF生成工具"
    
    def __init__(self, parent=None):
        super(Img2GifWidget, self).__init__(parent)
        self.setWindowTitle(Img2GifWidget.AppName)

        self.listWidget = QListWidget()
        self.listWidget.setMinimumSize(400, 300)
        self.btnAdd = QPushButton("&Add")
        self.btnUp = QPushButton("&Up")
        self.btnDown = QPushButton("&Down")
        self.btnDel = QPushButton("&Delete")
        self.btnClear = QPushButton("&Clear")
        topLeftLay = QVBoxLayout()
        topLeftLay.addWidget(self.btnAdd)
        topLeftLay.addWidget(self.btnUp)
        topLeftLay.addWidget(self.btnDown)
        topLeftLay.addWidget(self.btnDel)
        topLeftLay.addWidget(self.btnClear)
        topLeftLay.addStretch()
        topLay = QHBoxLayout()
        topLay.addWidget(self.listWidget)
        topLay.addLayout(topLeftLay)
        
        label = QLabel(u"Gif文件路径:")
        self.txtGifPath = QLineEdit()
        self.btnBrowser = QPushButton('...')
        midLay = QHBoxLayout()
        midLay.addWidget(label)
        midLay.addWidget(self.txtGifPath)
        midLay.addWidget(self.btnBrowser)

        timeLabel = QLabel(u"时间间隔:")
        self.spbTime = QDoubleSpinBox()
        self.spbTime.setRange(0.001, 10)
        self.spbTime.setSingleStep(0.001)
        self.spbTime.setValue(1)
        self.spbTime.setSuffix('s')
        loopLabel = QLabel(u"循环:")
        self.spbLoop = QDoubleSpinBox()
        self.spbLoop = QSpinBox()
        self.spbLoop.setRange(0, 1000)
        self.spbLoop.setSingleStep(1)
        self.spbLoop.setValue(0)
        self.spbLoop.setToolTip(u"0次循环表示永久循环")
        self.spbLoop.setSuffix(u"次")
        self.btnBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        bottomLay = QHBoxLayout()
        bottomLay.addWidget(timeLabel)
        bottomLay.addWidget(self.spbTime)
        bottomLay.addWidget(loopLabel)
        bottomLay.addWidget(self.spbLoop)
        bottomLay.addStretch()
        bottomLay.addWidget(self.btnBox)
        
        mainLay = QVBoxLayout()
        mainLay.addLayout(topLay)
        mainLay.addLayout(midLay)
        mainLay.addLayout(bottomLay)
        self.setLayout(mainLay)

        self.btnAdd.clicked.connect(self.itemAdd)
        self.btnUp.clicked.connect(self.itemUp)
        self.btnDown.clicked.connect(self.itemDown)
        self.btnDel.clicked.connect(self.itemDel)
        self.btnClear.clicked.connect(self.listWidget.clear)
        self.btnBrowser.clicked.connect(self.setGifPath)
        self.btnBox.rejected.connect(self.close)
        self.btnBox.accepted.connect(self.makeGif)

        self.txtGifPath.returnPressed.connect(self.updateGifPath)

    def itemAdd(self):
        fileNames = QFileDialog.getOpenFileNames(None, u"{0} -- {1}".format(qApp.applicationName(), Img2GifWidget.AppName),
                                                 '.', u'所有文件(*.*);;BMP文件(*.bmp);;PNG文件(*.png);;JPG文件(*.jpg *.jpeg)')
        for fn in fileNames:
            f = QFileInfo(fn)
            if unicode(f.suffix().toLower()) in ['jpg', 'png', 'bmp', 'jpeg']:
                self.listWidget.addItem(fn)

    def itemUp(self):
        row = self.listWidget.currentRow()
        if row <= 0:
            return
        item = self.listWidget.currentItem()
        self.listWidget.takeItem(row)
        self.listWidget.insertItem(row - 1, item)
        self.listWidget.setCurrentRow(row - 1)

    def itemDown(self):
        rows = self.listWidget.count()
        row = self.listWidget.currentRow()
        if (row < 0) or (row == rows - 1):
            return
        item = self.listWidget.currentItem()
        self.listWidget.takeItem(row)
        self.listWidget.insertItem(row + 1, item)
        self.listWidget.setCurrentRow(row + 1)

    def itemDel(self):
        row = self.listWidget.currentRow()
        if row >= 0:
            self.listWidget.takeItem(row)

    def setGifPath(self):
        filename = QFileDialog.getSaveFileName(self, u"{0} -- {1}".format(qApp.applicationName(), Img2GifWidget.AppName),
                                               ".", "Gif(*.gif)")
        self.txtGifPath.setText(filename)

    def updateGifPath(self):
        fileName = self.txtGifPath.text()
        f = QFileInfo(fileName)
        if f.dir().exists and not f.baseName().isEmpty() and not f.suffix().isEmpty():
            self.txtGifPath.setText(fileName)
            return True
        else:
            QMessageBox.warning(self, u"{0} -- warning".format(Img2GifWidget.AppName),
                                u"要生成的GIF存储路径{0}不是有效的GIF文件".format(unicode(fileName)))
            return False

    def makeGif(self):

        imgs = [unicode(self.listWidget.item(i).text()) for i in range(self.listWidget.count())]
        if len(imgs) <= 1:
            QMessageBox.warning(self, u"{0} - {1}".format(qApp.applicationName(), Img2GifWidget.AppName),
                                u"GIF动画文件必须要给定大于一张图片。")
            return
        if not self.updateGifPath():
            return
        durations = self.spbTime.value()
        loops = self.spbLoop.value()
        ok, msg = img2gif.images2gif(imgs, self.txtGifPath.text(), durations=durations, loops=loops)
        if ok:
            QMessageBox.about(self, u"{0} - {1}".format(qApp.applicationName(), Img2GifWidget.AppName),
                              u"Succeed!\n{0}".format(msg))
            qApp.processEvents()
        else:
            QMessageBox.about(u"{0} - {1}".format(qApp.applicationName(), Img2GifWidget.AppName),
                              u"sorry! Failed to generate the {0}".format(unicode(self.txtGifPath)))