Beispiel #1
0
class ValidatingLineEdit(LineEdit):
    statusChanged = pyqtSignal()

    def __init__(self, parent=None):
        super(ValidatingLineEdit, self).__init__(parent)
        self.invalid_entry_label = QLabel(self)
        self.invalid_entry_label.setFixedSize(18, 16)
        self.invalid_entry_label.setPixmap(
            QPixmap(Resources.get('icons/invalid16.png')))
        self.invalid_entry_label.setScaledContents(False)
        self.invalid_entry_label.setAlignment(Qt.AlignCenter)
        self.invalid_entry_label.setObjectName('invalid_entry_label')
        self.invalid_entry_label.hide()
        self.addTailWidget(self.invalid_entry_label)
        option = QStyleOptionFrameV2()
        self.initStyleOption(option)
        frame_width = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth,
                                               option, self)
        self.setMinimumHeight(self.invalid_entry_label.minimumHeight() + 2 +
                              2 * frame_width)
        self.textChanged.connect(self._SH_TextChanged)
        self.text_correct = True
        self.text_allowed = True
        self.exceptions = set()
        self.regexp = re.compile(r'.*')

    def _get_regexp(self):
        return self.__dict__['regexp']

    def _set_regexp(self, regexp):
        self.__dict__['regexp'] = regexp
        self._validate()

    regexp = property(_get_regexp, _set_regexp)
    del _get_regexp, _set_regexp

    @property
    def text_valid(self):
        return self.text_correct and self.text_allowed

    def _SH_TextChanged(self, text):
        self._validate()

    def _validate(self):
        text = self.text()
        text_correct = self.regexp.search(text) is not None
        text_allowed = text not in self.exceptions
        if self.text_correct != text_correct or self.text_allowed != text_allowed:
            self.text_correct = text_correct
            self.text_allowed = text_allowed
            self.invalid_entry_label.setVisible(not self.text_valid)
            self.statusChanged.emit()

    def addException(self, exception):
        self.exceptions.add(exception)
        self._validate()

    def removeException(self, exception):
        self.exceptions.remove(exception)
        self._validate()
Beispiel #2
0
class DialogLoginKey(QDialog):
    def __init__(self, parent, windowTitle, icon=None):
        def initGui():
            def connect():
                buttonLogin.clicked.connect(self.onLogin)
                self.textKey.textEdited.connect(self.onTextEdited)

            #
            self.setWindowTitle(windowTitle)
            if not icon is None:
                self.setWindowIcon(icon)
            labelKey = QLabel("Key: ", self)
            self.labelError = QLabel(self)
            self.labelError.hide()
            self.textKey = QLineEdit(self)
            self.textKey.setEchoMode(QLineEdit.Password)
            buttonLogin = QPushButton("Login", self)
            connect()
            layout = QVBoxLayout(self)
            layout.addWidget(labelKey)
            layout.addWidget(self.textKey)
            layout.addWidget(buttonLogin)
            layout.addWidget(self.labelError)
            #
            self.resize(4 * len(windowTitle) + 200, 30)

        #
        super(DialogLoginKey, self).__init__(parent)
        self.apiPL = API_PlanetLabs()
        self.responsePL = None
        initGui()

    @pyqtSlot(bool)
    def onLogin(self, checked):
        def setFinishedPL(response):
            self.responsePL = response
            loop.quit()

        def setKeyResponse():
            if self.responsePL['isOk']:
                self.accept()
            else:
                self.labelError.setTextFormat(Qt.RichText)
                msg = "<font color=\"red\"><b><i>Invalid key! %s</i></b></font>" % self.responsePL[
                    'message']
                self.labelError.setText(msg)
                self.labelError.show()

        key = self.textKey.text().encode('ascii', 'ignore')
        self.responsePL = None
        loop = QEventLoop()
        self.apiPL.setKey(key, setFinishedPL)
        loop.exec_()
        setKeyResponse()

    @pyqtSlot(str)
    def onTextEdited(self, text):
        if self.labelError.isHidden():
            return
        self.labelError.hide()
Beispiel #3
0
class TrueFalseCardShowWidget(QWidget):
    def __init__(self, parent=None):
        super(TrueFalseCardShowWidget, self).__init__(parent)
        self.grid = QGridLayout()
        self.setLayout(self.grid)

        self.word_label = QLabel('Word')
        self.word_label.setAlignment(Qt.AlignCenter)
        self.grid.addWidget(self.word_label, 0, 0)
        self.word_label.setFont(QFont('SansSerif', 13))

        self.example_label = QLabel('Example')
        self.example_label.setWordWrap(True);
        self.example_label.setAlignment(Qt.AlignCenter)
        self.grid.addWidget(self.example_label, 1, 0)
        self.example_label.setFont(QFont('SansSerif', 13))

        self.translation_label = QLabel('Translation')
        self.translation_label.setWordWrap(True);
        self.translation_label.setAlignment(Qt.AlignCenter)
        self.grid.addWidget(self.translation_label, 2, 0)
        self.translation_label.setFont(QFont('SansSerif', 13))
        self.translation_label.hide()

    def show_card(self, card):
        """
        Show card
        :param card: the card to show
        :type card:Card
        """
        self.word_label.setText(card.word)
        self.example_label.setText(card.example)
        self.translation_label.setText(card.translation)
        self.translation_label.hide()
Beispiel #4
0
 def createPixmapWidget(self, parent, iconName):
     w = QLabel(parent)
     parent.layout().addWidget(w)
     w.setFixedSize(16, 16)
     w.hide()
     if os.path.exists(iconName):
         w.setPixmap(QPixmap(iconName))
     return w
Beispiel #5
0
 def createPixmapWidget(self, parent, iconName):
     w = QLabel(parent)
     parent.layout().addWidget(w)
     w.setFixedSize(16, 16)
     w.hide()
     if os.path.exists(iconName):
         w.setPixmap(QPixmap(iconName))
     return w
Beispiel #6
0
class ValidatingLineEdit(LineEdit):
    statusChanged = pyqtSignal()

    def __init__(self, parent=None):
        super(ValidatingLineEdit, self).__init__(parent)
        self.invalid_entry_label = QLabel(self)
        self.invalid_entry_label.setFixedSize(18, 16)
        self.invalid_entry_label.setPixmap(QPixmap(Resources.get('icons/invalid16.png')))
        self.invalid_entry_label.setScaledContents(False)
        self.invalid_entry_label.setAlignment(Qt.AlignCenter)
        self.invalid_entry_label.setObjectName('invalid_entry_label')
        self.invalid_entry_label.hide()
        self.addTailWidget(self.invalid_entry_label)
        option = QStyleOptionFrameV2()
        self.initStyleOption(option)
        frame_width = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth, option, self)
        self.setMinimumHeight(self.invalid_entry_label.minimumHeight() + 2 + 2*frame_width)
        self.textChanged.connect(self._SH_TextChanged)
        self.text_correct = True
        self.text_allowed = True
        self.exceptions = set()
        self.regexp = re.compile(r'.*')

    def _get_regexp(self):
        return self.__dict__['regexp']

    def _set_regexp(self, regexp):
        self.__dict__['regexp'] = regexp
        self._validate()

    regexp = property(_get_regexp, _set_regexp)
    del _get_regexp, _set_regexp

    @property
    def text_valid(self):
        return self.text_correct and self.text_allowed

    def _SH_TextChanged(self, text):
        self._validate()

    def _validate(self):
        text = self.text()
        text_correct = self.regexp.search(text) is not None
        text_allowed = text not in self.exceptions
        if self.text_correct != text_correct or self.text_allowed != text_allowed:
            self.text_correct = text_correct
            self.text_allowed = text_allowed
            self.invalid_entry_label.setVisible(not self.text_valid)
            self.statusChanged.emit()

    def addException(self, exception):
        self.exceptions.add(exception)
        self._validate()

    def removeException(self, exception):
        self.exceptions.remove(exception)
        self._validate()
Beispiel #7
0
 def download_(self):
     print("download_")
     self.b = QCommandLinkButton("")
     self.b.clicked.connect(self.get_setup)
     msg = QLabel("Connexion ...")
     self.addWidget(msg)
     msg.hide()
     self.b.setText(self.check.data.get("message"))
     self.addWidget(self.b)
 def add_group_selector(self):
     self.module_group_box = QComboBox(self)
     self.module_group_box.currentIndexChanged.connect(self.state_changed)
     lab = QLabel("Module Group:")
     lab.setAlignment(Qt.AlignRight)
     self.grid_layout.addWidget(lab, self.rowCount(), 0)
     self.grid_layout.addWidget(self.module_group_box,
                                self.rowCount() - 1, 1)
     lab.hide()
     self.module_group_box.hide()
     self.module_group_box.addItem("R (0)")
     self.module_group_box.addItem("Phi (1)")
Beispiel #9
0
    def buildInterface(self, config):
        #<server uri>
        self.uri = QLineEdit()
        self.texts.add(self.uri)
        self.connect(self.uri, SIGNAL('textChanged(QString)'), self.setUri)
        self.connect(self.uri, SIGNAL('textChanged(QString)'), self.signalModified)
        self.connect(self.uri, SIGNAL('textEdited(QString)'), self.helpURI)
        self.connect(self.uri, SIGNAL('editingFinished()'), self.noHelpURI)
        self.connect(self.uri, SIGNAL('editingFinished()'), self.updateUri)
        self.form.addRow(tr('LDAP Server(s) uri'), self.uri)

        self.uri.setToolTip(help_uri_tooltip)
        self.connect(self.uri, SIGNAL('returnPressed()'), self.signalModified)

        self.uri_message_area = MessageArea()
        self.empty_uri_label = QLabel()
        self.form.addRow(self.empty_uri_label, self.uri_message_area)
        self.empty_uri_label.hide()
        self.uri_message_area.hide()
        self.uri_message_area.setMessage(help_uri_title, help_uri_message_area)

        self.numeric_uri_warning = MessageArea()
        empty  = QLabel()
        self.form.addRow(empty, self.numeric_uri_warning)
        empty.hide()
        self.numeric_uri_warning.hide()
        self.numeric_uri_warning.warning(numeric_warning_title, numeric_warning)
        self.numeric_uri_warning.setWidth(60)

        #</server uri>

        #<other fields>
        for args in self._genTextFieldsData():
            text_input = self.addTextInput(*args[1:])
            setattr(self, args[0], text_input)
            self.connect(text_input, SIGNAL('editingFinished(QString)'), self.valid)
        #</other fields>

        self.ssl_box = self.mkSslBox()
        self.connect(self.ssl_box, SIGNAL('toggled(bool)'), self.toggleSsl)
        self.form.addRow(self.ssl_box)

        self.form.addRow(separator())

        test_widget = QPushButton(tr("Test this configuration"))
        self.form.addRow("", test_widget)
        test_widget.connect(test_widget, SIGNAL('clicked()'), self.test_ldap)
class InteractiveItem(QGraphicsRectItem):
    def __init__(self, bgc_info, *args, **kargs):
        QGraphicsRectItem.__init__(self, *args, **kargs)
        self.node = None
        self.label = None
        self.bgc_info = bgc_info
        self.setCursor(QtCore.Qt.PointingHandCursor)
        self.setAcceptsHoverEvents(True)

    def hoverEnterEvent (self, e):
        # Show/hide a text item over the custom DynamicItemFace
        if not self.label:
            self.label = QLabel(self.bgc_info)
        self.label.show()

    def hoverLeaveEvent(self, e):
        if self.label:
            self.label.hide()
Beispiel #11
0
class Help(QFrame):
    def __init__(self, parent=None):
        QFrame.__init__(self, parent)
        layout = QHBoxLayout(self)
        self.icon = QLabel()
        self.icon.setPixmap(QPixmap(":/icons-32/info"))
        layout.addWidget(self.icon)
        self.message = QLabel()
        self.message.setWordWrap(True)
        layout.addWidget(self.message)
        layout.addStretch()
        self.setNoMessage()

    def setMessage(self, text):
        self.message.setText(text)
        self.message.show()
        self.icon.show()
        self.setFrameStyle(QFrame.StyledPanel)

    def setNoMessage(self):
        self.message.hide()
        self.icon.hide()
        self.setFrameStyle(QFrame.NoFrame)
Beispiel #12
0
class ResultPlot(QWidget):

    def __init__(self):
        super(ResultPlot, self).__init__()
        vl = QVBoxLayout()
        self.plot = Plot()
        vl.setAlignment(Qt.AlignTop)
        vl.addWidget(self.plot)

        self.residual_plot = ResidualPlot()
        self.residual_plot.setFixedHeight(150)
        vl.addWidget(self.residual_plot)

        hl = QHBoxLayout()
        #hl.setAlignment(Qt.AlignHCenter)

        self.chi2_label = QLabel('chi^2')
        self.chi2_label.setFixedWidth(30)
        self.chi2_label.hide();
        self.chi2_value = QLineEdit()
        self.chi2_value.setAlignment(Qt.AlignRight)
        self.chi2_value.setFixedWidth(120)
        self.chi2_value.hide()

        auto_plot =  QCheckBox('Auto plot finished result')
        auto_plot.stateChanged.connect(self._on_auto_plot_state_changed)
        hl.addWidget(auto_plot, Qt.AlignLeft)
        hl.addWidget(self.chi2_label)
        hl.addWidget(self.chi2_value)
        hl.setStretch(1, 0)

        vl.addLayout(hl)
        self.setLayout(vl)

    def _on_auto_plot_state_changed(self, checked_state):
        checked_state = True if checked_state else False
        Global.event.interface_auto_plot_state_changed.emit(checked_state)
class FeatureFormWidget(Ui_Form, QWidget):
    # Raise the cancel event, takes a reason and a level
    cancel = pyqtSignal(str, int)
    featuresaved = pyqtSignal()
    featuredeleted = pyqtSignal()

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

        toolbar = QToolBar()
        size = QSize(48, 48)
        toolbar.setIconSize(size)
        style = Qt.ToolButtonTextUnderIcon
        toolbar.setToolButtonStyle(style)
        self.actionDelete = toolbar.addAction(QIcon(":/icons/delete"), "Delete")
        self.actionDelete.triggered.connect(self.delete_feature)

        label = 'Required fields marked in <b style="background-color:rgba(255, 221, 48,150)">yellow</b>'
        self.missingfieldsLabel = QLabel(label)
        self.missingfieldsLabel.hide()
        self.missingfieldaction = toolbar.addWidget(self.missingfieldsLabel)

        titlespacer = QWidget()
        titlespacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        toolbar.addWidget(titlespacer)
        self.titlellabel = QLabel(label)
        self.titlellabel.setProperty("headerlabel", True)
        self.titlelabelaction = toolbar.addWidget(self.titlellabel)

        spacer = QWidget()
        spacer2 = QWidget()
        spacer2.setMinimumWidth(20)
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        spacer2.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        toolbar.addWidget(spacer)
        self.actionCancel = toolbar.addAction(QIcon(":/icons/cancel"), "Cancel")
        toolbar.addWidget(spacer2)
        self.actionSave = toolbar.addAction(QIcon(":/icons/save"), "Save")
        self.actionSave.triggered.connect(self.save_feature)

        self.layout().insertWidget(0, toolbar)

        self.flickwidget = FlickCharm()
        self.flickwidget.activateOn(self.scrollArea)

        self.featureform = None
        self.values = {}
        self.config = {}
        self.feature = None

    def set_featureform(self, featureform):
        """
        Note: There can only be one feature form.  If you need to show another one make a new FeatureFormWidget
        """
        self.featureform = featureform
        self.titlellabel.setText(self.featureform.windowTitle())
        self.featureform.formvalidation.connect(self._update_validation)
        self.featureform.helprequest.connect(functools.partial(RoamEvents.helprequest.emit, self))
        self.featureform.showlargewidget.connect(RoamEvents.show_widget.emit)
        self.featureform.enablesave.connect(self.actionSave.setEnabled)
        self.featureform.enablesave.connect(self.actionSave.setVisible)
        self.featureform.rejected.connect(self.cancel.emit)

        self.featureformarea.layout().addWidget(self.featureform)

    def delete_feature(self):
        try:
            msg = self.featureform.deletemessage
        except AttributeError:
            msg = 'Do you really want to delete this feature?'

        box = DeleteFeatureDialog(msg)

        if not box.exec_():
            return

        try:
            self.featureform.delete()
        except featureform.DeleteFeatureException as ex:
            RoamEvents.raisemessage(*ex.error)

        self.featureform.featuredeleted(self.feature)
        self.featuredeleted.emit()

    def save_feature(self):
        try:
            self.featureform.save()
        except featureform.MissingValuesException as ex:
            RoamEvents.raisemessage(*ex.error)
            return
        except featureform.FeatureSaveException as ex:
            RoamEvents.raisemessage(*ex.error)

        self.featuresaved.emit()
        RoamEvents.featuresaved.emit()

    def set_config(self, config):
        self.config = config
        editmode = config['editmode']
        allowsave = config.get('allowsave', True)
        self.feature = config.get('feature', None)
        self.featureform.feature = self.feature
        self.featureform.editingmode = editmode
        self.actionDelete.setVisible(editmode)
        self.actionSave.setEnabled(allowsave)

    def _update_validation(self, passed):
        # Show the error if there is missing fields
        self.missingfieldaction.setVisible(not passed)

    def bind_values(self, values):
        self.values = values
        self.featureform.bindvalues(values)

    def after_load(self):
        self.featureform.loaded()

    def before_load(self):
        self.featureform.load(self.config['feature'], self.config['layers'], self.values)
Beispiel #14
0
class entrar(QDialog):
    def __init__(self):

        super(entrar, self).__init__(None)

        self.resize(400, 440)
        self.setWindowTitle('Datos de Usuario')

        self.imaje = QLabel(self)
        self.imaje.setGeometry(160, 210, 225, 225)
        self.imaje.setPixmap(QPixmap(getcwd() + "/usuario.gif"))

        self.n = QLabel('Nombre Completo:', self)
        self.n.move(10, 10)

        self.u = QLabel('Nombre de Usuario:', self)
        self.u.move(10, 50)

        self.failu = QLabel('Este Usuario ya Existe', self)
        self.failu.move(140, 70)
        self.failu.hide()

        self.c = QLabel('Correo Electronico:', self)
        self.c.move(10, 90)

        self.a = QLabel('Edad:', self)
        self.a.move(10, 130)

        self.faila = QLabel('Ingrese una Edad', self)
        self.faila.move(140, 150)
        self.faila.hide()

        self.p = QLabel('Clave:', self)
        self.p.move(10, 170)

        self.failp = QLabel('Clave muy Debil', self)
        self.failp.move(140, 190)
        self.failp.hide()

        self.f = QLabel('Foto:', self)
        self.f.move(10, 210)

        self.Name = QLineEdit(self)
        self.Name.setGeometry(140, 10, 200, 20)

        self.User = QLineEdit(self)
        self.User.setGeometry(140, 50, 200, 20)

        self.Mail = QLineEdit(self)
        self.Mail.setGeometry(140, 90, 200, 20)

        self.Age = QLineEdit(self)
        self.Age.setGeometry(140, 130, 200, 20)

        self.Pass = QLineEdit(self)
        self.Pass.setGeometry(140, 170, 200, 20)

        self.buscarfoto = QPushButton('Buscar Foto', self)
        self.buscarfoto.setGeometry(10, 250, 100, 30)

        self.guardar = QPushButton('Guardar', self)
        self.guardar.setGeometry(30, 300, 60, 30)

        self.failc = QLabel('Llenar Campos Vacios', self)
        self.failc.move(10, 350)
        self.failc.hide()

        self.connect(self.buscarfoto, SIGNAL('clicked()'),
                     lambda: self.buscar())
        self.connect(
            self.guardar, SIGNAL('clicked()'), lambda: self.nuevo(
                self.Name, self.User, self.Mail, self.Age, self.Pass))
        #sys.exit(self.editar.exec_())

    def ponfoto(self, a):
        self.imaje.hide()
        #self.imaje.setPixmap(QPixmap(a))

    def buscar(self):
        e = explorador()
        e.exec_()

    def nuevo(self, name, user, mail, age, passw):
        n = name.text()
        u = user.text()
        m = mail.text()
        a = age.text()
        p = passw.text()

        if (n != '' and u != '' and m != '' and a != ''
                and p != ''):  #revisa que todos los campos esten llenos
            login = open('login.txt', 'r')
            self.failc.hide()

            for i in login:
                if str(u) in i:  # revisa si ya existe este nombre de usuario
                    self.failu.show()

                else:
                    self.failu.hide()

                    try:  # revisa si se ingresa un numero
                        int(a)
                        self.faila.hide()
                        usuarios = open('usuarios.txt', 'a')
                        usuarios.write(n + ',' + u + ',' + m + ',' + a + ',' +
                                       p + '\n')
                        usuarios.close()

                    except ValueError:
                        self.faila.show()

            login.close()

        else:
            self.failc.show()
Beispiel #15
0
class RunWidget(QWidget):

    def __init__(self):
        QWidget.__init__(self)
        vbox = QVBoxLayout(self)
        vbox.setSpacing(0)
        vbox.setContentsMargins(0, 0, 0, 0)
        self.output = OutputWidget(self)
        hbox = QHBoxLayout()
        self.input = QLineEdit()
        self.lblInput = QLabel(self.tr("Input:"))
        vbox.addWidget(self.output)
        hbox.addWidget(self.lblInput)
        hbox.addWidget(self.input)
        vbox.addLayout(hbox)

        #process
        self._proc = QProcess(self)
        self.connect(self._proc, SIGNAL("readyReadStandardOutput()"),
            self.output._refresh_output)
        self.connect(self._proc, SIGNAL("readyReadStandardError()"),
            self.output._refresh_error)
        self.connect(self._proc, SIGNAL("finished(int, QProcess::ExitStatus)"),
            self.finish_execution)
        self.connect(self._proc, SIGNAL("error(QProcess::ProcessError)"),
            self.process_error)
        self.connect(self.input, SIGNAL("returnPressed()"), self.insert_input)

    def process_error(self, error):
        self.lblInput.hide()
        self.input.hide()
        self._proc.kill()
        format = QTextCharFormat()
        format.setAnchor(True)
        format.setForeground(Qt.red)
        if error == 0:
            self.output.textCursor().insertText(self.tr('Failed to start'),
                format)
        else:
            self.output.textCursor().insertText(
                self.tr('Error during execution, QProcess error: %d' % error),
                format)

    def finish_execution(self, exitCode, exitStatus):
        self.lblInput.hide()
        self.input.hide()
        format = QTextCharFormat()
        format.setAnchor(True)
        self.output.textCursor().insertText('\n\n')
        if exitStatus == QProcess.NormalExit:
            format.setForeground(Qt.green)
            self.output.textCursor().insertText(
                self.tr("Execution Successful!"), format)
        else:
            format.setForeground(Qt.red)
            self.output.textCursor().insertText(
                self.tr("Execution Interrupted"), format)

    def insert_input(self):
        text = self.input.text() + '\n'
        self._proc.writeData(text)
        self.input.setText("")

    def start_process(self, fileName, pythonPath=False, programParams=''):
        self.lblInput.show()
        self.input.show()
        self.output.setCurrentCharFormat(self.output.plain_format)
        self.output.setPlainText('Running: %s (%s)\n\n' % (fileName,
            unicode(time.ctime())))
        self.output.moveCursor(QTextCursor.Down)
        self.output.moveCursor(QTextCursor.Down)
        self.output.moveCursor(QTextCursor.Down)

        #runner.run_code_from_file(fileName)
        if not pythonPath:
            pythonPath = settings.PYTHON_PATH
        #change the working directory to the fileName dir
        file_directory = file_manager.get_folder(fileName)
        self._proc.setWorkingDirectory(file_directory)
        #force python to unbuffer stdin and stdout
        options = ['-u'] + settings.EXECUTION_OPTIONS.split()
        self._proc.start(pythonPath, options + [fileName] + \
            [p.strip() for p in programParams.split(',') if p])

    def kill_process(self):
        self._proc.kill()
Beispiel #16
0
class ADBaseWidget(DirectoryWidget):
    def __init__(self, config, specific_config, mainwindow, parent=None):
        DirectoryWidget.__init__(self, config, specific_config, mainwindow, parent=None)
        self.qhostname_object = QHostnameObject.getInstance()
        self.buildInterface(config)
        self.updateView()
        self._poll()

    def register_qobjects(self):
        self.qhostname_object.registerCallbacks(
            self.acceptHostnameChange,
            self.handleHostnameChange,
            attach=self
            )

    def _poll(self):
        self.ad_status.fetch_data(self.mainwindow.client)
        timer = QTimer()
        timer.setSingleShot(True)
        timer.setInterval(20000) # ms
        timer.start()
        self.connect(timer, SIGNAL('timeout()'), self._poll)
        self.connect(self, SIGNAL('destroyed()'), timer.stop)

    def unregister_qobjects(self):
        self.qhostname_object.forget(self)

    def updateView(self, config=None):
        if config is None:
            config = self.specific_config
        self.setText(self.controller_ip, config.controller_ip)
        self.setDefaultText(self.user, config.user)
        self.setDefaultText(self.password, config.password)
        self.setDefaultText(self.workgroup, config.workgroup)
        self.setDefaultText(self.domain, config.domain)
        self.setDefaultText(self.dns_domain, config.dns_domain)
        self.setText(self.wins_ip, config.wins_ip)
        self.displayHostname()

    def acceptHostnameChange(self):
        button = QMessageBox.warning(
            self,
            tr("Hostname change"),
            tr("Warning: this hostname change will cause the appliance to register again on Active Directory."),
            QMessageBox.Cancel | QMessageBox.Ok

        )
        if button == QMessageBox.Ok:
            self.signalModified()
            return True

        return False

    def handleHostnameChange(self):
        self.displayHostname()

    def displayHostname(self):
        self.netbios_name.setText(u"<b>%s</b>" % unicode(self.qhostname_object.hostnamecfg.hostname))

    def buildInterface(self, config):

        fqdn_tooltip = tr("IP address, FQDN or Hostname")

        self.controller_ip = QLineEdit()
        self.texts.add(self.controller_ip)
        self.connect(self.controller_ip, SIGNAL('textChanged(QString)'), self.setControllerIp)
        self.form.addRow(tr('Authentication server'), self.controller_ip)
        self.controller_ip.setToolTip(help_ps_tooltip)
        self.connect(self.controller_ip, SIGNAL('returnPressed()'), self.signalModified)

        self.ps_message_area = MessageArea()
        self.empty_ps_label = QLabel()
        self.form.addRow(self.empty_ps_label, self.ps_message_area)
        self.empty_ps_label.hide()
        self.ps_message_area.hide()
        self.ps_message_area.setMessage(help_ps_title, help_ps_message_area)

        self.wins_ip = IpOrHostnameOrFqdnEdit(accept_empty=True)
        self.texts.add(self.wins_ip)
        self.connect(self.wins_ip, SIGNAL('textChanged(QString)'), self.setWinsIp)
        self.form.addRow(tr('WINS server (optional)'), self.wins_ip)
        self.wins_ip.setToolTip(
            "%s\n%s" % (
                fqdn_tooltip, tr("This field is useful if the AD and EdenWall appliances don't share the same subnet")
            )
        )
        self.connect(self.wins_ip, SIGNAL('returnPressed()'), self.signalModified)

        for args in (
            ('domain', tr('Active Directory Domain'), self.setDomain),
            ('dns_domain', tr('Active Directory DNS Domain (if different from the AD domain)'), self.setDNSDomain),
            ('workgroup', tr('Workgroup (optional)'), self.setWorkgroup)
        ):
            setattr(self, args[0], self.addTextInput(*args[1:]))
            #flagWriteAccess(text_input)


        self.netbios_name = QLabel()
        self.form.addRow(tr("Netbios name"), self.netbios_name)

        for args in (
            ('user', tr('Name used to join the domain'), self.setUser),
            ('password', tr('Password used to join the domain'), self.setPassword, False)
        ):
            setattr(self, args[0], self.addTextInput(*args[1:]))
            #flagWriteAccess(text_input)

        #flagWriteAccess(password_server)
        self.connect(self.controller_ip, SIGNAL('textEdited(QString)'), self.helpPS)
        self.connect(self.controller_ip, SIGNAL('editingFinished()'), self.noHelpPS)

        self.ad_status = ADStatus()
        self.form.addRow('', self.ad_status)

    def helpPS(self, text):
        self.ps_message_area.show()

    def noHelpPS(self):
        self.controller_ip.setText(
            unicode(
                self.controller_ip.text()
                ).strip()
            )
        self.ps_message_area.hide()

    def setControllerIp(self, server):
        self.specific_config.controller_ip = unicode(server).strip()
        self.signalModified()

    def setWinsIp(self, server):
        self.specific_config.wins_ip = unicode(server)
        self.signalModified()

    def setDomain(self, domain):
        self.specific_config.domain = domain

    def setDNSDomain(self, domain):
        self.specific_config.dns_domain = domain

    def setUser(self, user):
        self.specific_config.user = user

    def setPassword(self, password):
        self.specific_config.password = password

    def setWorkgroup(self, workgroup):
        self.specific_config.workgroup = workgroup

    def signalModified(self):
        self.config.org = self.specific_config
        DirectoryWidget.signalModified(self)
Beispiel #17
0
class Search(QWidget, plugin.MainWindowPlugin):
    def __init__(self, mainwindow):
        super(Search, self).__init__(mainwindow)
        self._currentView = None
        self._positions = None
        self._replace = False  # are we in replace mode?
        
        mainwindow.currentViewChanged.connect(self.viewChanged)
        mainwindow.actionCollection.edit_find_next.triggered.connect(self.findNext)
        mainwindow.actionCollection.edit_find_previous.triggered.connect(self.findPrevious)
        
        # dont inherit looks from view
        self.setFont(QApplication.font())
        self.setPalette(QApplication.palette())
        
        grid = QGridLayout()
        grid.setContentsMargins(4, 0, 4, 0)
        grid.setVerticalSpacing(0)
        self.setLayout(grid)
        
        self.searchEntry = QLineEdit(textChanged=self.slotSearchChanged)
        self.searchLabel = QLabel()
        self.caseCheck = QCheckBox(checked=True, focusPolicy=Qt.NoFocus)
        self.regexCheck = QCheckBox(focusPolicy=Qt.NoFocus)
        self.countLabel = QLabel(alignment=Qt.AlignRight | Qt.AlignVCenter)
        self.countLabel.setMinimumWidth(QApplication.fontMetrics().width("9999"))
        self.closeButton = QToolButton(autoRaise=True, focusPolicy=Qt.NoFocus)
        self.hideAction = QAction(self, triggered=self.slotHide)
        self.hideAction.setShortcut(QKeySequence(Qt.Key_Escape))
        self.hideAction.setIcon(self.style().standardIcon(QStyle.SP_DialogCloseButton))
        self.closeButton.setDefaultAction(self.hideAction)
        
        grid.addWidget(self.searchLabel, 0, 0)
        grid.addWidget(self.searchEntry, 0, 1)
        grid.addWidget(self.caseCheck, 0, 2)
        grid.addWidget(self.regexCheck, 0, 3)
        grid.addWidget(self.countLabel, 0, 4)
        grid.addWidget(self.closeButton, 0, 5)
        
        self.caseCheck.toggled.connect(self.slotSearchChanged)
        self.regexCheck.toggled.connect(self.slotSearchChanged)
        
        self.replaceEntry = QLineEdit()
        self.replaceLabel = QLabel()
        self.replaceButton = QPushButton(clicked=self.slotReplace)
        self.replaceAllButton = QPushButton(clicked=self.slotReplaceAll)
        
        grid.addWidget(self.replaceLabel, 1, 0)
        grid.addWidget(self.replaceEntry, 1, 1)
        grid.addWidget(self.replaceButton, 1, 2)
        grid.addWidget(self.replaceAllButton, 1, 3)
        
        app.settingsChanged.connect(self.readSettings)
        self.readSettings()
        app.translateUI(self)
        
    def translateUI(self):
        self.searchLabel.setText(_("Search:"))
        self.caseCheck.setText(_("&Case"))
        self.caseCheck.setToolTip(_("Case Sensitive"))
        self.regexCheck.setText(_("&Regex"))
        self.regexCheck.setToolTip(_("Regular Expression"))
        self.countLabel.setToolTip(_("The total number of matches"))
        self.hideAction.setToolTip(_("Close"))
        self.replaceLabel.setText(_("Replace:"))
        self.replaceButton.setText(_("Re&place"))
        self.replaceButton.setToolTip(_("Replaces the next occurrence of the search term."))
        self.replaceAllButton.setText(_("&All"))
        self.replaceAllButton.setToolTip(_("Replaces all occurrences of the search term in the document or selection."))
    
    def readSettings(self):
        data = textformats.formatData('editor')
        self.searchEntry.setFont(data.font)
        self.replaceEntry.setFont(data.font)
        p = data.palette()
        self.searchEntry.setPalette(p)
        self.replaceEntry.setPalette(p)
         
    def currentView(self):
        return self._currentView and self._currentView()
    
    def setCurrentView(self, view):
        self._currentView = weakref.ref(view) if view else None
        
    def showWidget(self):
        if self.isVisible():
            self.hideWidget()
        view = self.window().currentView()
        self.setCurrentView(view)
        layout = widgets.borderlayout.BorderLayout.get(view)
        layout.addWidget(self, widgets.borderlayout.BOTTOM)
        self.show()
        
    def hideWidget(self):
        view = self.currentView()
        if view:
            viewhighlighter.highlighter(view).clear("search")
            self.hide()
            layout = widgets.borderlayout.BorderLayout.get(view)
            layout.removeWidget(self)
    
    def viewChanged(self, new):
        self.setParent(None)
        self.hideWidget()
        self.setCurrentView(new)
        self.updatePositions()
        
    def slotHide(self):
        view = self.currentView()
        if view:
            self.hideWidget()
            view.setFocus()
        
    def find(self):
        # hide replace stuff
        self.replaceLabel.hide()
        self.replaceEntry.hide()
        self.replaceButton.hide()
        self.replaceAllButton.hide()
        self._replace = False # we are not in replace mode
        visible = self.isVisible()
        if not visible:
            with qutil.signalsBlocked(self.searchEntry):
                self.searchEntry.clear()
        self.showWidget()
        if not visible and self.currentView():
            # pick current word
            cursor = self.currentView().textCursor()
            cursor.movePosition(QTextCursor.StartOfWord)
            cursor.movePosition(QTextCursor.EndOfWord, QTextCursor.KeepAnchor)
            word = cursor.selection().toPlainText()
            if not re.search(r'\w', word):
                word = ""
            self.searchEntry.setText(word)
            self.searchEntry.selectAll()
        else:
            self.slotSearchChanged()
        self.searchEntry.setFocus()
        
    def replace(self):
        # show replace stuff
        self.replaceLabel.show()
        self.replaceEntry.show()
        self.replaceButton.show()
        self.replaceAllButton.show()
        focus = self.replaceEntry if self.isVisible() and self.searchEntry.text() else self.searchEntry
        self._replace = True # we are in replace mode
        self.showWidget()
        self.slotSearchChanged()
        focus.setFocus()
        
    def slotSearchChanged(self):
        self.updatePositions()
        viewhighlighter.highlighter(self.currentView()).highlight("search", self._positions, 1)

    def updatePositions(self):
        search = self.searchEntry.text()
        view = self.currentView()
        document = view.document()
        self._positions = []
        if search:
            text = document.toPlainText()
            flags = re.MULTILINE | re.DOTALL
            if not self.caseCheck.isChecked():
                flags |= re.IGNORECASE
            if not self.regexCheck.isChecked():
                search = re.escape(search)
            try:
                matches = re.finditer(search, text, flags)
            except re.error:
                pass
            else:
                for m in matches:
                    c = QTextCursor(document)
                    c.setPosition(m.end())
                    c.setPosition(m.start(), QTextCursor.KeepAnchor)
                    self._positions.append(c)
        self.countLabel.setText(unicode(len(self._positions)))
        
    def findNext(self):
        view = self.currentView()
        if view and self._positions:
            positions = [c.position() for c in self._positions]
            index = bisect.bisect_right(positions, view.textCursor().position())
            if index < len(positions):
                view.setTextCursor(self._positions[index])
            else:
                view.setTextCursor(self._positions[0])
            view.ensureCursorVisible()

    def findPrevious(self):
        view = self.currentView()
        positions = [c.position() for c in self._positions]
        if view and positions:
            index = bisect.bisect_left(positions, view.textCursor().position()) - 1
            view.setTextCursor(self._positions[index])
            view.ensureCursorVisible()

    def keyPressEvent(self, ev):
        if ev.key() == Qt.Key_Tab:
            # prevent Tab from reaching the View widget
            self.window().focusNextChild()
            return
        # if in search mode, Up and Down jump between search results
        if not self._replace and self._positions and self.searchEntry.text() and not ev.modifiers():
            if ev.key() == Qt.Key_Up:
                self.findPrevious()
                return
            elif ev.key() ==  Qt.Key_Down:
                self.findNext()
                return
        # use enter or return for search next
        if ev.key() in (Qt.Key_Enter, Qt.Key_Return):
            self.findNext()
            return
        super(Search, self).keyPressEvent(ev)

    def doReplace(self, cursor):
        text = cursor.selection().toPlainText()
        search = self.searchEntry.text()
        replace = self.replaceEntry.text()
        ok = text == self.searchEntry.text()
        if self.regexCheck.isChecked():
            m = re.match(search, text)
            ok = False
            if m:
                try:
                    replace = m.expand(replace)
                    ok = True
                except re.error:
                    pass
        if ok:
            pos = cursor.position()
            cursor.insertText(replace)
            cursor.setPosition(pos, QTextCursor.KeepAnchor)
        return ok
        
    def slotReplace(self):
        view = self.currentView()
        if view and self._positions:
            positions = [c.position() for c in self._positions]
            index = bisect.bisect_left(positions, view.textCursor().position())
            if index >= len(positions):
                index = 0
            if self.doReplace(self._positions[index]):
                viewhighlighter.highlighter(view).highlight("search", self._positions, 1)
                if index < len(positions) - 1:
                    view.setTextCursor(self._positions[index+1])
                else:
                    view.setTextCursor(self._positions[0])
                view.ensureCursorVisible()
    
    def slotReplaceAll(self):
        view = self.currentView()
        if view:
            replaced = False
            cursors = self._positions
            if view.textCursor().hasSelection():
                cursors = [cursor for cursor in cursors if cursortools.contains(view.textCursor(), cursor)]
            view.textCursor().beginEditBlock()
            for cursor in cursors:
                if self.doReplace(cursor):
                    replaced = True
            view.textCursor().endEditBlock()
            if replaced:
                viewhighlighter.highlighter(view).highlight("search", self._positions, 1)
Beispiel #18
0
class LCD20x4(PluginBase):
    MAX_LINE = 4
    MAX_POSITION = 20
    qtcb_pressed = pyqtSignal(int)
    qtcb_released = pyqtSignal(int)
    
    def __init__(self, ipcon, uid, version):
        PluginBase.__init__(self, ipcon, uid, 'LCD 20x4 Bricklet', version)
        
        self.version = version
        self.lcd = BrickletLCD20x4(uid, ipcon)

        self.hardware_version = (1, 0, 0)

        self.qtcb_pressed.connect(self.cb_pressed)
        self.lcd.register_callback(self.lcd.CALLBACK_BUTTON_PRESSED,
                                   self.qtcb_pressed.emit)
        self.qtcb_released.connect(self.cb_released)
        self.lcd.register_callback(self.lcd.CALLBACK_BUTTON_RELEASED,
                                   self.qtcb_released.emit)
        
        self.line_label = QLabel('Line: ')
        self.line_combo = QComboBox()
        for i  in range(LCD20x4.MAX_LINE):
            self.line_combo.addItem(str(i))
        
        self.pos_label = QLabel('Position: ')
        self.pos_combo = QComboBox()
        for i  in range(LCD20x4.MAX_POSITION):
            self.pos_combo.addItem(str(i))
        
        self.pos_layout = QHBoxLayout()
        self.pos_layout.addWidget(self.pos_label)
        self.pos_layout.addWidget(self.pos_combo) 
        self.pos_layout.addStretch()
        
        self.line_layout = QHBoxLayout()
        self.line_layout.addWidget(self.line_label)
        self.line_layout.addWidget(self.line_combo)
        self.line_layout.addStretch()
        
        self.text_label = QLabel('Text: ')
        self.text_edit = QLineEdit();
        self.text_edit.setMaxLength(LCD20x4.MAX_POSITION)
        self.text_button = QPushButton('Send Text')
        self.text_layout = QHBoxLayout()
        self.text_layout.addWidget(self.text_label)
        self.text_layout.addWidget(self.text_edit)
        self.text_layout.addWidget(self.text_button)
        
        self.clear_button = QPushButton("Clear Display")
        
        self.bl_button = QPushButton()
        self.cursor_button = QPushButton()
        self.blink_button = QPushButton()
            
        self.onofflayout = QHBoxLayout()
        self.onofflayout.addWidget(self.bl_button)
        self.onofflayout.addWidget(self.cursor_button)
        self.onofflayout.addWidget(self.blink_button)
            
        self.b0_label = QLabel('Button 0: Released,')
        self.b1_label = QLabel('Button 1: Released,')
        self.b2_label = QLabel('Button 2: Released,')
        self.b3_label = QLabel('Button 3: Released')
        
        self.buttonlayout = QHBoxLayout()
        self.buttonlayout.addWidget(self.b0_label)
        self.buttonlayout.addWidget(self.b1_label)
        self.buttonlayout.addWidget(self.b2_label)
        self.buttonlayout.addWidget(self.b3_label)
        
        self.cursor_button.pressed.connect(self.cursor_pressed)
        self.blink_button.pressed.connect(self.blink_pressed)
        self.clear_button.pressed.connect(self.clear_pressed)
        self.bl_button.pressed.connect(self.bl_pressed)
        self.text_button.pressed.connect(self.text_pressed)
        
        if self.version >= (2, 0, 1):
            line = QFrame()
            line.setFrameShape(QFrame.HLine)
            line.setFrameShadow(QFrame.Sunken)
            
            gridlayout = QGridLayout()
            gridlayout.setHorizontalSpacing(2)
            gridlayout.setVerticalSpacing(2)
                    
            self.character_boxes_bool = []
            self.character_boxes = []
            for i in range(5):
                self.character_boxes.append([])
                self.character_boxes_bool.append([])
                for j in range(8):
                    b = QToolButton()
                    b.setAutoFillBackground(True)
                    b.setStyleSheet("background-color: rgb(255, 255, 255)")
                    b.setMaximumSize(25, 25)
                    b.setMinimumSize(25, 25)
                    
                    def get_lambda(i, j):
                        return lambda: self.char_button_pressed(i, j)
                    b.pressed.connect(get_lambda(i, j))
                    
                    self.character_boxes[i].append(b)
                    self.character_boxes_bool[i].append(True)
                    gridlayout.addWidget(b, j, i)
                    
            self.char_index_label = QLabel('Index:')
            self.char_index_combo = QComboBox()
            self.char_index_combo.currentIndexChanged.connect(self.char_index_changed)
            for i in range(8):
                self.char_index_combo.addItem(str(i))
                
            self.char_index_layout = QHBoxLayout()
            self.char_index_layout.addStretch()
            self.char_index_layout.addWidget(self.char_index_label)
            self.char_index_layout.addWidget(self.char_index_combo)
            self.char_index_layout.addStretch()
            
            self.char_index_save = QPushButton('Save Character')
            self.char_index_save.pressed.connect(self.char_index_save_pressed)
            self.char_show = QPushButton('Show all Custom Characters on LCD')
            self.char_show.pressed.connect(self.show_pressed)
            self.char_save_layout = QVBoxLayout()
            self.char_save_layout.addStretch()
            self.char_save_layout.addLayout(self.char_index_layout)
            self.char_save_layout.addWidget(self.char_index_save)
            self.char_save_layout.addWidget(self.char_show)
            self.char_save_layout.addStretch()
            
            
            grid_stretch_layout = QHBoxLayout()
            grid_stretch_layout.addWidget(QLabel('Custom Character: '))
            grid_stretch_layout.addLayout(gridlayout)
            grid_stretch_layout.addLayout(self.char_save_layout)
            grid_stretch_layout.addStretch()
            
            self.char_main_layout = QHBoxLayout()
            self.char_main_layout.addStretch()
            self.char_main_layout.addLayout(grid_stretch_layout)
            self.char_main_layout.addStretch()
            
            self.char_main_layoutv = QVBoxLayout()
            self.char_main_layoutv.addLayout(self.char_main_layout)
            self.char_main_layoutv.addWidget(QLabel('Use "\\0, \\1, ..., \\7" in text field to show custom characters.'))
        
        layout = QVBoxLayout(self)
        layout.addLayout(self.line_layout)
        layout.addLayout(self.pos_layout)
        layout.addLayout(self.text_layout)
        layout.addWidget(self.clear_button)
        layout.addLayout(self.onofflayout)
        layout.addLayout(self.buttonlayout)
        
        if self.version >= (2, 0, 1):
            layout.addWidget(line)
            layout.addLayout(self.char_main_layoutv)
        layout.addStretch(1)

    def char_button_pressed(self, i, j):
        if self.character_boxes_bool[i][j]:
            self.character_boxes_bool[i][j] = False
            self.character_boxes[i][j].setStyleSheet("background-color: rgb(0, 0, 255)")
        else:
            self.character_boxes_bool[i][j] = True
            self.character_boxes[i][j].setStyleSheet("background-color: rgb(255, 255, 255)")

    def is_backlight_on_async(self, on):
        if on:
            self.bl_button.setText('Backlight Off')
        else:
            self.bl_button.setText('Backlight On')
            
    def get_config_async(self, config):
        cursor, blink = config
        if cursor:
            self.cursor_button.setText('Cursor Off')
        else:
            self.cursor_button.setText('Cursor On')
            
        if blink:
            self.blink_button.setText('Blink Off')
        else:
            self.blink_button.setText('Blink On')

    def start(self):
        async_call(self.lcd.is_backlight_on, None, self.is_backlight_on_async, self.increase_error_count)
        async_call(self.lcd.get_config, None, self.get_config_async, self.increase_error_count)
        
    def stop(self):
        pass

    def get_url_part(self):
        return 'lcd_20x4_v{0}{1}'.format(self.hardware_version[0], self.hardware_version[1])
    
    def is_hardware_version_relevant(self, hardware_version):
        # FIXME: hack to avoid passing the hardware_version to all plugins
        self.hardware_version = hardware_version
        if hardware_version <= (1, 1, 0):
            self.b3_label.hide()
        return True

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickletLCD20x4.DEVICE_IDENTIFIER
    
    def cb_pressed(self, button):
        if button == 0:
            self.b0_label.setText('Button 0: Pressed,')
        elif button == 1:
            self.b1_label.setText('Button 1: Pressed,')
        elif button == 2:
            self.b2_label.setText('Button 2: Pressed,')
        elif button == 3:
            self.b3_label.setText('Button 3: Pressed')
        
    def cb_released(self, button):
        if button == 0:
            self.b0_label.setText('Button 0: Released,')
        elif button == 1:
            self.b1_label.setText('Button 1: Released,')
        elif button == 2:
            self.b2_label.setText('Button 2: Released,')
        elif button == 3:
            self.b3_label.setText('Button 3: Released')
    
    def bl_pressed(self):
        try:
            if self.bl_button.text() == 'Backlight On':
                self.lcd.backlight_on()
                self.bl_button.setText('Backlight Off')
            else:
                self.lcd.backlight_off()
                self.bl_button.setText('Backlight On')
        except ip_connection.Error:
            return
    
    def get_config(self):
        cursor = self.cursor_button.text() == 'Cursor Off'
        blink = self.blink_button.text() == 'Blink Off'
        return (cursor, blink)
    
    def cursor_pressed(self):
        cursor, blink = self.get_config()
        try:
            self.lcd.set_config(not cursor, blink)
        except ip_connection.Error:
            return
        
        if cursor:
            self.cursor_button.setText('Cursor On')
        else:
            self.cursor_button.setText('Cursor Off')
    
    def blink_pressed(self):
        cursor, blink = self.get_config()
        try:
            self.lcd.set_config(cursor, not blink)
        except ip_connection.Error:
            return
        
        if blink:
            self.blink_button.setText('Blink On')
        else:
            self.blink_button.setText('Blink Off')
    
    def clear_pressed(self):
        try:
            self.lcd.clear_display()
        except ip_connection.Error:
            return
    
    def text_pressed(self):
        line = int(self.line_combo.currentText())
        position = int(self.pos_combo.currentText())
        text = unicode(self.text_edit.text().toUtf8(), 'utf-8')
        if self.version >= (2, 0, 1):
            for i in range(8):
                text = text.replace('\\' + str(i), chr(i+8))
        try:
            self.lcd.write_line(line, position, unicode_to_ks0066u(text)) 
        except ip_connection.Error:
            return
        
    def char_index_save_pressed(self):
        char = [0]*8
        for i in range(len(self.character_boxes)):
            for j in range(len(self.character_boxes[i])):
                if self.character_boxes_bool[i][j]:
                    char[j] |= 1 << (4 - i)
                    
        index = int(self.char_index_combo.currentText())
        self.lcd.set_custom_character(index, char)
        
    def show_pressed(self):
        self.lcd.clear_display()
        line1 = '0:{0} 1:{1} 2:{2} 3:{3}'.format(chr(8), chr(9), chr(10), chr(11))
        line2 = '4:{0} 5:{1} 6:{2} 7:{3}'.format(chr(12), chr(13), chr(14), chr(15))
        self.lcd.write_line(0, 0, line1)
        self.lcd.write_line(1, 0, line2)
    
    def custom_character_async(self, characters):
        for i in range(len(self.character_boxes)):
            for j in range(len(self.character_boxes[i])):
                if characters[j] & (1 << i):
                    self.character_boxes_bool[4-i][j] = True
                    self.character_boxes[4-i][j].setStyleSheet("background-color: rgb(255, 255, 255)")
                else:
                    self.character_boxes_bool[4-i][j] = False
                    self.character_boxes[4-i][j].setStyleSheet("background-color: rgb(0, 0, 255)")
    
    def char_index_changed(self, index):
        async_call(self.lcd.get_custom_character, (index,), self.custom_character_async, self.increase_error_count)
Beispiel #19
0
 def create_rows(self, layout):
     u"""Build the rows of the dialog box"""
     play_button_group = QButtonGroup(self)
     old_play_button_group = QButtonGroup(self)
     for num, entry in enumerate(self.entries_list, 3):
         tt_text = self.build_text_help_label(entry)
         ico_label = QLabel('', self)
         ico_label.setToolTip(tt_text)
         if entry.icon:
             ico_label.setPixmap(QPixmap.fromImage(entry.icon))
         layout.addWidget(ico_label, num, 0)
         tt_label = QLabel(entry.display_word, self)
         tt_label.setToolTip(tt_text)
         layout.addWidget(tt_label, num, 1)
         if self.hide_text:
             tt_label.hide()
         # Play button.
         t_play_button = QPushButton(self)
         play_button_group.addButton(t_play_button, num - 3)
         t_play_button.setToolTip(self.play_help)
         t_play_button.setIcon(QIcon(os.path.join(icons_dir, 'play.png')))
         layout.addWidget(t_play_button, num, self.play_column)
         if self.note[entry.audio_field_name]:
             t_play_old_button = QPushButton(self)
             old_play_button_group.addButton(t_play_old_button, num - 3)
             t_play_old_button.setIcon(
                 QIcon(os.path.join(icons_dir, 'play.png')))
             if not self.hide_text:
                 t_play_old_button.setToolTip(
                     self.note[entry.audio_field_name])
             else:
                 t_play_old_button.setToolTip(self.play_old_help_short)
             layout.addWidget(t_play_old_button, num, self.play_old_column)
         else:
             dummy_label = QLabel('', self)
             dummy_label.setToolTip(self.play_old_empty_line_help)
             layout.addWidget(dummy_label, num, self.play_old_column)
         # The group where we later look what to do:
         t_button_group = QButtonGroup(self)
         t_button_group.setExclusive(True)
         # Now the four buttons
         t_add_button = QPushButton(self)
         t_add_button.setCheckable(True)
         t_add_button.setFlat(True)
         t_add_button.setToolTip(self.add_help_text_short)
         t_add_button.setIcon(QIcon(os.path.join(icons_dir, 'add.png')))
         layout.addWidget(t_add_button, num, self.add_column)
         t_button_group.addButton(t_add_button, Action.Add)
         t_keep_button = QPushButton(self)
         t_keep_button.setCheckable(True)
         t_keep_button.setFlat(True)
         t_keep_button.setToolTip(self.keep_help_text_short)
         t_keep_button.setIcon(QIcon(os.path.join(icons_dir, 'keep.png')))
         layout.addWidget(t_keep_button, num, self.keep_column)
         t_button_group.addButton(t_keep_button, Action.Keep)
         t_delete_button = QPushButton(self)
         t_delete_button.setCheckable(True)
         t_delete_button.setFlat(True)
         t_delete_button.setToolTip(self.delete_help_text_short)
         t_delete_button.setIcon(
             QIcon(os.path.join(icons_dir, 'delete.png')))
         layout.addWidget(t_delete_button, num, self.delete_column)
         t_button_group.addButton(t_delete_button,  Action.Delete)
         t_blacklist_button = QPushButton(self)
         t_blacklist_button.setCheckable(True)
         t_blacklist_button.setFlat(True)
         t_blacklist_button.setToolTip(self.blacklist_help_text_short)
         t_blacklist_button.setIcon(
             QIcon(os.path.join(icons_dir, 'blacklist.png')))
         if entry.entry_hash:
             layout.addWidget(
                 t_blacklist_button, num, self.blacklist_column)
         else:
             t_blacklist_button.hide()
             dummy_label_bl = QLabel('', self)
             dummy_label_bl.setToolTip(self.blacklist_empty_line_help)
             layout.addWidget(dummy_label_bl, num, self.blacklist_column)
         t_button_group.button(entry.action).setChecked(True)
         # New: check a button based on how good the downloader is.
         t_button_group.addButton(t_blacklist_button, Action.Blacklist)
         self.buttons_groups.append(t_button_group)
     play_button_group.buttonClicked.connect(
         lambda button: play(
             self.entries_list[play_button_group.id(button)].file_path))
     # N.B.: anki.sound.play() plays files from anywhere, not just
     # from the colection.media folder. We should be good,
     # here. (This behaviour may be a security risk, idk.)
     old_play_button_group.buttonClicked.connect(
         lambda button: playFromText(
             self.note[
                 self.entries_list[
                     old_play_button_group.id(button)].audio_field_name]))
class GenericParameterWidget(QWidget, object):
    """Widget class for generic parameter."""
    def __init__(self, parameter, parent=None):
        """Constructor

        .. versionadded:: 2.2

        :param parameter: A Generic object.
        :type parameter: GenericParameter

        """
        QWidget.__init__(self, parent)
        self._parameter = parameter

        # Create elements
        # Label (name)
        self._label = QLabel(self._parameter.name)

        # Label (help text)
        self._help_text_label = QLabel(self._parameter.help_text)
        self._help_text_label.setWordWrap(True)

        # Label (description)
        self._description_label = QLabel(self._parameter.description)
        self._description_label.setWordWrap(True)
        self._description_label.hide()

        # Flag for show-status of description
        self._hide_description = True

        # Tool button for showing and hide detail description
        self._switch_button = QToolButton()
        self._switch_button.setArrowType(4)  # 2=down arrow, 4=right arrow
        # noinspection PyUnresolvedReferences
        self._switch_button.clicked.connect(self.show_hide_description)
        self._switch_button.setToolTip('Click for detail description')
        self._switch_button_stylesheet = 'border: none;'
        self._switch_button.setStyleSheet(self._switch_button_stylesheet)
        # Layouts
        self._main_layout = QVBoxLayout()
        self._input_layout = QHBoxLayout()
        self._help_layout = QGridLayout()
        # _inner_input_layout must be filled with widget in the child class
        self._inner_input_layout = QHBoxLayout()
        self._inner_help_layout = QVBoxLayout()

        # spacing
        self._main_layout.setSpacing(0)
        self._input_layout.setSpacing(0)
        self._help_layout.setSpacing(0)
        self._inner_input_layout.setSpacing(7)
        self._inner_help_layout.setSpacing(0)

        # Put elements into layouts
        self._input_layout.addWidget(self._label)
        self._input_layout.addLayout(self._inner_input_layout)
        # self._input_layout.addSpacing(100)

        self._help_layout.addWidget(self._switch_button, 0, 0)
        self._help_layout.addWidget(self._help_text_label, 0, 1)
        self._help_layout.addWidget(self._description_label, 1, 1)

        self._main_layout.addLayout(self._input_layout)
        self._main_layout.addLayout(self._help_layout)

        self.setLayout(self._main_layout)

        self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.MinimumExpanding)

    def get_parameter(self):
        """Interface for returning parameter object.

        This must be implemented in child class.

        :raises: NotImplementedError

        """
        raise NotImplementedError('Must be implemented in child class')

    def show_hide_description(self):
        """Show and hide long description."""
        if self._hide_description:
            self._hide_description = False
            self._description_label.show()
            self._switch_button.setArrowType(2)
            self._switch_button.setToolTip('Click for hide detail description')
        else:
            self._hide_description = True
            self._description_label.hide()
            self._switch_button.setArrowType(4)
            self._switch_button.setToolTip('Click for detail description')
class GenericParameterWidget(QWidget, object):
    """Widget class for generic parameter."""
    def __init__(self, parameter, parent=None):
        """Constructor

        .. versionadded:: 2.2

        :param parameter: A Generic object.
        :type parameter: GenericParameter

        """
        QWidget.__init__(self, parent)
        self._parameter = parameter

        # Create elements
        # Label (name)
        self.label = QLabel(self._parameter.name)

        # Label (description text)
        # Hacky fix for #1830 - checking the base type
        if isinstance(self._parameter.description, basestring):
            self.description_text_label = QLabel(self._parameter.description)
        else:
            self.description_text_label = QLabel()

        self.description_text_label.setWordWrap(True)

        # Label (help)
        self.help_label = QLabel(self._parameter.help_text)
        self.help_label.setWordWrap(True)
        self.help_label.hide()

        # Flag for show-status of help
        self._hide_help = True

        # Tool button for showing and hide detail help
        self.switch_button = QToolButton()
        self.switch_button.setArrowType(4)  # 2=down arrow, 4=right arrow
        # noinspection PyUnresolvedReferences
        self.switch_button.clicked.connect(self.show_hide_help)
        self.switch_button.setToolTip('Click for detail help')
        self.switch_button_stylesheet = 'border: none;'
        self.switch_button.setStyleSheet(self.switch_button_stylesheet)
        # Layouts
        self.main_layout = QVBoxLayout()
        self.input_layout = QHBoxLayout()
        self.help_layout = QGridLayout()
        # _inner_input_layout must be filled with widget in the child class
        self.inner_input_layout = QHBoxLayout()
        self.inner_help_layout = QVBoxLayout()

        # spacing
        self.main_layout.setSpacing(0)
        self.main_layout.setContentsMargins(0, 0, 0, 0)
        self.input_layout.setSpacing(0)
        self.input_layout.setContentsMargins(0, 0, 0, 0)
        self.help_layout.setSpacing(0)
        self.help_layout.setContentsMargins(0, 0, 0, 0)
        self.inner_input_layout.setSpacing(7)
        self.inner_input_layout.setContentsMargins(0, 0, 0, 0)
        self.inner_help_layout.setSpacing(0)
        self.inner_help_layout.setContentsMargins(0, 0, 0, 0)

        # Put elements into layouts
        self.input_layout.addWidget(self.label)
        self.input_layout.addLayout(self.inner_input_layout)

        if self._parameter.description:
            self.help_layout.addWidget(self.description_text_label, 0, 1)
        if self._parameter.help_text:
            self.help_layout.addWidget(self.switch_button, 0, 0)
            self.help_layout.addWidget(self.help_label, 1, 1)

        self.main_layout.addLayout(self.input_layout)
        self.main_layout.addLayout(self.help_layout)

        self.setLayout(self.main_layout)

        self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.MinimumExpanding)

    def get_parameter(self):
        """Interface for returning parameter object.

        This must be implemented in child class.

        :raises: NotImplementedError

        """
        raise NotImplementedError('Must be implemented in child class')

    def show_hide_help(self):
        """Show and hide long help."""
        if self._hide_help:
            self._hide_help = False
            self.help_label.show()
            self.switch_button.setArrowType(2)
            self.switch_button.setToolTip('Click for hide detail help')
        else:
            self._hide_help = True
            self.help_label.hide()
            self.switch_button.setArrowType(4)
            self.switch_button.setToolTip('Click for detail help')
class PreprocessorModule(QWidget):
    """The base widget for the pre-processing modules."""

    change_signal = Signal()  # Emitted when the settings are changed.
    # Emitted when the module has a message to display in the main widget.
    error_signal = Signal(str)
    enabled = False  # If the module is enabled.

    def __init__(self, title, toggle_enabled, is_enabled):
        super().__init__()

        # Title bar.
        title_holder = QWidget()
        title_holder.setSizePolicy(QSizePolicy.MinimumExpanding,
                                   QSizePolicy.Fixed)
        title_holder.setStyleSheet("""
        .QWidget {
        background: qlineargradient( x1:0 y1:0, x2:0 y2:1,
        stop:0 #F8F8F8, stop:1 #C8C8C8);
        border-bottom: 1px solid #B3B3B3;
        }
        """)
        self.titleArea = QHBoxLayout()
        self.titleArea.setContentsMargins(15, 10, 15, 10)
        self.titleArea.setSpacing(0)
        title_holder.setLayout(self.titleArea)

        self.title_label = QLabel(title)
        self.title_label.setStyleSheet('font-size: 12px;')
        self.titleArea.addWidget(self.title_label)

        self.off_label = QLabel('[disabled]')
        self.off_label.setStyleSheet('color: #B0B0B0; margin-left: 5px;')
        self.titleArea.addWidget(self.off_label)
        self.off_label.hide()

        self.titleArea.addStretch()

        # Root.
        self.rootArea = QVBoxLayout()
        self.rootArea.setContentsMargins(0, 0, 0, 0)
        self.rootArea.setSpacing(0)
        self.setLayout(self.rootArea)
        self.rootArea.addWidget(title_holder)

        self.contents = QWidget()
        contentArea = QVBoxLayout()
        contentArea.setContentsMargins(15, 10, 15, 10)
        self.contents.setLayout(contentArea)
        self.rootArea.addWidget(self.contents)

        self.enabled = is_enabled
        if toggle_enabled:
            self.toggle_module_switch = QCheckBox()
            switch_icon_on_resource = _i('on_button.png')
            switch_icon_off_resource = _i('off_button.png')
            style_sheet = '''
            QCheckBox::indicator {
                width: 23px;
                height: 23px;
            }
            QCheckBox::indicator:checked {
                image: url(%s);
            }
            QCheckBox::indicator:unchecked {
                image: url(%s);
            }
            ''' % (switch_icon_on_resource, switch_icon_off_resource)
            self.toggle_module_switch.setStyleSheet(style_sheet)
            self.toggle_module_switch.setChecked(self.enabled)
            self.toggle_module_switch.stateChanged.connect(self.on_toggle)

            # Change the view according to the flag.
            if self.enabled:
                self.off_label.hide()
                self.contents.show()
                self.title_label.setStyleSheet('color: #000000;')
            else:
                self.off_label.show()
                self.contents.hide()
                self.title_label.setStyleSheet('color: #B0B0B0;')

            self.titleArea.addWidget(self.toggle_module_switch)

    def add_to_content_area(self, new_widget):
        self.contents.layout().addWidget(new_widget)

    def add_layout_to_content_area(self, new_layout):
        self.contents.layout().addLayout(new_layout)

    def notify_on_change(self):
        # Emits signals corresponding to the changes done.
        self.change_signal.emit()

    def on_toggle(self):
        # Activated when the widget is enabled/disabled.
        self.enabled = not self.enabled
        if self.enabled:
            self.off_label.hide()
            self.contents.show()
            self.title_label.setStyleSheet('color: #000000;')
        else:
            self.off_label.show()
            self.contents.hide()
            self.title_label.setStyleSheet('color: #B0B0B0;')
        self.change_signal.emit()

    def restore_data(self, data):
        # Restores the widget state from the input data.
        raise NotImplementedError

    def export_data(self):
        # Export the settings for this module instance.
        return NotImplementedError

    @staticmethod
    def get_pp_settings():
        # Returns the dict representation of this portion of a pre-processor.
        return NotImplementedError
Beispiel #23
0
class Stopat(QWidget):
    def __init__(self, images, parent=None, options = None):
        QWidget.__init__(self, parent)
        self.images = images
        self.options = options
        self.info = QFrame()
        self.mediacache = []
        self.threads = []
        self.synced = True

        LL0 = dict(lab=None, lag=None)
        self.elems = dict(
            at   =dict(up=LL0, bl=LL0, br=LL0), # up, bottom-left, bottom-right
            after=dict(s1=LL0, s2=LL0, s3=LL0), # 1st stop, 2nd stop, 3rd stop
        )
        self.bgs =dict(unregistered="bg-"+WSU+".jpg", registered="bg-noinfo2-"+WSU+".jpg",
                disconnected="bg-"+WSU+".jpg", connected="bg-noinfo2-"+WSU+".jpg")
        self.tags_l1 = ('at', 'after')
        for t in self.tags_l1:
            self.bgs[t] = BG_STYLE if self.images is None else "background-image:url(" + self.images[t] + ");"
        self.set_bg("unregistered")

        self.setContentsMargins(0, 0, 0, 0)
        self.route = self.setlabel(None, 'route', Qt.AlignCenter)
        self.tags_l2 = dict(
            at=dict(    # up, bottom-left, bottom-right
                up=dict(text=None,    lag=None, align=Qt.AlignCenter),
                bl=dict(text=TS_TEXT, lag=None, align=(Qt.AlignVCenter|Qt.AlignLeft)),
                br=dict(text=None,    lag=None, align=(Qt.AlignVCenter|Qt.AlignLeft)),
            ),
            after=dict( # 1st stop, 2nd stop, 3rd stop
                s1=dict(text=None, lag=None, align=Qt.AlignCenter),
                s2=dict(text=None, lag=0, align=Qt.AlignVCenter|Qt.AlignLeft),
                s3=dict(text=None, lag=0, align=Qt.AlignVCenter|Qt.AlignLeft),
            )
        )
        for t1 in self.tags_l1:
            for t2 in self.tags_l2[t1]:
                v = self.tags_l2[t1][t2]
                self.elems[t1][t2] = self.setlabel(v['text'], t2, v['align'], v['lag'])

        for t1 in self.elems:   # hide them all
            for t2 in self.elems[t1]:
                for t3 in self.elems[t1][t2]:
                    v = self.elems[t1][t2][t3]
                    if v is not None:
                        v.hide()

        self.sw_label = QLabel(PROGNAME+"-"+SW_VERSION, self.info)
        self.sw_label.setStyleSheet(stop_css['version']['style'])
        self.sw_label.setGeometry(stop_css['version']['geom']['x'], stop_css['version']['geom']['y'], stop_css['version']['geom']['w'], stop_css['version']['geom']['h'])
        self.sw_timer = QTimer()
        self.sw_timer.timeout.connect(self.rm_sw)
        self.sw_timer.start(5000)

        self.box = QHBoxLayout()
        self.box.setSpacing(0)
        self.box.setContentsMargins(0, 0, 0, 0)
        self.box.addWidget(self.info)
        self.setLayout(self.box)

        # audio only (without any video out, without window, i.e. some background audio)
        self.player = vlc.MediaPlayer(vlc.Instance()) if self.options is None else vlc.MediaPlayer(vlc.Instance(self.options))

    def rm_sw(self):
        self.sw_label.hide()
        self.sw_timer.stop()

    def look_in_cache(self, filename, timestamp):
        for k in self.mediacache:
            if (k['fn'] == filename) and (k['ts'] == timestamp):
                return k['path']
        return None

    def getter(self, url, fpath):
        try:
            re = urllib.request.urlretrieve(url, fpath)
        except urllib.error.ContentTooShortError as err:
            print_n_log("Got truncated data: {} ({})".forma(err.msg, url))
        except urllib.error.HTTPError as err:
            print_n_log("Got HTTP error: {} {} ({})".format(err.code, err.reason, url))
        except urllib.error.URLError as err:
            print_n_log("Got URL error: {} ({})".format(err.reason, url))

    def squeeze_threads_out(self):
        for t in self.threads:
            if not t['thr'].isAlive():
                t['thr'].handled = True
        self.threads = [t for t in self.threads if not t['thr'].handled]   # remove finished threads

    def in_progress(self, url):
        for t in self.threads:
            if t['thr'].isAlive():
                if t['url'] == url:
                    return True
        return False

    def is_it_localmedia(self, rid, sid, category, url, timestamp, retrieve = True):
        filename = os.path.basename(url)
        cached = self.look_in_cache(filename, timestamp)
        if cached is not None:
            return (True, cached)

        if len(self.threads) > 0:   # squeeze threads out by the way
            self.threads = [t for t in self.threads if t['thr'].isAlive()]
        if self.in_progress(url):
            print_n_log("Retrieving", url, "in progress..")
            return (False, None)

        ldir = MEDIA_DIR + str(rid)
        fpath = "{}/{:02d}-{}-{}-{}".format(ldir, sid, category, timestamp, filename)
        if os.path.isfile(fpath):
            self.mediacache.append(dict(fn=filename, ts=timestamp, path=fpath))
            return (True, fpath)
        else:
            if retrieve:
                if not os.path.isdir(ldir):
                    try:
                        os.makedirs(ldir, exist_ok=True)
                    except OSError as e:
                        print_n_log(e)
                        return (False, None)
                print_n_log("Retrieve", url, "as", fpath)
                t = threading.Thread(target=self.getter, args=(url, fpath))
                t.start()
                self.threads.append(dict(thr=t, url=url))
        return (False, None)

    def check_all_media(self, data, callback):
        for m in data:
            url = m.get('url', None)
            rid = m.get('rid', None)
            sid = m.get('sid', None)
            cat = m.get('category', None)
            ts = m.get('timestamp', None)
            hsum = m.get('hash', None)
            if all(v is not None for v in (rid, sid, cat, url, ts, hsum)):
                if not callback(rid, sid, cat, url, ts, hsum):
                    return False
            else:
                print_n_log("Not enough attributes (url/rid/sid/cat/ts) in:", m)
                return False
        return True

    def is_it_actual(self, lfile, hsum, ts):
        if not os.path.isfile(lfile):
            return False
        try:
            lsum = hashlib.md5(open(lfile,'rb').read()).hexdigest()
        except Exception as e:
            print_n_log("Got hashlib exception:", e)
            return False
        if hsum != lsum:
            print_n_log("hash error:", hsum, lsum)
            return False
        else:
            return True

    def local_or_retrieve(self, rid, sid, cat, url, ts, hsum):
        its_local, localfile = self.is_it_localmedia(rid, sid, cat, url, ts)
        if its_local:
            if not self.is_it_actual(localfile, hsum, ts):
                try:
                    os.remove(localfile)
                    self.is_it_localmedia(rid, sid, cat, url, ts)
                except OSError as e:
                    if e.errno != errno.ENOENT:
                        print_n_log("IO error:", e)
                        return False
        return True

    def only_localmedia(self, rid, sid, cat, url, ts, hsum):
        its_local, localfile = self.is_it_localmedia(rid, sid, cat, url, ts, retrieve = False)
        if its_local:
            if self.is_it_actual(localfile, hsum, ts):
                return True
        return False

    def savemedia(self, data):
        sync = 0
        while sync < 3:
            sync += 1
            start_tm = time.time()
            again = "" if sync == 1 else "again"
            print_n_log("Syncing {}...".format(again))
            if not self.check_all_media(data, self.local_or_retrieve):
                continue
            for t in self.threads:
                t['thr'].join()
            if self.check_all_media(data, self.only_localmedia):
                print_n_log("Elapsed synchronization time:", (time.time() - start_tm))
                self.synced = True
                return self.synced
        print_n_log("Synchronization failed")
        self.synced = False
        return self.synced

    def is_synced(self):
        return self.synced

    def playnsave(self, rid, sid, category, url, timestamp):
#    vlc http://dl6.mp3party.net/download/7952427 --vout dummy --sout "#duplicate{dst=std{access=file,mux=raw,dst=OUT.mp3},dst=display" --sout-all
        if (not isinstance(rid, int)) or (not isinstance(sid, int)):
            print_n_log("RouteID and StopID must be INT:", ris, sid)
            return
        its_local, localfile = self.is_it_localmedia(rid, sid, category, url, timestamp)
        item = localfile if its_local else url
        self.playfile(dict(file=item), True if its_local else None)

    def playfile(self, media, cached=None):
        if self.player.is_playing():
            print_n_log("Stop playing")
            self.player.stop()
        sfx = "" if self.options is None else ", options: "+self.options
        pfx = "" if cached is None else "(cached)"
        print_n_log("Play" + pfx + ": " + media['file'] + sfx)
        self.player.set_mrl(media['file']) if self.options is None else self.player.set_mrl(media['file'], self.options)
        self.player.play()
        i = 0
        while (not self.player.is_playing()) and (i < 6):  # wait for start upto 3sec
            time.sleep(0.5)
            i += 1


    def setlabel(self, txt, tag, align, lag = None):
        lab = QLabel(txt, self.info)
        lab.setAlignment(align)
        lab.setStyleSheet(stop_css[tag]['style'])
        lab.setGeometry(stop_css[tag]['geom']['x'], stop_css[tag]['geom']['y'], stop_css[tag]['geom']['w'], stop_css[tag]['geom']['h'])
        lab.setWordWrap(True)
#        f = QFont(BASE_FF)
#        f.setStretch(110) #QFont.SemiExpanded)
#        f.setWeight(800) #QFont.Black)
#        f.setLetterSpacing(QFont.PercentageSpacing, 110)
#        lab.setFont(f)
        lag_lab = None
        if lag is not None:
            lag_lab = QLabel(str(lag)+" хв", self.info)
            lag_lab.setAlignment(Qt.AlignVCenter|Qt.AlignRight)
            lag_lab.setStyleSheet(stop_css[tag]['lag']['style'])
            lag_lab.setGeometry(stop_css[tag]['lag']['geom']['x'], stop_css[tag]['lag']['geom']['y'], stop_css[tag]['lag']['geom']['w'], stop_css[tag]['lag']['geom']['h'])
        return dict(lab=lab, lag=lag_lab)

    def change_display(self, active, inactive):
        for t in self.elems[active]:
            self.elems[active][t]['lab'].show()
            ll = self.elems[active][t].get('lag', None)
            if ll is not None:
                ll.show()
        for t in self.elems[inactive]:
            self.elems[inactive][t]['lab'].hide()
            ll = self.elems[inactive][t].get('lag', None)
            if ll is not None:
                ll.hide()

    def display_stop(self, stop, elem):
        (name, eta) = ('', 0) if stop is None else (stop.get('name', None), stop.get('lag', None))
        if name is not None:
            lab = elem.get('lab', None)
            if lab is not None:
                lab.setText(name.upper())
        if eta is not None:
            lag = elem.get('lag', None)
            if lag is not None:
                eta_txt = '' if name == '' else str(round((eta+0.1)/60))+" хв"
                lag.setText(eta_txt)

    def set_stops(self, tag, stops):
        ina = 'after' if tag == 'at' else 'at'
        if tag == 'at':
            self.display_stop(stops['s1'], self.elems[tag]['up'])
            self.display_stop(stops['s2'], self.elems[tag]['br'])
        elif tag == 'after':
            self.display_stop(stops['s2'], self.elems[tag]['s1'])
            self.display_stop(stops['s3'], self.elems[tag]['s2'])
            self.display_stop(stops['s4'], self.elems[tag]['s3'])
        self.change_display(tag, ina)
        self.info.setStyleSheet(self.bgs[tag])
        self.info.update()

    def set_title(self, text):
        self.route['lab'].setText(text)

    def set_bg(self, tag):
        if tag in self.bgs:
            print_n_log("Set background:", BASE_DIR+self.bgs[tag])
            self.info.setStyleSheet("background-image:url("+BASE_DIR+self.bgs[tag]+");")
Beispiel #24
0
class PreprocessorModule(QWidget):
    """The base widget for the pre-processing modules."""

    change_signal = Signal()  # Emitted when the settings are changed.
    # Emitted when the module has a message to display in the main widget.
    error_signal = Signal(str)
    enabled = False  # If the module is enabled.

    def __init__(self, title, toggle_enabled, is_enabled):
        super().__init__()

        # Title bar.
        title_holder = QWidget()
        title_holder.setSizePolicy(QSizePolicy.MinimumExpanding,
                                   QSizePolicy.Fixed)
        title_holder.setStyleSheet("""
        .QWidget {
        background: qlineargradient( x1:0 y1:0, x2:0 y2:1,
        stop:0 #F8F8F8, stop:1 #C8C8C8);
        border-bottom: 1px solid #B3B3B3;
        }
        """)
        self.titleArea = QHBoxLayout()
        self.titleArea.setContentsMargins(15, 10, 15, 10)
        self.titleArea.setSpacing(0)
        title_holder.setLayout(self.titleArea)

        self.title_label = QLabel(title)
        self.title_label.setStyleSheet('font-size: 12px;')
        self.titleArea.addWidget(self.title_label)

        self.off_label = QLabel('[disabled]')
        self.off_label.setStyleSheet('color: #B0B0B0; margin-left: 5px;')
        self.titleArea.addWidget(self.off_label)
        self.off_label.hide()

        self.titleArea.addStretch()

        # Root.
        self.rootArea = QVBoxLayout()
        self.rootArea.setContentsMargins(0, 0, 0, 0)
        self.rootArea.setSpacing(0)
        self.setLayout(self.rootArea)
        self.rootArea.addWidget(title_holder)

        self.contents = QWidget()
        contentArea = QVBoxLayout()
        contentArea.setContentsMargins(15, 10, 15, 10)
        self.contents.setLayout(contentArea)
        self.rootArea.addWidget(self.contents)

        self.enabled = is_enabled
        if toggle_enabled:
            self.toggle_module_switch = QCheckBox()
            switch_icon_on_resource = _i('on_button.png')
            switch_icon_off_resource = _i('off_button.png')
            style_sheet = '''
            QCheckBox::indicator {
                width: 23px;
                height: 23px;
            }
            QCheckBox::indicator:checked {
                image: url(%s);
            }
            QCheckBox::indicator:unchecked {
                image: url(%s);
            }
            ''' % (switch_icon_on_resource, switch_icon_off_resource)
            self.toggle_module_switch.setStyleSheet(style_sheet)
            self.toggle_module_switch.setChecked(self.enabled)
            self.toggle_module_switch.stateChanged.connect(self.on_toggle)

            # Change the view according to the flag.
            if self.enabled:
                self.off_label.hide()
                self.contents.show()
                self.title_label.setStyleSheet('color: #000000;')
            else:
                self.off_label.show()
                self.contents.hide()
                self.title_label.setStyleSheet('color: #B0B0B0;')

            self.titleArea.addWidget(self.toggle_module_switch)

    def add_to_content_area(self, new_widget):
        self.contents.layout().addWidget(new_widget)

    def add_layout_to_content_area(self, new_layout):
        self.contents.layout().addLayout(new_layout)

    def notify_on_change(self):
        # Emits signals corresponding to the changes done.
        self.change_signal.emit()

    def on_toggle(self):
        # Activated when the widget is enabled/disabled.
        self.enabled = not self.enabled
        if self.enabled:
            self.off_label.hide()
            self.contents.show()
            self.title_label.setStyleSheet('color: #000000;')
        else:
            self.off_label.show()
            self.contents.hide()
            self.title_label.setStyleSheet('color: #B0B0B0;')
        self.change_signal.emit()

    def restore_data(self, data):
        # Restores the widget state from the input data.
        raise NotImplementedError

    def export_data(self):
        # Export the settings for this module instance.
        return NotImplementedError

    @staticmethod
    def get_pp_settings():
        # Returns the dict representation of this portion of a pre-processor.
        return NotImplementedError
class XLoaderWidget(QWidget):
    """ """
    Mode    = enum('Spinner', 'Progress')
    MOVIE   = None
    
    def __init__( self, parent = None, style='gray' ):
        super(XLoaderWidget, self).__init__( parent )
        
        # define properties
        self._currentMode       = None
        self._showSubProgress   = False
        
        self.setAttribute(Qt.WA_DeleteOnClose)
        
        # udpate the palette
        palette = self.palette()
        
        if style == 'white':
            palette.setColor( palette.Window, QColor(255, 255, 255, 180) )
        else:
            palette.setColor( palette.Window, QColor( 80, 80, 80, 180 ) )
        
        palette.setColor( palette.Base, Qt.gray )
        palette.setColor( palette.AlternateBase, Qt.lightGray )
        palette.setColor( palette.WindowText, Qt.gray )
        self.setPalette(palette)
        
        # create the movie label
        self._movieLabel = QLabel(self)
        self._movieLabel.setAlignment(Qt.AlignCenter)
        self._movieLabel.setMovie(XLoaderWidget.getMovie())
        self._movieLabel.setPalette(palette)
        
        self._smallMovieLabel = QLabel(self)
        self._smallMovieLabel.setAlignment(Qt.AlignCenter)
        self._smallMovieLabel.setMovie(XLoaderWidget.getMovie())
        self._smallMovieLabel.setPalette(palette)
        self._smallMovieLabel.hide()
        
        # create text label
        self._messageLabel = QLabel(self)
        self._messageLabel.setAlignment(Qt.AlignCenter)
        self._messageLabel.setText('Loading...')
        self._messageLabel.setPalette(palette)
        
        # create primary progress bar
        self._primaryProgressBar    = XLoaderProgressBar(self)
        self._subProgressBar        = XLoaderProgressBar(self)
        
        self._primaryProgressBar.setPalette(palette)
        self._subProgressBar.setPalette(palette)
        
        # create the loader widget
        self._loaderFrame = QFrame(self)
        self._loaderFrame.setFrameShape(QFrame.Box)
        self._loaderFrame.setAutoFillBackground(True)
        self._loaderFrame.setFixedWidth(160)
        self._loaderFrame.setFixedHeight(60)
        
        if style == 'white':
            palette.setColor(palette.Window, QColor('white'))
        else:
            palette.setColor(palette.Window, QColor(85, 85, 85))
        self._loaderFrame.setPalette(palette)
        
        layout = QVBoxLayout()
        layout.addWidget(self._movieLabel)
        layout.addWidget(self._primaryProgressBar)
        layout.addWidget(self._subProgressBar)
        layout.addStretch()
        layout.addWidget(self._messageLabel)
        self._loaderFrame.setLayout(layout)
        
        # set default properties
        self.setAutoFillBackground(True)
        
        # layout the controls
        layout = QVBoxLayout()
        layout.addStretch(1)
        layout.addWidget(self._loaderFrame)
        layout.addWidget(self._smallMovieLabel)
        layout.addStretch(1)
        
        hlayout = QHBoxLayout()
        hlayout.addStretch(1)
        hlayout.addLayout(layout)
        hlayout.addStretch(1)
        
        self.setLayout(hlayout)
        self.setCurrentMode(XLoaderWidget.Mode.Spinner)
        
        # create connections
    
    def currentMode( self ):
        """
        Returns the current mode that this loader's in.
        
        :return     <XLoaderWidget.Mode>
        """
        return self._currentMode
    
    def eventFilter( self, object, event ):
        """
        Resizes this widget with the parent when its resize event is triggered.
        
        :param      object | <QObject>
                    event  | <QEvent>
        
        :return     <bool> | consumed
        """
        if event.type() == event.Resize:
            self.resize(event.size())
            
        elif event.type() == event.Move:
            self.move(event.pos())
        
        elif event.type() == event.Close:
            self.setParent(None)
            self.deleteLater()
        
        return False
    
    def increment( self, amount=1):
        """
        Increments the main progress bar by amount.
        """
        self._primaryProgressBar.setValue(self.value() + amount)
    
    def incrementSub( self, amount=1):
        """
        Increments the sub-progress bar by amount.
        """
        self._subProgressBar.setValue(self.subValue() + amount)
    
    def message( self ):
        """
        Returns the current message being displayed in the loader.
        
        :return     <str>
        """
        return self._messageLabel.text()
    
    def movie(self):
        """
        Returns the movie linked with this loader.
        
        :return     <QMovie>
        """
        return self._movieLabel.movie()
    
    def resize(self, size):
        """
        Handles when the loader is too small for an area.
        
        :param      event | <QResizeEvent>
        """
        super(XLoaderWidget, self).resize(size)
        
        # show small loader
        if size.width() < self._loaderFrame.width() or \
           size.height() < self._loaderFrame.height():
            self._loaderFrame.hide()
            self._smallMovieLabel.show()
        
        # show regular loader
        else:
            self._loaderFrame.show()
            self._smallMovieLabel.hide()
    
    def subValue( self ):
        """
        Returns the value of the sub progress bar.
        
        :return     <int>
        """
        return self._subProgressBar.value()
    
    def setCurrentMode( self, mode ):
        """
        Sets what mode this loader will be in.
        
        :param      mode | <XLoaderWidget.Mode>
        """
        if ( mode == self._currentMode ):
            return
            
        self._currentMode = mode
        
        ajax = mode == XLoaderWidget.Mode.Spinner
        self._movieLabel.setVisible(ajax)
        self._primaryProgressBar.setVisible(not ajax)
        self._subProgressBar.setVisible(not ajax and self._showSubProgress)
    
    def setMessage( self, message ):
        """
        Sets the loading message to display.
        
        :param      message | <str>
        """
        self._messageLabel.setText(message)
    
    def setMovie( self, movie ):
        """
        Sets the movie for this loader to the inputed movie.
        
        :param      movie | <QMovie>
        """
        self._movieLabel.setMovie(movie)
        self._smallMovieLabel.setMovie(movie)
    
    def setTotal( self, amount ):
        """
        Sets the total amount for the main progress bar.
        
        :param      amount | <int>
        """
        self._primaryProgressBar.setValue(0)
        self._primaryProgressBar.setMaximum(amount)
        
        if amount:
            self.setCurrentMode(XLoaderWidget.Mode.Progress)
    
    def setSubTotal( self, amount ):
        """
        Sets the total value for the sub progress bar.
        
        :param      amount | <int>
        """
        self._subProgressBar.setValue(0)
        self._subProgressBar.setMaximum(amount)
        if amount:
            self.setShowSubProgress(True)
    
    def setSubValue( self, value ):
        """
        Sets the current value for the sub progress bar.
        
        :param      value | <int>
        """
        self._subProgressBar.setValue(value)
        
    def setShowSubProgress( self, state ):
        """
        Toggles whether or not the sub progress bar should be visible.
        
        :param      state | <bool>
        """
        ajax = self.currentMode() == XLoaderWidget.Mode.Spinner
        self._showSubProgress = state
        self._subProgressBar.setVisible(not ajax and state)
    
    def setValue(self, value):
        """
        Sets the current value for the primary progress bar.
        
        :param      value | <int>
        """
        self._primaryProgressBar.setValue(value)
    
    def showSubProgress( self ):
        """
        Returns whether or not the sub progress bar is visible when not in
        ajax mode.
        
        :return     <bool>
        """
        return self._showSubProgress
    
    def subValue( self ):
        """
        Returns the sub value for this loader.
        
        :return     <int>
        """
        return self._subProgressBar.value()
    
    def value( self ):
        """
        Returns the value for the primary progress bar.
        
        :return     <int>
        """
        return self._primaryProgressBar.value()
    
    @staticmethod
    def getMovie():
        """
        Returns the movie instance for the loader widget.
        
        :return     <QMovie>
        """
        if not XLoaderWidget.MOVIE:
            filename = projexui.resources.find('img/ajax_loader.gif')
            XLoaderWidget.MOVIE = QMovie()
            XLoaderWidget.MOVIE.setFileName(filename)
            XLoaderWidget.MOVIE.start()
        
        return XLoaderWidget.MOVIE
    
    @staticmethod
    def start(widget, processEvents=True, style=None, movie=None):
        """
        Starts a loader widget on the inputed widget.
        
        :param      widget          | <QWidget>
        
        :return     <XLoaderWidget>
        """
        if style is None:
            style = os.environ.get('PROJEXUI_LOADER_STYLE', 'gray')
        
        # there is a bug with the way the loader is handled in a splitter,
        # so bypass it
        parent = widget.parent()
        while isinstance(parent, QSplitter):
            parent = parent.parent()
        
        # retrieve the loader widget
        loader = getattr(widget, '_private_xloader_widget', None)
        if not loader:
            loader = XLoaderWidget(parent, style)
            
            # make sure that if the widget is destroyed, the loader closes
            widget.destroyed.connect(loader.deleteLater)
            
            setattr(widget, '_private_xloader_widget', loader)
            setattr(widget, '_private_xloader_count', 0)
            
            loader.move(widget.pos())
            if widget.isVisible():
                loader.show()
            
            if movie:
                loader.setMovie(movie)
            
            widget.installEventFilter(loader)
        else:
            count = getattr(widget, '_private_xloader_count', 0)
            setattr(widget, '_private_xloader_count', count + 1)
        
        loader.resize(widget.size())
        return loader
    
    @staticmethod
    def stop(widget, force=False):
        """
        Stops a loader widget on the inputed widget.
        
        :param      widget | <QWidget>
        """
        # make sure we have a widget to stop
        loader = getattr(widget, '_private_xloader_widget', None)
        if not loader:
            return
        
        # decrement the number of times this loader was created for the widget
        # to allow for stacked closure
        count = getattr(widget, '_private_xloader_count', 0)
        if force or count <= 1:
            # close out the loader widget
            setattr(widget, '_private_xloader_count', 0)
            setattr(widget, '_private_xloader_widget', None)
            
            loader.close()
            loader.setParent(None)
            loader.deleteLater()
        else:
            setattr(widget, '_private_xloader_count', count - 1)
    
    @staticmethod
    def stopAll(widget):
        """
        Stops all loader widgets from this parent down, cleaning out the \
        memory for them.
        
        :param      widget  | <QWidget>
        """
        for loader in widget.findChildren(XLoaderWidget):
            loader.setParent(None)
            loader.deleteLater()
Beispiel #26
0
class FindDialog(QDialog):
    def __init__(self,parent=None):
        logging.debug(__name__ +': __init__')
        QDialog.__init__(self,parent)
        self.setWindowFlags(Qt.Window)
        self.setWindowTitle("Find...")
        
        self._findAlgorithm=None
        self._properties=[]
        self._scripts=[]
        self._find=True
        self._filter=False

        self.fill()
        
    def fill(self):
        logging.debug(__name__ +': fill')
        self._findLabelLabel = QLabel("Label: ")
        self._findLabelLineEdit = QLineEdit()
        self._findLabelLineEdit.setToolTip("Example: Particle1")

        self._caseSensitiveCheckBox=QCheckBox("Case sensitive")
        self._exactMatchCheckBox=QCheckBox("Exact match")
        self._helpButton = QPushButton("&Help")
        
        self._findPreviousButton = QPushButton("&Previous")
        self._findPreviousButton.hide()
        self._findNumberLabel = QLabel("?/?")
        self._findNumberLabel.hide()
        self._findNextButton = QPushButton("&Find")
        self._filterButton = QPushButton("&Filter")
        self._resetButton = QPushButton("&Reset")
        self._closeButton = QPushButton("&Close")

        self.setLayout(QVBoxLayout())
        self.layout().setSizeConstraint(QLayout.SetFixedSize)
        self._layout1=QHBoxLayout()
        self._layout3=QHBoxLayout()
        self._layout4=QHBoxLayout()
    
        self._layout1.setSizeConstraint(QLayout.SetDefaultConstraint)
        self._layout3.setSizeConstraint(QLayout.SetDefaultConstraint)
        self._layout4.setSizeConstraint(QLayout.SetDefaultConstraint)
        self.layout().addLayout(self._layout1)
        self.layout().addLayout(self._layout3)
        self.layout().addStretch()
        self.layout().addLayout(self._layout4)
        
        self._layout1.addWidget(self._findLabelLabel)
        self._layout1.addWidget(self._findLabelLineEdit)

        self._layout3.addWidget(self._helpButton)
        self._layout3.addStretch()
        self._layout3.addWidget(self._caseSensitiveCheckBox)
        self._layout3.addWidget(self._exactMatchCheckBox)
        
        self._layout4.addWidget(self._findPreviousButton)
        self._layout4.addWidget(self._findNumberLabel)
        self._layout4.addWidget(self._findNextButton)
        self._layout4.addWidget(self._filterButton)
        self._layout4.addWidget(self._resetButton)
        self._layout4.addStretch()
        self._layout4.addWidget(self._closeButton)

        self.connect(self._findLabelLineEdit, SIGNAL('textChanged(QString)'), self.edited)
        self.connect(self._caseSensitiveCheckBox, SIGNAL('stateChanged(int)'), self.edited)
        self.connect(self._exactMatchCheckBox, SIGNAL('stateChanged(int)'), self.edited)

        self.connect(self._findPreviousButton, SIGNAL('clicked(bool)'), self.findPrevious)
        self.connect(self._findNextButton, SIGNAL('clicked(bool)'), self.findNext)
        self.connect(self._filterButton, SIGNAL('clicked(bool)'), self.filter)
        self.connect(self._resetButton, SIGNAL('clicked(bool)'), self.reset)
        self.connect(self._helpButton, SIGNAL('clicked(bool)'), self.help)
        self.connect(self._closeButton, SIGNAL('clicked(bool)'), self.reject)

        self._addStringProperty(False,False)
        self._addScript(False,False)

    def _removeProperty(self):
        for property in self._properties:
            if self.sender() in property:
                self._remove(property)
                return

    def _remove(self,object):
        for o in object:
            if isinstance(o,QWidget):
                o.close()
        self.layout().removeItem(object[0])
        if object in self._properties:
            self._properties.remove(object)
        elif object in self._scripts:
            self._scripts.remove(object)

    def _addStringProperty(self,bool,deletable=True):

        layout2=QHBoxLayout()

        findPropertyNameLabel = QLabel("Property: ")
        findPropertyNameLineEdit = QLineEdit()
        findPropertyNameLineEdit.setToolTip("Example: Label = Particle1 ")
        findPropertyValueLabel = QLabel(" = ")
        findPropertyValueLineEdit = QLineEdit()
        findPropertyValueLineEdit.setToolTip("Example: Label = Particle1 ")
        propertyAdd = QToolButton()
        propertyAdd.setText("+")
        propertyDelete = QToolButton()
        propertyDelete.setText("-")
        
        if deletable:
            propertyAdd.hide()
        else:
            propertyDelete.hide()
        layout2.addWidget(propertyAdd)
        layout2.addWidget(propertyDelete)
        layout2.addWidget(findPropertyNameLabel)
        layout2.addWidget(findPropertyNameLineEdit)
        layout2.addWidget(findPropertyValueLabel)
        layout2.addWidget(findPropertyValueLineEdit)

        self.connect(findPropertyNameLineEdit, SIGNAL('textChanged(QString)'), self.edited)
        self.connect(findPropertyValueLineEdit, SIGNAL('textChanged(QString)'), self.edited)
        self.connect(propertyAdd, SIGNAL('clicked(bool)'), self._addStringProperty)
        self.connect(propertyDelete, SIGNAL('clicked(bool)'), self._removeProperty)

        self.layout().insertLayout(len(self._properties)+len(self._scripts)+1,layout2)
        
        self._properties+=[(layout2,findPropertyNameLineEdit,findPropertyValueLineEdit,findPropertyNameLabel,findPropertyValueLabel,propertyAdd,propertyDelete)]
        
    def _removeScript(self):
        for script in self._scripts:
            if self.sender() in script:
                self._remove(script)
                return
        
    def _addScript(self,bool,deletable=True):

        layout2=QHBoxLayout()

        findScriptLabel = QLabel("Filter = ")
        findScriptLineEdit = QLineEdit("")
        findScriptLineEdit.setToolTip("Example: object.Label == 'Particle1' ")
        scriptAdd = QToolButton()
        scriptAdd.setText("+")
        scriptDelete = QToolButton()
        scriptDelete.setText("-")
        
        if deletable:
            scriptAdd.hide()
        else:
            scriptDelete.hide()
        layout2.addWidget(scriptAdd)
        layout2.addWidget(scriptDelete)
        layout2.addWidget(findScriptLabel)
        layout2.addWidget(findScriptLineEdit)

        self.connect(findScriptLineEdit, SIGNAL('textChanged(QString)'), self.edited)
        self.connect(scriptAdd, SIGNAL('clicked(bool)'), self._addScript)
        self.connect(scriptDelete, SIGNAL('clicked(bool)'), self._removeScript)

        self.layout().insertLayout(len(self._properties)+len(self._scripts)+1,layout2)
        
        self._scripts+=[(layout2,findScriptLineEdit,findScriptLabel,scriptAdd,scriptDelete)]
        
    def onScreen(self, filter=False, find=True):
        logging.debug(__name__ +': onScreen')
        self._find=find
        self._filter=filter
        if self._find and self._filter:
            self._findNextButton.setDefault(True)
            self.setWindowTitle("Find/Filter...")
        elif self._find:
            self._findNextButton.setDefault(True)
            self.setWindowTitle("Find...")
        elif self._filter:
            self._filterButton.setDefault(True)
            self.setWindowTitle("Filter...")
            
        self._findNextButton.setVisible(find)
        if not find:
            self._findPreviousButton.setVisible(find)
        self._filterButton.setVisible(filter)
        self.show()
        self.raise_()
        self.activateWindow()
        self._findLabelLineEdit.setFocus()
        
    def keyPressEvent(self, event):
        """ 
        """
        if event.modifiers() == Qt.ControlModifier and event.key() == Qt.Key_W:
            self.close()
        QDialog.keyPressEvent(self, event)

    def setFindAlgorithm(self,findAlgorithm):
        logging.debug(__name__ +': setFindAlgorithm')
        self._findAlgorithm=findAlgorithm
        
    def findAlgorithm(self):
        return self._findAlgorithm
        
    def label(self):
        return str(self._findLabelLineEdit.text().toAscii())
    
    def setLabel(self,label):
        logging.debug(__name__ +': setLabel '+label)
        self._findLabelLineEdit.setText(label)
    
    def properties(self):
        return [(str(property[1].text().toAscii()),str(property[2].text().toAscii())) for property in self._properties]
    
    def scripts(self):
        return [str(script[1].text().toAscii()) for script in self._scripts]
    
    def caseSensitive(self):
        return self._caseSensitiveCheckBox.checkState()==Qt.Checked

    def exactMatch(self):
        return self._exactMatchCheckBox.checkState()==Qt.Checked
    
    def edited(self):
        self._findPreviousButton.hide()
        if self._findNextButton.isVisible():
            self._findNumberLabel.hide()
            self._findNextButton.setText("&Find")
    
    def _updateNumberLabel(self):
        current=self._findAlgorithm.currentNumber()
        total=self._findAlgorithm.numberOfResults()
        message=self._findAlgorithm.message()
        text=""
        if self._filter:
            text=str(total)+" found"
        else:
            if total>0:
                text=str(current)+"/"+str(total)
            else:
                text="not found"
        if message:
            text+=" ("+message+")"
        self._findNumberLabel.setText(text)
    
    def findPrevious(self):
        logging.debug(__name__ +': findPrevious')
        object=self._findAlgorithm.previous()
        self._updateNumberLabel()
        self.emit(SIGNAL("found"),object)
    
    def findNext(self):
        logging.debug(__name__ +': findNext')
        if not self._findPreviousButton.isVisible():
            self._findNextButton.setVisible(False)
            self._filterButton.setVisible(False)
            self._resetButton.setVisible(False)
            self._findNumberLabel.setText("Searching...")
            self._findNumberLabel.show()
            thread = ThreadChain(self._findAlgorithm.findUsingFindDialog, self)
            while thread.isRunning():
                if not Application.NO_PROCESS_EVENTS:
                    QCoreApplication.instance().processEvents()
            object=thread.returnValue()
            self._findNextButton.setVisible(True)
            if self._filter:
                self._filterButton.setVisible(True)
            self._resetButton.setVisible(True)
            self._findPreviousButton.show()
            self._findNextButton.setText("&Next")
        else:
            object=next(self._findAlgorithm)
        self._updateNumberLabel()
        self.emit(SIGNAL("found"),object)

    def filter(self):
        logging.debug(__name__ +': filter')
        self._findNextButton.setVisible(False)
        self._filterButton.setVisible(False)
        self._resetButton.setVisible(False)
        self._findNumberLabel.setText("Searching...")
        self._findNumberLabel.show()
        thread = ThreadChain(self._findAlgorithm.findUsingFindDialog, self)
        while thread.isRunning():
            if not Application.NO_PROCESS_EVENTS:
                QCoreApplication.instance().processEvents()
        if self._find:
            self._findNextButton.setVisible(True)
        self._filterButton.setVisible(True)
        self._resetButton.setVisible(True)
        self._updateNumberLabel()
        self.emit(SIGNAL("filtered"),self._findAlgorithm.results())

    def reset(self):
        self.setLabel("")
        for o in self._scripts+self._properties:
            self._remove(o)
        self._addStringProperty(False,False)
        self._addScript(False,False)
        self._findAlgorithm.clear()
        self._updateNumberLabel()
        if self._filter:
            self.emit(SIGNAL("filtered"),None)
        self.update()

    def help(self):
        QMessageBox.about(self, 'Info', "You can find objects \n1. using their label shown in the center view, \n2. their properties shown in the property view, or \n3. using a Python script returning a boolean. Empty fields are ignored. Examples are shown as tool tips.")
Beispiel #27
0
class LCD20x4(PluginBase):
    MAX_LINE = 4
    MAX_POSITION = 20
    qtcb_pressed = pyqtSignal(int)
    qtcb_released = pyqtSignal(int)

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

        self.lcd = self.device

        self.qtcb_pressed.connect(self.cb_pressed)
        self.lcd.register_callback(self.lcd.CALLBACK_BUTTON_PRESSED,
                                   self.qtcb_pressed.emit)
        self.qtcb_released.connect(self.cb_released)
        self.lcd.register_callback(self.lcd.CALLBACK_BUTTON_RELEASED,
                                   self.qtcb_released.emit)

        self.line_label = QLabel('Line: ')
        self.line_combo = QComboBox()
        for i in range(LCD20x4.MAX_LINE):
            self.line_combo.addItem(str(i))

        self.pos_label = QLabel('Position: ')
        self.pos_combo = QComboBox()
        for i in range(LCD20x4.MAX_POSITION):
            self.pos_combo.addItem(str(i))

        self.line_pos_layout = QHBoxLayout()
        self.line_pos_layout.addWidget(self.line_label)
        self.line_pos_layout.addWidget(self.line_combo)
        self.line_pos_layout.addWidget(self.pos_label)
        self.line_pos_layout.addWidget(self.pos_combo)
        self.line_pos_layout.addStretch()

        self.text_label = QLabel('Text: ')
        self.text_edit = QLineEdit()
        self.text_edit.setMaxLength(LCD20x4.MAX_POSITION)
        self.text_button = QPushButton('Send Text')
        self.text_layout = QHBoxLayout()
        self.text_layout.addWidget(self.text_label)
        self.text_layout.addWidget(self.text_edit)
        self.text_layout.addWidget(self.text_button)

        self.clear_button = QPushButton("Clear Display")

        self.bl_button = QPushButton()
        self.cursor_button = QPushButton()
        self.blink_button = QPushButton()

        self.onofflayout = QHBoxLayout()
        self.onofflayout.addWidget(self.bl_button)
        self.onofflayout.addWidget(self.cursor_button)
        self.onofflayout.addWidget(self.blink_button)

        self.b0_label = QLabel('Button 0: Released,')
        self.b1_label = QLabel('Button 1: Released,')
        self.b2_label = QLabel('Button 2: Released,')
        self.b3_label = QLabel('Button 3: Released')

        self.buttonlayout = QHBoxLayout()
        self.buttonlayout.addWidget(self.b0_label)
        self.buttonlayout.addWidget(self.b1_label)
        self.buttonlayout.addWidget(self.b2_label)
        self.buttonlayout.addWidget(self.b3_label)

        self.cursor_button.clicked.connect(self.cursor_clicked)
        self.blink_button.clicked.connect(self.blink_clicked)
        self.clear_button.clicked.connect(self.clear_clicked)
        self.bl_button.clicked.connect(self.bl_clicked)
        self.text_button.clicked.connect(self.text_clicked)

        if self.firmware_version >= (2, 0, 1):
            line = QFrame()
            line.setFrameShape(QFrame.HLine)
            line.setFrameShadow(QFrame.Sunken)

            gridlayout = QGridLayout()
            gridlayout.setHorizontalSpacing(2)
            gridlayout.setVerticalSpacing(2)

            self.character_boxes_bool = []
            self.character_boxes = []
            for i in range(5):
                self.character_boxes.append([])
                self.character_boxes_bool.append([])
                for j in range(8):
                    b = QToolButton()
                    b.setAutoFillBackground(True)
                    b.setStyleSheet("background-color: rgb(255, 255, 255)")
                    b.setMaximumSize(25, 25)
                    b.setMinimumSize(25, 25)

                    def get_lambda(i, j):
                        return lambda: self.char_button_clicked(i, j)

                    b.clicked.connect(get_lambda(i, j))

                    self.character_boxes[i].append(b)
                    self.character_boxes_bool[i].append(True)
                    gridlayout.addWidget(b, j, i)

            self.char_index_label = QLabel('Index:')
            self.char_index_combo = QComboBox()
            self.char_index_combo.currentIndexChanged.connect(
                self.char_index_changed)
            for i in range(8):
                self.char_index_combo.addItem(str(i))

            self.char_index_layout = QHBoxLayout()
            self.char_index_layout.addStretch()
            self.char_index_layout.addWidget(self.char_index_label)
            self.char_index_layout.addWidget(self.char_index_combo)
            self.char_index_layout.addStretch()

            self.char_index_save = QPushButton('Save Character')
            self.char_index_save.clicked.connect(self.char_index_save_clicked)
            self.char_show = QPushButton('Show all Custom Characters on LCD')
            self.char_show.clicked.connect(self.show_clicked)
            self.char_save_layout = QVBoxLayout()
            self.char_save_layout.addStretch()
            self.char_save_layout.addLayout(self.char_index_layout)
            self.char_save_layout.addWidget(self.char_index_save)
            self.char_save_layout.addWidget(self.char_show)

            help_label = QLabel(
                'Use "\\0, \\1, ..., \\7" in text field to show custom characters.'
            )
            help_label.setWordWrap(True)

            self.char_save_layout.addWidget(help_label)
            self.char_save_layout.addStretch()

            grid_stretch_layout = QHBoxLayout()
            grid_stretch_layout.addWidget(QLabel('Custom Character: '))
            grid_stretch_layout.addLayout(gridlayout)
            grid_stretch_layout.addLayout(self.char_save_layout)
            grid_stretch_layout.addStretch()

            self.char_main_layout = QHBoxLayout()
            self.char_main_layout.addStretch()
            self.char_main_layout.addLayout(grid_stretch_layout)
            self.char_main_layout.addStretch()

        layout = QVBoxLayout(self)
        layout.addLayout(self.line_pos_layout)
        layout.addLayout(self.text_layout)
        layout.addWidget(self.clear_button)
        layout.addLayout(self.onofflayout)
        layout.addLayout(self.buttonlayout)

        if self.hardware_version <= (1, 1, 0):
            self.b3_label.hide()

        if self.firmware_version >= (2, 0, 1):
            layout.addWidget(line)
            layout.addLayout(self.char_main_layout)

        layout.addStretch(1)

    def char_button_clicked(self, i, j):
        if self.character_boxes_bool[i][j]:
            self.character_boxes_bool[i][j] = False
            self.character_boxes[i][j].setStyleSheet(
                "background-color: rgb(0, 0, 255)")
        else:
            self.character_boxes_bool[i][j] = True
            self.character_boxes[i][j].setStyleSheet(
                "background-color: rgb(255, 255, 255)")

    def is_backlight_on_async(self, on):
        if on:
            self.bl_button.setText('Backlight Off')
        else:
            self.bl_button.setText('Backlight On')

    def get_config_async(self, config):
        cursor, blink = config
        if cursor:
            self.cursor_button.setText('Cursor Off')
        else:
            self.cursor_button.setText('Cursor On')

        if blink:
            self.blink_button.setText('Blink Off')
        else:
            self.blink_button.setText('Blink On')

    def start(self):
        async_call(self.lcd.is_backlight_on, None, self.is_backlight_on_async,
                   self.increase_error_count)
        async_call(self.lcd.get_config, None, self.get_config_async,
                   self.increase_error_count)

    def stop(self):
        pass

    def destroy(self):
        pass

    def get_url_part(self):
        return 'lcd_20x4_v{0}{1}'.format(self.hardware_version[0],
                                         self.hardware_version[1])

    def is_hardware_version_relevant(self):
        return True

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

    def cb_pressed(self, button):
        if button == 0:
            self.b0_label.setText('Button 0: Pressed,')
        elif button == 1:
            self.b1_label.setText('Button 1: Pressed,')
        elif button == 2:
            self.b2_label.setText('Button 2: Pressed,')
        elif button == 3:
            self.b3_label.setText('Button 3: Pressed')

    def cb_released(self, button):
        if button == 0:
            self.b0_label.setText('Button 0: Released,')
        elif button == 1:
            self.b1_label.setText('Button 1: Released,')
        elif button == 2:
            self.b2_label.setText('Button 2: Released,')
        elif button == 3:
            self.b3_label.setText('Button 3: Released')

    def bl_clicked(self):
        try:
            if self.bl_button.text() == 'Backlight On':
                self.lcd.backlight_on()
                self.bl_button.setText('Backlight Off')
            else:
                self.lcd.backlight_off()
                self.bl_button.setText('Backlight On')
        except ip_connection.Error:
            return

    def get_config(self):
        cursor = self.cursor_button.text() == 'Cursor Off'
        blink = self.blink_button.text() == 'Blink Off'
        return (cursor, blink)

    def cursor_clicked(self):
        cursor, blink = self.get_config()
        try:
            self.lcd.set_config(not cursor, blink)
        except ip_connection.Error:
            return

        if cursor:
            self.cursor_button.setText('Cursor On')
        else:
            self.cursor_button.setText('Cursor Off')

    def blink_clicked(self):
        cursor, blink = self.get_config()
        try:
            self.lcd.set_config(cursor, not blink)
        except ip_connection.Error:
            return

        if blink:
            self.blink_button.setText('Blink On')
        else:
            self.blink_button.setText('Blink Off')

    def clear_clicked(self):
        try:
            self.lcd.clear_display()
        except ip_connection.Error:
            return

    def text_clicked(self):
        line = int(self.line_combo.currentText())
        position = int(self.pos_combo.currentText())
        text = self.text_edit.text()
        if self.firmware_version >= (2, 0, 1):
            for i in range(8):
                text = text.replace('\\' + str(i), chr(i + 8))
        try:
            self.lcd.write_line(line, position, unicode_to_ks0066u(text))
        except ip_connection.Error:
            return

    def char_index_save_clicked(self):
        char = [0] * 8
        for i in range(len(self.character_boxes)):
            for j in range(len(self.character_boxes[i])):
                if self.character_boxes_bool[i][j]:
                    char[j] |= 1 << (4 - i)

        index = int(self.char_index_combo.currentText())
        self.lcd.set_custom_character(index, char)

    def show_clicked(self):
        self.lcd.clear_display()
        line1 = '0:{0} 1:{1} 2:{2} 3:{3}'.format(chr(8), chr(9), chr(10),
                                                 chr(11))
        line2 = '4:{0} 5:{1} 6:{2} 7:{3}'.format(chr(12), chr(13), chr(14),
                                                 chr(15))
        self.lcd.write_line(0, 0, line1)
        self.lcd.write_line(1, 0, line2)

    def custom_character_async(self, characters):
        for i in range(len(self.character_boxes)):
            for j in range(len(self.character_boxes[i])):
                if characters[j] & (1 << i):
                    self.character_boxes_bool[4 - i][j] = True
                    self.character_boxes[4 - i][j].setStyleSheet(
                        "background-color: rgb(255, 255, 255)")
                else:
                    self.character_boxes_bool[4 - i][j] = False
                    self.character_boxes[4 - i][j].setStyleSheet(
                        "background-color: rgb(0, 0, 255)")

    def char_index_changed(self, index):
        async_call(self.lcd.get_custom_character, (index, ),
                   self.custom_character_async, self.increase_error_count)
Beispiel #28
0
class RunWidget(QWidget):

    def __init__(self):
        QWidget.__init__(self)
        vbox = QVBoxLayout(self)
        vbox.setSpacing(0)
        vbox.setContentsMargins(0, 0, 0, 0)
        self.output = OutputWidget(self)
        hbox = QHBoxLayout()
        self.input = QLineEdit()
        self.lblInput = QLabel(self.tr("Input:"))
        vbox.addWidget(self.output)
        hbox.addWidget(self.lblInput)
        hbox.addWidget(self.input)
        vbox.addLayout(hbox)

        #process
        self._proc = QProcess(self)
        self.connect(self._proc, SIGNAL("readyReadStandardOutput()"),
            self.output._refresh_output)
        self.connect(self._proc, SIGNAL("readyReadStandardError()"),
            self.output._refresh_error)
        self.connect(self._proc, SIGNAL("finished(int, QProcess::ExitStatus)"),
            self.finish_execution)
        self.connect(self.input, SIGNAL("returnPressed()"), self.insert_input)

    def finish_execution(self, exitCode, exitStatus):
        self.lblInput.hide()
        self.input.hide()
        format = QTextCharFormat()
        format.setAnchor(True)
        self.output.textCursor().insertText('\n\n')
        if exitStatus == QProcess.NormalExit:
            format.setForeground(Qt.green)
            self.output.textCursor().insertText(
                self.tr("Execution Successful!"), format)
        else:
            format.setForeground(Qt.red)
            self.output.textCursor().insertText(
                self.tr("Execution Interrupted"), format)

    def insert_input(self):
        text = self.input.text() + '\n'
        self._proc.writeData(text)
        self.input.setText("")

    def start_process(self, fileName, pythonPath=False, programParams=''):
        self.lblInput.show()
        self.input.show()
        self.output.setCurrentCharFormat(self.output.plain_format)
        self.output.setPlainText('Running: %s (%s)\n\n' % (fileName,
            unicode(time.ctime())))
        self.output.moveCursor(QTextCursor.Down)
        self.output.moveCursor(QTextCursor.Down)
        self.output.moveCursor(QTextCursor.Down)

        #runner.run_code_from_file(fileName)
        if not pythonPath:
            pythonPath = settings.PYTHON_PATH
        #change the working directory to the fileName dir
        file_directory = file_manager.get_folder(fileName)
        self._proc.setWorkingDirectory(file_directory)
        #force python to unbuffer stdin and stdout
        options = ['-u'] + settings.EXECUTION_OPTIONS.split()
        self._proc.start(pythonPath, options + [fileName] + \
            [p.strip() for p in programParams.split(',') if p])

    def kill_process(self):
        self._proc.kill()
Beispiel #29
0
class WidgetFFmpeg(QDialog):

    def __init__(self, idCodec, cheminVideoEntre, cheminSorti, valeurNum=0, laisserOuvert=1, tailleIm=None, tailleVideo=None, systeme=None, cheminFfmpeg=None, tempsApercu=None, optionSpeciale=None, cheminMPlayer=None):

        """widget ffmpeg"""
        super(WidgetFFmpeg, self).__init__()

        self.cheminFfmpeg=u"ffmpeg"

        self.cheminVideoEntre = unicode(cheminVideoEntre)
        self.cheminSorti = unicode(cheminSorti)

        # identifiant du codec
        self.idCodec = idCodec

        # valeur de la boite de spin pour l'encodage
        self.valeurNum = valeurNum

        # dimension des images (liste de 2 éléments)
        self.tailleIm = tailleIm

        # dimension de la vidéo (liste de 2 éléments)
        self.tailleVideo = tailleVideo

        # laisser ouvert la fenêtre après encodage
        self.laisserOuvert = laisserOuvert

        # Conversion minimale du filtre pour avoir un aperçu.
        # Indique le temps où l'aperçu doit être créé
        self.tempsApercu = tempsApercu

        # drapeau pour ne pas lancer 2 fois l'encodage
        self.estLancee = False

        # Est-ce que le 1er % de progression a été récupéré (utile pour montage vidéo -> découper)?
        self.__recupPourcentDebut = 0

        # Pour le son lors de la découpe vidéo pour l'instant
        if optionSpeciale!=None:
            self.optionSpeciale = optionSpeciale

        self.resize(500, 100)

        #=== Widgets ===#

        self.labelAttente=QLabel()
        self.labelAttente.setText(_(u"Attendez la fin du calcul s'il vous plaît, soyez patient !"))

        self.zoneTexte = QTextEdit("") # là où s'afficheront les infos
        if PYQT_VERSION_STR < "4.1.0":
            self.zoneTexte.setText = self.zoneTexte.setPlainText
        self.zoneTexte.setReadOnly(True)
        self.zoneTexte.setText("#######\n# LOG :\n#######\n")
        self.zoneTexte.hide()

        self.bout_annuler = QPushButton(_(u"Annuler"))

        self.bout_preZoneTexte = QPushButton(_("Voir les informations de l'encodage"))
        self.bout_preZoneTexte.hide()

        self.pbar = QProgressBar()
        self.pbar.setMaximum(100)

        vbox = QVBoxLayout()
        vbox.addWidget(self.labelAttente)
        vbox.addWidget(self.bout_preZoneTexte)
        vbox.addWidget(self.zoneTexte)
        hbox = QHBoxLayout()
        hbox.addWidget(self.pbar)
        hbox.addWidget(self.bout_annuler)
        vbox.addLayout(hbox)
        self.setLayout(vbox)

        self.ffmpegProcess = FFmpeg(inputfile = unicode(self.cheminVideoEntre), outputfile = unicode(self.cheminSorti), codec = self.idCodec, imgsize = self.tailleIm, videosize = self.tailleVideo)

        #=== connexion des widgets à des fonctions ===#
        self.connect(self.ffmpegProcess, SIGNAL('progress(int)'), self.pbar.setValue)
        self.connect(self.ffmpegProcess, SIGNAL('log(QString)'), self.zoneTexte.append)
        self.connect(self.ffmpegProcess, SIGNAL('finished(int)'), self.finEncodage)
        self.connect(self.bout_annuler, SIGNAL('clicked()'), self.close)
        self.connect(self.bout_preZoneTexte, SIGNAL('clicked()'), self.afficherLog)

        ## On sort cette partie qui ne doit pas être lancée dans l'init de l'objet.
        # Uniquement FFmpeg
        #self.demarrerEncodeur('Ffmpeg')

    def setVideoLen(self, videoLen) :
        self.ffmpegProcess.setVideoLen(videoLen)

    def close(self):
        """ Annule le traitement en cours """
        self.ffmpegProcess.cancel()
        self.ffmpegProcess.wait()
        #super(WidgetFFmpeg, self).close() # Python 2.6
        QDialog.close(self)

    def exec_(self):
        """ Surcharge de la fonction exec permettant l'execution hors de l'init"""
        self.demarrerEncodeur('Ffmpeg')
        #super(WidgetFFmpeg, self).exec_() # Python 2.6
        QDialog.exec_(self)

    def demarrerEncodeur(self, encodeur):
        """démarrage de mencoder avec les arguments choisis"""

        if self.estLancee == False: # pas question de démarrer 2 fois l'encodage
            commande = None
            has_audio = False

            debug('\n')

            # Si la conversion d'images en vidéo est sélectionné, aucune
            # info Mplayer n'est affichée (problème de récup infos par Mplayer)
            if self.idCodec in ['mpeg1video', 'mjpeg', 'h263p', 'mpeg4', 'msmpeg4v2', 'ljpeg', 'dv', 'huffyuv', 'mov', 'flv', 'mp4', 'vob']:
                # ICI SI LES FICHIERS CHARGES SONT DES IMAGES
                a = "###############################"
                b = "# Informations sur les images :"
                c = "###############################"

                infos = '\n'+a+'\n'+b+'\n'+c+'\n'
                debug(infos)
                self.zoneTexte.append(infos)

                import glob
                # Le chemin pour l'affichage des infos sur les images ne fonctionnait
                # plus après la nouvelle structure des fichiers temporaires
                self.recupTempImgAnim = glob.glob(EkdConfig.getTempDir() + os.sep + "*.*")
                self.recupTempImgAnim.sort()
                # Affichage du chemin (temp) + le poids de chaque image
                # --> Une énumération de parcours a été introduite
                for parcNb, parcInfIm in enumerate(self.recupTempImgAnim):
                    debug('* '+str(parcNb+1)+'. '+parcInfIm+' --> '+str(float(os.path.getsize(parcInfIm)/1000))+' ko'+'\n')
                    self.zoneTexte.append('* '+str(parcNb+1)+'. '+parcInfIm+' --> '+str(float(os.path.getsize(parcInfIm)/1000))+' ko'+'\n')

                # Elimination de la dernière image de la liste car car elle
                # s'affiche en double ds la fenêtre information de l'encodage
                # et aussi ds la console
                #self.log = self.log[:len(self.log)-1]

                # On définie la longueur de la futur vidéo en divisant le nombre d'image par le
                # nombre d'image par seconde (valeurNum ici)
                self.ffmpegProcess.setVideoLen(len(self.recupTempImgAnim) / int(self.valeurNum))

            # Pour les traitements autres que la transformation des images en vidéo
            if self.idCodec not in ['mpeg1video', 'mjpeg', 'h263p', 'mpeg4', 'msmpeg4v2', 'ljpeg', 'dv', 'huffyuv', 'mov', 'flv', 'mp4', 'vob']:

                a = "########################"
                b = "# Informations MPlayer :"
                c = "########################"

                infos = '\n'+a+'\n'+b+'\n'+c+'\n'
                debug(infos)
                ######## Ajouté le 24/07/09 ##################################################################
                # Utilisation de la classe infovideo (et en particilier la fonction setVideo)
                # présents dans gui_modules_animation/infoVideo.py
                info = infovideo(self.cheminVideoEntre)

                id_filename = 'ID_FILENAME='+self.cheminVideoEntre+'\n'
                debug(id_filename)
                id_demuxer = 'ID_DEMUXER='+info.demux+'\n'
                debug(id_demuxer)
                id_video_format = 'ID_VIDEO_FORMAT='+info.videoFormat+'\n'
                debug(id_video_format)
                id_video_codec = 'ID_VIDEO_CODEC='+info.video_codec+'\n'
                debug(id_video_codec)
                id_video_bitrate = 'ID_VIDEO_BITRATE='+str(info.videoBitrate)+'\n'
                debug(id_video_bitrate)
                id_video_largeur = 'ID_VIDEO_WIDTH='+str(info.videoLargeur)+'\n'
                debug(id_video_largeur)
                id_video_hauteur = 'ID_VIDEO_HEIGHT='+str(info.videoHauteur)+'\n'
                debug(id_video_hauteur)
                id_img_par_sec = 'ID_VIDEO_FPS='+str(info.imgParSec)+'\n'
                debug(id_img_par_sec)
                ##### Donnée très importante pour la suite du calcul (pour ffmpeg.py et ffmpeg2theora) ####
                self.dureeTotaleVideo = float(info.dureeTotaleVideo)
                ###########################################################################################
                id_duree_totale_video = 'ID_LENGTH='+str(info.dureeTotaleVideo)+'\n'
                debug(id_duree_totale_video)
                id_audio_codec = 'ID_AUDIO_CODEC='+info.audioCodec+'\n'
                debug(id_audio_codec)
                id_audio_rate = 'ID_AUDIO_RATE='+str(info.audioRate)+'\n'
                debug(id_audio_rate)
                id_audio_bitrate = 'ID_AUDIO_BITRATE='+str(info.audioBitrate)+'\n'
                debug(id_audio_bitrate)

                self.zoneTexte.append(infos+id_filename+id_demuxer+id_video_format+id_video_codec+id_video_bitrate+id_video_largeur+id_video_hauteur+id_img_par_sec+id_duree_totale_video+id_audio_codec+id_audio_rate+id_audio_bitrate)
                ##############################################################################################
                ## On définie la longueur de la vidéo pour le process
                self.ffmpegProcess.setVideoLen(self.dureeTotaleVideo)

                if info.audioCodec :
                    has_audio = True

            debug('\n')

            a = "############################"
            b = "# Informations %s :" %encodeur
            c = "############################"


            infos = '\n'+a+'\n'+b+'\n'+c+'\n'
            debug(infos)
            self.zoneTexte.append(infos)

            if self.idCodec=='codec_dv_ffmpeg':
                self.ffmpegProcess.commandeFfmpegEncodageDv()
	    elif self.idCodec=='codec_mov_ffmpeg':
		#### Enlevé le 09/04/11 ##############################
		#self.ffmpegProcess.commandeFfmpegEncodageMov()
		######################################################
		#### Ajouté/rectifié le 09/04/11 #####################
                self.ffmpegProcess.commandeFfmpegEncodageMov(comp = self.valeurNum[0], size = self.valeurNum[1])
		######################################################
	    elif self.idCodec=='codec_hfyu_ffmpeg':
		#### Enlevé le 10/04/11 ##############################
                #self.ffmpegProcess.commandeFfmpegEncodageHfyu(audio = has_audio)
		######################################################
		#### Ajouté/rectifié le 10/04/11 #####################
                self.ffmpegProcess.commandeFfmpegEncodageHfyu(size = self.valeurNum, audio = has_audio)
		######################################################
            elif self.idCodec=='codec_vob_ffmpeg':
                self.ffmpegProcess.commandeFfmpegEncodageVob(vquantizer = self.valeurNum)
            elif self.idCodec=='codec_3GP_ffmpeg':
		#### Enlevé le 30/03/11 ##############################
                #self.ffmpegProcess.commandeFfmpegEncodage3gp(audio = has_audio)
		#### Ajouté/rectifié le 30/03/11 #####################
		self.ffmpegProcess.commandeFfmpegEncodage3gp(size = self.valeurNum)
		######################################################
            elif self.idCodec=='codec_AMV_ffmpeg':
		#### Rectifié le 30/03/11 ## Ajout de size ###########
                self.ffmpegProcess.commandeFfmpegEncodageAMV(size = self.valeurNum)
		######################################################
            elif self.idCodec=='idx':
                self.ffmpegProcess.commandeFfmpegNbrImgSec(rate = self.valeurNum)
            elif self.idCodec in ['mpeg1video', 'mjpeg', 'h263p', 'mpeg4', 'msmpeg4v2', 'ljpeg', 'dv', 'huffyuv', 'mov', 'flv', 'mp4', 'vob']:
                self.ffmpegProcess.commandeFfmpegConvertImg(rate = self.valeurNum, size = "%sx%s" % (self.tailleIm[0], self.tailleIm[1]), vcodec = self.idCodec)

	    # --------------------------------------------------------------------------------- #
	    # Traitement pour chaque entrée concernant la HD (classique, en dehors du codec Avid DNxHD)
	    # --------------------------------------------------------------------------------- #
            elif self.idCodec in ['hd_1920x1080_mov__pcm_s16be__16/9', 'hd_1280x720_mov__pcm_s16be__16/9', 'hd_1440x1080_mov__pcm_s16be__4/3']:
                ## FIXME : La taille est récupérée du nom de idCodec (crade)
                self.ffmpegProcess.commandeFfmpegConvHD(size = self.idCodec.split("_")[1])

	    ### Ajouté le 19/08/10 (Gestion du codec Avid DNxHD) ################################
	    # --------------------------------------------------------------------------------- #
	    # Traitement pour chaque entrée (24) concernant le codec Avid DNxHD pour la HD
	    # --------------------------------------------------------------------------------- #
            elif self.idCodec=='hd_dnxhd_1920x1080_29.97_220_mbs':
                ## FIXME : Les éléments utiles sont récupérés du nom de idCodec (crade mais utile)
                self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 1
	    elif self.idCodec=='hd_dnxhd_1920x1080_29.97_145_mbs':
                self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 2
	    elif self.idCodec=='hd_dnxhd_1920x1080_25_185_mbs':
                self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 3
	    elif self.idCodec=='hd_dnxhd_1920x1080_25_120_mbs':
                self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 4
	    elif self.idCodec=='hd_dnxhd_1920x1080_25_36_mbs':
                self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 5
	    elif self.idCodec=='hd_dnxhd_1920x1080_24_175_mbs':
                self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 6
	    elif self.idCodec=='hd_dnxhd_1920x1080_24_115_mbs':
                self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 7
	    elif self.idCodec=='hd_dnxhd_1920x1080_24_36_mbs':
                self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 8
	    elif self.idCodec=='hd_dnxhd_1920x1080_23.976_175_mbs':
                self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 9
	    elif self.idCodec=='hd_dnxhd_1920x1080_23.976_115_mbs':
                self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 10
	    elif self.idCodec=='hd_dnxhd_1920x1080_23.976_36_mbs':
                self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 11
	    elif self.idCodec=='hd_dnxhd_1920x1080_29.97_220_mbs':
                self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 12
	    elif self.idCodec=='hd_dnxhd_1920x1080_29.97_145_mbs':
                self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 13
	    elif self.idCodec=='hd_dnxhd_1920x1080_29.97_45_mbs':
                self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 14
	    elif self.idCodec=='hd_dnxhd_1280x720_59.94_220_mbs':
                self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 15
	    elif self.idCodec=='hd_dnxhd_1280x720_59.94_145_mbs':
                self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 16
	    elif self.idCodec=='hd_dnxhd_1280x720_50_175_mbs':
                self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 17
	    elif self.idCodec=='hd_dnxhd_1280x720_50_115_mbs':
                self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 18
	    elif self.idCodec=='hd_dnxhd_1280x720_29.97_110_mbs':
                self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 19
	    elif self.idCodec=='hd_dnxhd_1280x720_29.97_75_mbs':
                self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 20
	    elif self.idCodec=='hd_dnxhd_1280x720_25_90_mbs':
                self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 21
	    elif self.idCodec=='hd_dnxhd_1280x720_25_60_mbs':
                self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 22
	    elif self.idCodec=='hd_dnxhd_1280x720_23.976_90_mbs':
                self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 23
	    elif self.idCodec=='hd_dnxhd_1280x720_23.976_60_mbs':
                self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 24     
		#################################################################################

            elif self.idCodec=='jpeg': # convertir animation en images
                self.ffmpegProcess.commandeFfmpegConvAnimImg()
            elif self.idCodec=='extractionaudio':
                self.ffmpegProcess.commandeFfmpegSeparation()
            elif self.idCodec=='encodage_wav': # encodage de fichiers audio en wav
                self.ffmpegProcess.commandeFfmpegEncodageWav()
            elif self.idCodec=='conv_en_16_9_ou_4_3': # Convertir vidéo en 16/9 ou 4/3
                self.ffmpegProcess.commandeFfmpegConv_16_9_ou_4_3(
                            ext = os.path.splitext(self.cheminVideoEntre)[1],
                            size = "%sx%s" % (self.tailleVideo[0], self.tailleVideo[1]),
                            aspect = self.valeurNum,
                            audio = has_audio)

            # Remonté d'un niveau pour simplifier le code et éviter les répetitions
            if commande == None:
                commande = self.ffmpegProcess.command
            else :
                self.ffmpegProcess.command = commande

            debug(commande)
            self.zoneTexte.append(commande+'\n\n')
            self.ffmpegProcess.start()
            debug(u"Commande lancée")
            self.estLancee = True



    def finEncodage(self, statutDeSortie):
        """choses à faire à la fin de l'encodage de la vidéo"""

        # fermer la fenêtre à la fin de l'encodage
        if not self.laisserOuvert:
            self.close()

        debug("fini!")
        self.labelAttente.hide()
        self.pbar.setValue(100)
        # l'encodage est fini. Il ne peut plus être annulé. La
        # seule action possible devient ainsi la fermeture
        self.bout_annuler.setText(_(u"Fermer"))
        if statutDeSortie != 0 :
            self.bout_annuler.setText(_(u"Crash"))
        self.bout_preZoneTexte.show()
        self.emit(SIGNAL("finEncodage"))


    def afficherLog(self):
        """afficher les information de la vidéo de départ et de l'encodage"""
        self.zoneTexte.setText(self.ffmpegProcess.log)
        self.zoneTexte.show()
        self.resize(500, 300)
Beispiel #30
0
class PylintViewer( QWidget ):
    " Pylint tab widget "

    # Limits to colorize the final score
    BadLimit = 8.5
    GoodLimit = 9.5

    # Options of providing a report
    SingleFile     = 0
    DirectoryFiles = 1
    ProjectFiles   = 2
    SingleBuffer   = 3

    updatePylintTooltip = pyqtSignal( str )

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

        self.__reportUUID = ""
        self.__reportFileName = ""
        self.__reportOption = -1
        self.__reportShown = False
        self.__report = None

        self.__widgets = []

        # Prepare members for reuse
        if GlobalData().pylintAvailable:
            self.__noneLabel = QLabel( "\nNo results available" )
        else:
            self.__noneLabel = QLabel( "\nPylint is not available" )
        self.__noneLabel.setAutoFillBackground( True )
        noneLabelPalette = self.__noneLabel.palette()
        noneLabelPalette.setColor( QPalette.Background,
                                   GlobalData().skin.nolexerPaper )
        self.__noneLabel.setPalette( noneLabelPalette )

        self.__noneLabel.setFrameShape( QFrame.StyledPanel )
        self.__noneLabel.setAlignment( Qt.AlignHCenter )
        self.__headerFont = self.__noneLabel.font()
        self.__headerFont.setPointSize( self.__headerFont.pointSize() + 4 )
        self.__noneLabel.setFont( self.__headerFont )

        self.__createLayout( parent )

        self.__updateButtonsStatus()
        self.resizeEvent()
        return

    def __createLayout( self, parent ):
        " Creates the toolbar and layout "

        # Buttons
        self.printButton = QAction( PixmapCache().getIcon( 'printer.png' ),
                                    'Print', self )
        #printButton.setShortcut( 'Ctrl+' )
        self.printButton.triggered.connect( self.__onPrint )
        self.printButton.setVisible( False )

        self.printPreviewButton = QAction(
                PixmapCache().getIcon( 'printpreview.png' ),
                'Print preview', self )
        #printPreviewButton.setShortcut( 'Ctrl+' )
        self.printPreviewButton.triggered.connect( self.__onPrintPreview )
        self.printPreviewButton.setVisible( False )

        spacer = QWidget()
        spacer.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Expanding )

        self.clearButton = QAction(
            PixmapCache().getIcon( 'trash.png' ),
            'Clear', self )
        self.clearButton.triggered.connect( self.__clear )

        # The toolbar
        self.toolbar = QToolBar( self )
        self.toolbar.setOrientation( Qt.Vertical )
        self.toolbar.setMovable( False )
        self.toolbar.setAllowedAreas( Qt.RightToolBarArea )
        self.toolbar.setIconSize( QSize( 16, 16 ) )
        self.toolbar.setFixedWidth( 28 )
        self.toolbar.setContentsMargins( 0, 0, 0, 0 )

        self.toolbar.addAction( self.printPreviewButton )
        self.toolbar.addAction( self.printButton )
        self.toolbar.addWidget( spacer )
        self.toolbar.addAction( self.clearButton )

        self.__vLayout = QVBoxLayout()
        self.__vLayout.setContentsMargins( 5, 5, 5, 5 )
        self.__vLayout.setSpacing( 0 )
        self.__vLayout.setSizeConstraint( QLayout.SetFixedSize )

        self.__bodyFrame = QFrame( self )
#        self.__bodyFrame.setFrameShape( QFrame.StyledPanel )
        self.__bodyFrame.setFrameShape( QFrame.NoFrame )

#        self.__bodyFrame.setSizePolicy( QSizePolicy.Maximum,
#                                        QSizePolicy.Expanding )
        self.__bodyFrame.setLayout( self.__vLayout )
        self.bodyWidget = QScrollArea( self )
        self.bodyWidget.setFocusPolicy( Qt.NoFocus )
        self.bodyWidget.setWidget( self.__bodyFrame )
        self.bodyWidget.hide()

        self.__hLayout = QHBoxLayout()
        self.__hLayout.setContentsMargins( 0, 0, 0, 0 )
        self.__hLayout.setSpacing( 0 )
        self.__hLayout.addWidget( self.toolbar )
        self.__hLayout.addWidget( self.__noneLabel )
        self.__hLayout.addWidget( self.bodyWidget )

        self.setLayout( self.__hLayout )
        return

    def __updateButtonsStatus( self ):
        " Updates the buttons status "
        self.printButton.setEnabled( self.__reportShown )
        self.printPreviewButton.setEnabled( self.__reportShown )
        self.clearButton.setEnabled( self.__reportShown )
        return

    def __onPrint( self ):
        " Triggered when the print button is pressed "
        pass

    def __onPrintPreview( self ):
        " triggered when the print preview button is pressed "
        pass

    def setFocus( self ):
        " Overridden setFocus "
        self.__vLayout.setFocus()
        return

    def __clear( self ):
        " Clears the content of the vertical layout "
        if not self.__reportShown:
            return

        self.__removeAll()
        self.bodyWidget.hide()
        self.__noneLabel.show()

        self.__report = None
        self.__reportShown = False
        self.__updateButtonsStatus()
        self.resizeEvent()

        self.__updateTooltip()
        return

    def __removeAll( self ):
        " Removes all the items from the report "
        for item in self.__widgets:
            item.hide()
            self.__vLayout.removeWidget( item )
            del item

        self.__widgets = []
        return

    def __createScoreLabel( self, score, previousScore,
                            showFileName, fileName ):
        " Creates the score label "

        txt = "Score: " + str( score )
        if previousScore != "":
            txt += " / Previous score: " + str( previousScore )
        if not showFileName:
            txt += " for " + os.path.basename( fileName )

        scoreLabel = QLabel( txt )
        scoreLabel.setFrameShape( QFrame.StyledPanel )
        scoreLabel.setFont( self.__headerFont )
        scoreLabel.setAutoFillBackground( True )
        palette = scoreLabel.palette()

        if score < self.BadLimit:
            palette.setColor( QPalette.Background, QColor( 255, 127, 127 ) )
            palette.setColor( QPalette.Foreground, QColor( 0, 0, 0 ) )
        elif score > self.GoodLimit:
            palette.setColor( QPalette.Background, QColor( 220, 255, 220 ) )
            palette.setColor( QPalette.Foreground, QColor( 0, 0, 0 ) )
        else:
            palette.setColor( QPalette.Background, QColor( 255, 255, 127 ) )
            palette.setColor( QPalette.Foreground, QColor( 0, 0, 0 ) )

        scoreLabel.setPalette( palette )
        return scoreLabel

    @staticmethod
    def __setTableHeight( table ):
        " Auxiliary function to set the table height "

        # Height - it is ugly and approximate however I am tired of
        # calculating the proper height. Why is this so hard, huh?
        lastRowHeight = table.itemDelegate().lastHeight
        height = lastRowHeight * ( table.topLevelItemCount() + 1 ) + 10
        table.setFixedHeight( height )
        return

    @staticmethod
    def __shouldShowFileName( messages ):
        " Decides if the file name column should be supressed "
        if len( messages ) == 0:
            return False
        firstName = messages[ 0 ].fileName
        for index in range( 1, len( messages ) ):
            if firstName != messages[ index ].fileName:
                return True
        return False

    def __addErrorsTable( self, messages, showFileName ):
        " Creates the messages table "

        errTable = QTreeWidget( self.bodyWidget )
        errTable.setAlternatingRowColors( True )
        errTable.setRootIsDecorated( False )
        errTable.setItemsExpandable( False )
        errTable.setSortingEnabled( True )
        errTable.setItemDelegate( NoOutlineHeightDelegate( 4 ) )
        errTable.setUniformRowHeights( True )
        errTable.itemActivated.connect( self.__errorActivated )

        headerLabels = [ "File name", "Line", "Message ID", "Object", "Message" ]
        errTable.setHeaderLabels( headerLabels )

        for item in messages:
            if item.position is None:
                lineNumber = str( item.lineNumber )
            else:
                lineNumber = str( item.lineNumber ) + ":" + str( item.position )
            values = [ item.fileName, lineNumber, item.messageID,
                       item.objectName, item.message ]
            errTable.addTopLevelItem( ErrorTableItem( values, 1 ) )

        # Hide the file name column if required
        if not showFileName:
            errTable.setColumnHidden( 0, True )

        # Resizing
        errTable.header().resizeSections( QHeaderView.ResizeToContents )
        errTable.header().setStretchLastSection( True )

        # Sort indicator
        if showFileName:
            sortIndex = 0   # By file names
        else:
            sortIndex = 1   # By line number because this is from the same file
        errTable.header().setSortIndicator( sortIndex, Qt.AscendingOrder )
        errTable.sortItems( sortIndex, errTable.header().sortIndicatorOrder() )

        # Height
        self.__setTableHeight( errTable )

        self.__vLayout.addWidget( errTable )
        self.__widgets.append( errTable )
        return

    def __addSimilarity( self, similarity, titleText ):
        " Adds a similarity "

        # Label
        title = QLabel( titleText )
        title.setFont( self.__headerFont )

        self.__vLayout.addWidget( title )
        self.__widgets.append( title )

        # List of files
        simTable = QTreeWidget( self.bodyWidget )
        simTable.setAlternatingRowColors( True )
        simTable.setRootIsDecorated( False )
        simTable.setItemsExpandable( False )
        simTable.setSortingEnabled( False )
        simTable.setItemDelegate( NoOutlineHeightDelegate( 4 ) )
        simTable.setUniformRowHeights( True )
        simTable.itemActivated.connect( self.__similarityActivated )
        simTable.setHeaderLabels( [ "File name", "Line" ] )

        for item in similarity.files:
            values = [ item[ 0 ], str( item[ 1 ] ) ]
            simTable.addTopLevelItem( QTreeWidgetItem( values )  )

        # Resizing
        simTable.header().resizeSections( QHeaderView.ResizeToContents )
        simTable.header().setStretchLastSection( True )

        # Height
        self.__setTableHeight( simTable )

        self.__vLayout.addWidget( simTable )
        self.__widgets.append( simTable )

        # The fragment itself
        if len( similarity.fragment ) > 10:
            # Take first 9 lines
            text = "\n".join( similarity.fragment[ : 9 ] ) + "\n ..."
            toolTip = "\n".join( similarity.fragment )
        else:
            text = "\n".join( similarity.fragment )
            toolTip = ""
        fragmentLabel = QLabel( "<pre>" + self.__htmlEncode( text ) + "</pre>" )
        if toolTip != "":
            fragmentLabel.setToolTip( "<pre>" + self.__htmlEncode( toolTip ) +
                                      "</pre>" )
        palette = fragmentLabel.palette()
        palette.setColor( QPalette.Background, QColor( 250, 250, 175 ) )
        palette.setColor( QPalette.Foreground, QColor( 0, 0, 0 ) )
        fragmentLabel.setPalette( palette )
        fragmentLabel.setFrameShape( QFrame.StyledPanel )
        fragmentLabel.setAutoFillBackground( True )

        labelFont = fragmentLabel.font()
        labelFont.setFamily( GlobalData().skin.baseMonoFontFace )
        fragmentLabel.setFont( labelFont )

        self.__vLayout.addWidget( fragmentLabel )
        self.__widgets.append( fragmentLabel )
        return

    @staticmethod
    def __htmlEncode( string ):
        " Encodes HTML "
        return string.replace( "&", "&amp;" ) \
                     .replace( ">", "&gt;" ) \
                     .replace( "<", "&lt;" )

    def __addSectionSpacer( self ):
        " Adds a fixed height spacer to the VBox layout "
        spacer = QWidget()
        spacer.setFixedHeight( 10 )
        self.__vLayout.addWidget( spacer )
        self.__widgets.append( spacer )
        return

    def __addGenericTable( self, table ):
        " Adds a generic table to the report "

        theTable = QTreeWidget( self.bodyWidget )
        theTable.setAlternatingRowColors( True )
        theTable.setRootIsDecorated( False )
        theTable.setItemsExpandable( False )
        theTable.setSortingEnabled( False )
        theTable.setItemDelegate( NoOutlineHeightDelegate( 4 ) )
        theTable.setUniformRowHeights( True )

        headerLabels = []
        for index in range( 0, len( table.header ) ):
            headerLabels.append( table.header[ index ] )
        theTable.setHeaderLabels( headerLabels )

        for item in table.body:
            row = []
            for index in range( 0, len( table.header ) ):
                row.append( item[ index ] )
            theTable.addTopLevelItem( QTreeWidgetItem( row ) )

        theTable.setFocusPolicy( Qt.NoFocus )

        # Resizing
        theTable.header().resizeSections( QHeaderView.ResizeToContents )
        theTable.header().setStretchLastSection( True )

        # Height
        self.__setTableHeight( theTable )

        self.__vLayout.addWidget( theTable )
        self.__widgets.append( theTable )
        return

    def __addGenericTableTitle( self, table ):
        " Adds a generic table title "
        tableTitle = QLabel( table.title )
        tableTitle.setFont( self.__headerFont )

        self.__vLayout.addWidget( tableTitle )
        self.__widgets.append( tableTitle )
        return

    def __updateTooltip( self ):
        " Generates a signal with appropriate string message "
        if not self.__reportShown:
            tooltip = "No results available"
        elif self.__reportOption == self.DirectoryFiles:
            tooltip = "Report generated for directory: " + \
                      self.__reportFileName
        elif self.__reportOption == self.ProjectFiles:
            tooltip = "Report generated for the whole project"
        elif self.__reportOption == self.SingleFile:
            tooltip = "Report generated for file: " + self.__reportFileName
        elif self.__reportOption == self.SingleBuffer:
            tooltip = "Report generated for unsaved file: " + \
                      self.__reportFileName
        else:
            tooltip = ""
        self.updatePylintTooltip.emit( tooltip )
        return

    def showReport( self, lint, reportOption, fileName, uuid ):
        " Shows the pylint results "
        self.__removeAll()
        self.__noneLabel.hide()

        self.__report = lint
        self.__reportUUID = uuid
        self.__reportFileName = fileName
        self.__reportOption = reportOption

        showFileName = self.__shouldShowFileName( lint.errorMessages )

        scoreLabel = self.__createScoreLabel( lint.score, lint.previousScore,
                                              showFileName, fileName )
        self.__vLayout.addWidget( scoreLabel )
        self.__widgets.append( scoreLabel )

        if len( lint.errorMessages ) > 0:
            self.__addSectionSpacer()
            self.__addErrorsTable( lint.errorMessages, showFileName )

        index = 0
        for similarity in lint.similarities:
            self.__addSectionSpacer()
            self.__addSimilarity( similarity, "Similarity #" + str( index ) )
            index += 1

        for table in lint.tables:
            self.__addSectionSpacer()
            self.__addGenericTableTitle( table )
            self.__addGenericTable( table )

        self.bodyWidget.show()
        self.bodyWidget.ensureVisible( 0, 0, 0, 0 )
        self.__reportShown = True
        self.__updateButtonsStatus()
        self.__updateTooltip()

        # It helps, but why do I have flickering?
        QApplication.processEvents()
        self.__resizeBodyFrame()
        return

    def __errorActivated( self, item, column ):
        " Handles the double click (or Enter) on the item "

        linePos = str( item.text( 1 ) )
        if ":" in linePos:
            parts = linePos.split( ":" )
            lineNumber = int( parts[ 0 ] )
            pos = int( parts[ 1 ] )
        else:
            lineNumber = int( linePos )
            pos = 0

        if self.__reportOption in [ self.SingleFile, self.DirectoryFiles,
                                    self.ProjectFiles ]:
            fileName = str( item.text( 0 ) )
        else:
            # SingleBuffer
            if self.__reportFileName != "":
                if os.path.isabs( self.__reportFileName ):
                    fileName = self.__reportFileName
                else:
                    # Could be unsaved buffer, so try to search by the
                    mainWindow = GlobalData().mainWindow
                    widget = mainWindow.getWidgetByUUID( self.__reportUUID )
                    if widget is None:
                        logging.error( "The unsaved buffer has been closed" )
                        return
                    # The widget was found, so jump to the required
                    editor = widget.getEditor()
                    editor.gotoLine( lineNumber, pos )
                    editor.setFocus()
                    return

        GlobalData().mainWindow.openFile( fileName, lineNumber, pos )
        return

    def __resizeBodyFrame( self ):
        " Resizing the frame to occupy all available width "
        size = self.bodyWidget.maximumViewportSize()
        self.__bodyFrame.setMinimumWidth( size.width() - 16 )
        self.__bodyFrame.setMinimumHeight( size.height() )
        return

    def showEvent( self, showEv = None ):
        " Called when the widget is shown "
        self.__resizeBodyFrame()
        return

    def resizeEvent( self, resizeEv = None ):
        " Called when the main window gets resized "
        self.__resizeBodyFrame()
        return

    def onFileUpdated( self, fileName, uuid ):
        " Called when a buffer is saved or saved as "

        if not self.__reportShown:
            return
        if self.__reportUUID != uuid:
            return

        # Currently shown report is for the saved buffer
        # File name is expected being absolute
        self.__reportFileName = fileName
        self.updatePylintTooltip.emit( "Report generated for buffer saved as " +
                                       fileName )
        return

    def __similarityActivated( self, item, column ):
        " Triggered when a similarity is activated "
        fileName = str( item.text( 0 ) )
        lineNumber = int( item.text( 1 ) )
        GlobalData().mainWindow.openFile( fileName, lineNumber )
        return
Beispiel #31
0
class WRepositories(QWidget, Logger.ClassLogger):
    """
    Repositories widget
    """
    def __init__(self, parent=None):
        """
        Constructs WRepositories widget

        @param parent: 
        @type parent:
        """
        QWidget.__init__(self, parent)

        self.localRepoPath = Settings.instance().readValue(
            key='Repositories/local-repo')
        self.localRepository = None
        self.localSaveOpen = None
        self.remoteRepository = None
        self.adaptersRemoteRepository = None

        self.createWidgets()
        self.createConnections()
        self.onResetRemote()

    def localRepoIsPresent(self):
        """
        The local repository is configured ?
        """
        if self.localRepoPath != "Undefined":
            if not os.path.exists(self.localRepoPath):
                self.localConfigured = "Undefined"
                self.testsTab.setTabEnabled(TAB_LOCAL_POS, False)
            else:
                self.localConfigured = self.localRepoPath
                self.testsTab.setTabEnabled(TAB_LOCAL_POS, True)
        else:
            self.localConfigured = self.localRepoPath
            self.testsTab.setTabEnabled(TAB_LOCAL_POS, False)

    def createWidgets(self):
        """
        Create qt widgets

        QTabWidget:
          ________  ________
         /        \/        \___________
        |                               |
        |                               |
        |                               |
        |_______________________________|
        """
        self.line = QFrame()
        self.line.setGeometry(QRect(110, 221, 51, 20))
        self.line.setFrameShape(QFrame.HLine)
        self.line.setFrameShadow(QFrame.Sunken)

        self.testsTab = QTabWidget()
        self.testsTab.setTabPosition(QTabWidget.North)
        self.testsTab.setStyleSheet(
            "QTabWidget { border: 0px; }")  # remove 3D border

        # local repo
        self.localConfigured = self.localRepoPath
        self.localRepository = LocalRepository.Repository(parent=self)
        self.localRepository.deactive()
        self.localRepoIsPresent()

        self.localSaveOpen = LocalRepository.SaveOpenToRepoDialog(parent=self)

        # remote repo
        self.remoteRepository = RemoteTests.Repository(parent=self,
                                                       projectSupport=True)
        if not RCI.instance().isAuthenticated():
            self.remoteRepository.setNotConnected()
            self.remoteRepository.setEnabled(False)

        # adapters remote repo
        self.adaptersRemoteRepository = RemoteAdapters.Repository(parent=self)
        if not RCI.instance().isAuthenticated():
            self.adaptersRemoteRepository.setNotConnected()
            self.adaptersRemoteRepository.setEnabled(False)

        # libraries adapters remote repo
        self.librariesRemoteRepository = RemoteLibraries.Repository(
            parent=self)
        if not RCI.instance().isAuthenticated():
            self.librariesRemoteRepository.setNotConnected()
            self.librariesRemoteRepository.setEnabled(False)

        self.testsTab.addTab(self.localRepository,
                             QIcon(":/repository-tests.png"),
                             self.tr("Local Tests"))
        self.testsTab.addTab(self.remoteRepository,
                             QIcon(":/repository-tests.png"),
                             self.tr("Remote Tests"))
        self.testsTab.setTabEnabled(TAB_LOCAL_POS, False)
        self.testsTab.setTabEnabled(TAB_REMOTE_POS, False)

        self.connectorsTab = QTabWidget()
        self.connectorsTab.setTabPosition(QTabWidget.North)
        self.connectorsTab.setStyleSheet(
            "QTabWidget { border: 0px; }")  # remove 3D border

        self.connectorsTab.addTab(self.adaptersRemoteRepository,
                                  QIcon(":/repository-adapters.png"),
                                  self.tr("Adapters"))
        self.connectorsTab.addTab(self.librariesRemoteRepository,
                                  QIcon(":/repository-libraries.png"),
                                  self.tr("Libraries"))
        self.connectorsTab.setTabEnabled(TAB_ADAPTER_POS, False)
        self.connectorsTab.setTabEnabled(TAB_LIBRARY_POS, False)

        self.title = QLabel(self.tr("Repositories"))
        font = QFont()
        font.setBold(True)
        self.title.setFont(font)

        self.labelHelp = QLabel(
            self.tr(
                "Drag and drop your selected file in the workspace to open it."
            ))
        self.labelHelp.setEnabled(False)
        font = QFont()
        font.setItalic(True)
        self.labelHelp.setFont(font)

        layout = QVBoxLayout()
        layout.addWidget(self.title)
        layout.addWidget(self.labelHelp)

        self.mainTab = QTabWidget()
        self.mainTab.setEnabled(False)
        self.mainTab.setTabPosition(QTabWidget.North)
        self.mainTab.setMinimumWidth(300)

        self.mainTab.addTab(self.testsTab, QIcon(":/test-description.png"),
                            "Tests Listing")
        self.mainTab.addTab(self.connectorsTab, QIcon(":/adapters.png"),
                            "Modules Listing")

        layout.addWidget(self.mainTab)
        layout.addWidget(self.line)

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

        # set the default tab
        defaultTab = Settings.instance().readValue(
            key='Repositories/default-repo-test')
        if int(defaultTab) == TAB_LOCAL_POS or int(
                defaultTab) == TAB_REMOTE_POS:
            self.mainTab.setCurrentIndex(MAIN_TAB_TEST)
            self.testsTab.setCurrentIndex(int(defaultTab))
        else:
            self.mainTab.setCurrentIndex(MAIN_TAB_DEV)
            self.connectorsTab.setCurrentIndex(int(defaultTab) - 2)

    def hideWidgetsHeader(self):
        """
        Hide the widget header
        """
        self.line.hide()
        self.title.hide()
        self.labelHelp.hide()

    def showWidgetsHeader(self):
        """
        Show the widget header
        """
        self.line.show()
        self.title.show()
        self.labelHelp.show()

    def createConnections(self):
        """
        Create qt connections
        """
        pass

    def initLocalRepo(self):
        """
        Initialize the local repository
        """
        if self.localConfigured != "Undefined":
            self.localRepository.active()

    def cleanLocalRepo(self):
        """
        Cleanup the local repository
        """
        self.localRepository.deactive()

    def local(self):
        """
        Returns the local repository widget

        @return: LocalRepository.Repository
        @rtype: QWidget
        """
        return self.localRepository

    def localDialogSave(self):
        """
        Return the save/open dialog
        """
        return self.localSaveOpen

    def remote(self):
        """
        Returns the remote repository widget

        @return: RemoteRepository.Repository
        @rtype: QWidget
        """
        return self.remoteRepository

    def remoteAdapter(self):
        """
        Returns the remote repository widget

        @return: RemoteRepository.Repository
        @rtype: QWidget
        """
        return self.adaptersRemoteRepository

    def remoteLibrary(self):
        """
        Returns the remote repository widget

        @return: RemoteRepository.Repository
        @rtype: QWidget
        """
        return self.librariesRemoteRepository

    def decodeData(self, b64data):
        """
        Decode data
        """
        data_json = ''
        try:
            data_decoded = base64.b64decode(b64data)
        except Exception as e:
            self.error('unable to decode from base64 structure: %s' % str(e))
        else:
            try:
                data_uncompressed = zlib.decompress(data_decoded)
            except Exception as e:
                self.error('unable to decompress: %s' % str(e))
            else:
                try:
                    if sys.version_info > (3, ):
                        data_json = json.loads(
                            data_uncompressed.decode('utf-8'))
                    else:
                        data_json = json.loads(data_uncompressed)
                except Exception as e:
                    self.error('unable to decode from json structure: %s' %
                               str(e))
        return data_json

    # functions for remote repository
    def onLoadRemote(self, data):
        """
        Called on load remote actions
        """
        self.mainTab.setEnabled(True)
        self.labelHelp.setEnabled(True)
        # if UCI.RIGHTS_TESTER in RCI.instance().userRights:
        # self.remoteRepository.setConnected()
        # self.remoteRepository.setEnabled(True)
        # self.localRepository.setEnabled(True)

        # self.testsTab.setTabEnabled( TAB_REMOTE_POS, True )
        # if self.localConfigured != "Undefined":
        # self.testsTab.setTabEnabled( TAB_LOCAL_POS, True )
        # else:
        # self.testsTab.setTabEnabled( TAB_LOCAL_POS, False )
        # self.connectorsTab.setTabEnabled( TAB_LIBRARY_POS, False )
        # self.connectorsTab.setTabEnabled( TAB_ADAPTER_POS, False )

        # defaultTab = Settings.instance().readValue( key = 'Repositories/default-repo-test' )
        # if int(defaultTab) == TAB_LOCAL_POS or int(defaultTab) == TAB_REMOTE_POS:
        # self.mainTab.setCurrentIndex(MAIN_TAB_TEST)
        # self.testsTab.setCurrentIndex(int(defaultTab))
        # else:
        # self.mainTab.setCurrentIndex(MAIN_TAB_DEV)
        # self.connectorsTab.setCurrentIndex(int(defaultTab)-2)

        # self.remoteRepository.defaultActions()
        # self.remoteRepository.initialize(listing= data['repo']  )
        # self.remoteRepository.initializeProjects( projects=data['projects'],
        # defaultProject=data['default-project'] )

        # if UCI.RIGHTS_TESTER in RCI.instance().userRights:
        # self.connectorsTab.setTabEnabled( TAB_ADAPTER_POS, True )
        # self.connectorsTab.setTabEnabled( TAB_LIBRARY_POS, True )

        # if UCI.RIGHTS_TESTER in RCI.instance().userRights: # exception if the developer if also a tester
        # defaultTab = Settings.instance().readValue( key = 'Repositories/default-repo-test' )
        # if int(defaultTab) == TAB_LOCAL_POS or int(defaultTab) == TAB_REMOTE_POS:
        # self.mainTab.setCurrentIndex(MAIN_TAB_TEST)
        # self.testsTab.setCurrentIndex(int(defaultTab))
        # else:
        # self.mainTab.setCurrentIndex(MAIN_TAB_DEV)
        # self.connectorsTab.setCurrentIndex(int(defaultTab)-2)
        # else:
        # defaultTab = Settings.instance().readValue( key = 'Repositories/default-repo-dev' )
        # if int(defaultTab) == TAB_LOCAL_POS or int(defaultTab) == TAB_REMOTE_POS:
        # self.mainTab.setCurrentIndex(MAIN_TAB_TEST)
        # self.testsTab.setCurrentIndex(int(defaultTab))
        # else:
        # self.mainTab.setCurrentIndex(MAIN_TAB_DEV)
        # self.connectorsTab.setCurrentIndex(int(defaultTab)-2)

        # self.adaptersRemoteRepository.setConnected()
        # self.adaptersRemoteRepository.setEnabled(True)
        # self.adaptersRemoteRepository.defaultActions()
        # self.adaptersRemoteRepository.initialize(listing=data['repo-adp'] )

        # self.librariesRemoteRepository.setConnected()
        # self.librariesRemoteRepository.setEnabled(True)
        # self.librariesRemoteRepository.defaultActions()
        # self.librariesRemoteRepository.initialize( listing=data['repo-lib-adp'] )

        # if UCI.RIGHTS_ADMIN in RCI.instance().userRights:
        self.remoteRepository.setConnected()
        self.remoteRepository.setEnabled(True)
        self.localRepository.setEnabled(True)

        self.testsTab.setTabEnabled(TAB_REMOTE_POS, True)
        if self.localConfigured != "Undefined":
            self.testsTab.setTabEnabled(TAB_LOCAL_POS, True)
        else:
            self.testsTab.setTabEnabled(TAB_LOCAL_POS, False)
        self.connectorsTab.setTabEnabled(TAB_ADAPTER_POS, True)
        self.connectorsTab.setTabEnabled(TAB_LIBRARY_POS, True)

        defaultTab = Settings.instance().readValue(
            key='Repositories/default-repo-test')
        if int(defaultTab) == TAB_LOCAL_POS or int(
                defaultTab) == TAB_REMOTE_POS:
            self.mainTab.setCurrentIndex(MAIN_TAB_TEST)
            self.testsTab.setCurrentIndex(int(defaultTab))
        else:
            self.mainTab.setCurrentIndex(MAIN_TAB_DEV)
            self.connectorsTab.setCurrentIndex(int(defaultTab) - 2)

        self.remoteRepository.defaultActions()
        if self.remoteRepository.initializeProjects(
                projects=data['projects'],
                defaultProject=data['default-project']):
            self.remoteRepository.initialize(listing=data['repo'])

        self.adaptersRemoteRepository.setConnected()
        self.adaptersRemoteRepository.setEnabled(True)
        self.adaptersRemoteRepository.defaultActions()
        self.adaptersRemoteRepository.initialize(listing=data['repo-adp'])

        self.librariesRemoteRepository.setConnected()
        self.librariesRemoteRepository.setEnabled(True)
        self.librariesRemoteRepository.defaultActions()
        self.librariesRemoteRepository.initialize(listing=data['repo-lib-adp'])

    def onResetRemote(self):
        """
        Called on reset remote actions
        """
        self.mainTab.setEnabled(False)
        self.labelHelp.setEnabled(False)

        self.remoteRepository.setNotConnected()
        self.remoteRepository.wrepository.clear()
        self.remoteRepository.setEnabled(False)
        self.localRepository.setEnabled(False)
        self.localRepository.defaultActions()

        self.adaptersRemoteRepository.setNotConnected()
        self.adaptersRemoteRepository.wrepository.clear()
        self.adaptersRemoteRepository.setEnabled(False)

        self.librariesRemoteRepository.setNotConnected()
        self.librariesRemoteRepository.wrepository.clear()
        self.librariesRemoteRepository.setEnabled(False)

        self.testsTab.setTabEnabled(TAB_REMOTE_POS, False)
        self.connectorsTab.setTabEnabled(TAB_ADAPTER_POS, False)
        self.testsTab.setTabEnabled(TAB_LOCAL_POS, False)
        self.connectorsTab.setTabEnabled(TAB_LIBRARY_POS, False)

        defaultTab = Settings.instance().readValue(
            key='Repositories/default-repo-test')
        if int(defaultTab) == TAB_LOCAL_POS or int(
                defaultTab) == TAB_REMOTE_POS:
            self.mainTab.setCurrentIndex(MAIN_TAB_TEST)
            self.testsTab.setCurrentIndex(int(defaultTab))
        else:
            self.mainTab.setCurrentIndex(MAIN_TAB_DEV)
            self.connectorsTab.setCurrentIndex(int(defaultTab) - 2)

    def onRefreshRemoteTests(self, data, projectId, forSaveAs=False):
        """
        """
        self.remoteRepository.defaultActions()

        if forSaveAs:
            self.remoteRepository.initializeSaveAs(listing=data,
                                                   reloadItems=True)
        else:
            # update default project
            projectName = self.remoteRepository.getProjectName(projectId)
            self.remoteRepository.setDefaultProject(projectName=projectName)

            # reconstruct
            self.remoteRepository.initialize(listing=data)

    def onRefreshRemoteAdapters(self, data):
        """
        """
        self.adaptersRemoteRepository.defaultActions()
        self.adaptersRemoteRepository.initialize(listing=data)

    def onRefreshRemoteLibraries(self, data):
        """
        """
        self.librariesRemoteRepository.defaultActions()
        self.librariesRemoteRepository.initialize(listing=data)
Beispiel #32
0
 def create_rows(self, layout):
     play_button_group = QButtonGroup(self)
     old_play_button_group = QButtonGroup(self)
     for num, (source, dest, text, dl_fname, dl_hash, extras, icon)\
             in enumerate(self.list, 3):
         tt_text = self.build_text_help_label(text, source, extras)
         ico_label = QLabel('', self)
         ico_label.setToolTip(tt_text)
         if icon:
             ico_label.setPixmap(QPixmap.fromImage(icon))
         layout.addWidget(ico_label, num, 0)
         tt_label = QLabel(text, self)
         tt_label.setToolTip(tt_text)
         layout.addWidget(tt_label, num, 1)
         if self.hide_text:
             tt_label.hide()
         # Play button.
         t_play_button = QPushButton(self)
         play_button_group.addButton(t_play_button, num - 3)
         t_play_button.setToolTip(self.play_help)
         t_play_button.setIcon(QIcon(os.path.join(icons_dir, 'play.png')))
         layout.addWidget(t_play_button, num, self.play_column)
         if self.note[dest]:
             t_play_old_button = QPushButton(self)
             old_play_button_group.addButton(t_play_old_button, num - 3)
             t_play_old_button.setIcon(
                 QIcon(os.path.join(icons_dir, 'play.png')))
             if not self.hide_text:
                 t_play_old_button.setToolTip(self.note[dest])
             else:
                 t_play_old_button.setToolTip(self.play_old_help_short)
             layout.addWidget(t_play_old_button, num, self.play_old_column)
         else:
             dummy_label = QLabel('', self)
             dummy_label.setToolTip(self.play_old_empty_line_help)
             layout.addWidget(dummy_label, num, self.play_old_column)
         # The group where we later look what to do:
         t_button_group = QButtonGroup(self)
         t_button_group.setExclusive(True)
         # Now the four buttons
         t_add_button = QPushButton(self)
         t_add_button.setCheckable(True)
         t_add_button.setChecked(True)
         t_add_button.setFlat(True)
         t_add_button.setToolTip(self.add_help_text_short)
         t_add_button.setIcon(QIcon(os.path.join(icons_dir, 'add.png')))
         layout.addWidget(t_add_button, num, self.add_column)
         t_button_group.addButton(t_add_button, action['add'])
         t_keep_button = QPushButton(self)
         t_keep_button.setCheckable(True)
         t_keep_button.setFlat(True)
         t_keep_button.setToolTip(self.keep_help_text_short)
         t_keep_button.setIcon(QIcon(os.path.join(icons_dir, 'keep.png')))
         layout.addWidget(t_keep_button, num, self.keep_column)
         t_button_group.addButton(t_keep_button,  action['keep'])
         t_delete_button = QPushButton(self)
         t_delete_button.setCheckable(True)
         t_delete_button.setFlat(True)
         t_delete_button.setToolTip(self.delete_help_text_short)
         t_delete_button.setIcon(QIcon(os.path.join(icons_dir,
                                                    'delete.png')))
         layout.addWidget(t_delete_button, num, self.delete_column)
         t_button_group.addButton(t_delete_button,  action['delete'])
         t_blacklist_button = QPushButton(self)
         t_blacklist_button.setCheckable(True)
         t_blacklist_button.setFlat(True)
         t_blacklist_button.setToolTip(self.blacklist_help_text_short)
         t_blacklist_button.setIcon(QIcon(os.path.join(icons_dir,
                                                       'blacklist.png')))
         if self.show_skull_and_bones:
             layout.addWidget(
                 t_blacklist_button, num, self.blacklist_column)
         else:
             t_blacklist_button.hide()
         t_button_group.addButton(t_blacklist_button,  action['blacklist'])
         self.buttons_groups.append(t_button_group)
     play_button_group.buttonClicked.connect(
         lambda button: play(self.list[play_button_group.id(button)][3]))
     old_play_button_group.buttonClicked.connect(
         lambda button: playFromText(
             self.note[self.list[old_play_button_group.id(button)][1]]))
Beispiel #33
0
class Metadata(QWidget):
  def __init__(self):
    QWidget.__init__(self)
    self.tabs = QTabWidget()
    self.nometa = QLabel("No EXIF metadata found")
    self.nometa.setAlignment(Qt.AlignCenter)
    self.box = QHBoxLayout()
    self.setLayout(self.box)
    self.box.addWidget(self.tabs)
    self.box.addWidget(self.nometa)
    self.nometa.hide()
    self.tabs.show()
    self.tabs.setTabPosition(QTabWidget.East)


  def process(self, node):
    for idx in xrange(0, self.tabs.count()):
      widget = self.tabs.widget(idx)
      del widget
    self.tabs.clear()
    self.node = node
    file = self.node.open()
    tags = EXIF.process_file(file)
    if len(tags) == 0:
      self.nometa.setSizePolicy(self.tabs.sizePolicy())
      self.tabs.hide()
      self.nometa.show()
    else:
      self.tabs.show()
      self.nometa.hide()
      sortedTags = {}
      for tag in tags.keys():
        if tag not in ('JPEGThumbnail', 'TIFFThumbnail', 'Filename', 'EXIF MakerNote'):
          spaceidx = tag.find(" ")
          ifd = tag[:spaceidx].strip()
          if ifd == "Image":
            ifd = "IFD 0 (Image)"
          if ifd == "Thumbnail":
            ifd = "IFD 1 (Thumbnail)"
          key = tag[spaceidx:].strip()
          try:
            val = str(tags[tag])
          except:
            val = "cannot be decoded"
          if ifd not in sortedTags.keys():
            sortedTags[ifd] = []
          sortedTags[ifd].append((key, val))
      for ifd in sortedTags.keys():
        table = QTableWidget(len(sortedTags[ifd]), 2)
        table.setShowGrid(False)
        table.setAlternatingRowColors(True)
        table.verticalHeader().hide()
        table.horizontalHeader().setClickable(False)
        table.horizontalHeader().setStretchLastSection(True)
        table.setHorizontalHeaderLabels(["Tag", "Value"])
        table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.tabs.addTab(table, ifd)
        row = 0
        for res in sortedTags[ifd]:
          key = QTableWidgetItem(res[0])
          key.setFlags(Qt.ItemIsSelectable|Qt.ItemIsEnabled)
          val = QTableWidgetItem(res[1])
          val.setFlags(Qt.ItemIsSelectable|Qt.ItemIsEnabled)
          table.setItem(row, 0, key)
          table.setItem(row, 1, val)
          row += 1
      if 'JPEGThumbnail' in tags.keys():
        label = QLabel()
        img = QImage()
        img.loadFromData(tags['JPEGThumbnail'])
        label.setPixmap(QPixmap.fromImage(img))
        label.setAlignment(Qt.AlignCenter)
        self.tabs.addTab(label, "Embedded Thumbnail")
      if 'TIFFThumbnail' in tags.keys():
        label = QLabel()
        img = QImage()
        img.loadFromData(tags['TIFFThumbnail'])
        label.setPixmap(QPixmap.fromImage(img))
        label.setAlignment(Qt.AlignCenter)
        self.tabs.addTab(label, "Embedded Thumbnail")
      file.close()	
Beispiel #34
0
class CreerSuite(MyMiniFrame):
    def __init__(self, parent):
        MyMiniFrame.__init__(self, parent, u"Représenter une suite")
        ##self.SetExtraStyle(wx.WS_EX_BLOCK_EVENTS )
        self.parent = parent
        self._param_ = self.parent._param_
        ##p = self.panel = QWidget(self)

        self.sizer = sizer = QVBoxLayout()
        sizer.addWidget(QLabel(u"Choisissez le mode de génération de la suite :"))
        self.mode = QComboBox()
        self.mode.addItems([u"u(n+1)=f(u(n))", u"u(n)=f(n)"])
        self.mode.setCurrentIndex(0)
        self.mode.currentIndexChanged.connect(self.EvtChoixMode)
        sizer.addWidget(self.mode)

        f = QHBoxLayout()
        f.addWidget(QLabel(u"Choisissez la fonction f :"))
        self.fonction = QComboBox()
        self.fonction.addItems(["Y" + str(i+1) for i in xrange(self.parent.nombre_courbes)])
        self.fonction.setCurrentIndex(0)
        self.fonction.currentIndexChanged.connect(self.EvtChoixFonction)
        f.addWidget(self.fonction)
        sizer.addLayout(f)

        start = QHBoxLayout()
        start.addWidget(QLabel(u"Commencer pour n ="))
        self.n0 = QSpinBox()
        self.n0.setRange(0, 1000000)
        self.n0.setValue(0)
        start.addWidget(self.n0)
        sizer.addLayout(start)

        terme = QHBoxLayout()
        self.label_init = QLabel(u"Terme initial :")
        terme.addWidget(self.label_init)
        self.un0 =  QLineEdit("1")
        self.un0.setMinimumWidth(100)
        terme.addWidget(self.un0)
        sizer.addLayout(terme)

        ligne = QFrame()
        ligne.setFrameStyle(QFrame.HLine|QFrame.Raised)
        ##sizer.addWidget(wx.StaticLine(p, -1, style=wx.LI_HORIZONTAL), 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)

        nbr = QHBoxLayout()
        nbr.addWidget(QLabel(u"Construire les"))
        self.termes = QSpinBox()
        self.termes.setRange(0, 100)
        self.termes.setValue(5)
        nbr.addWidget(self.termes)
        nbr.addWidget(QLabel(u"premiers termes."))
        sizer.addLayout(nbr)

        ligne = QFrame()
        ligne.setFrameStyle(QFrame.HLine|QFrame.Raised)

        sizer.addWidget(ligne)

        #p.SetSizer(sizer)
        boutons = QHBoxLayout()
        fermer = QPushButton(u"Fermer")
        boutons.addWidget(fermer)
        lancer = QPushButton(u"Créer")
        boutons.addWidget(lancer)
        fermer.clicked.connect(self.close)
        lancer.clicked.connect(self.Creer)
        sizer.addLayout(boutons)

        self.setLayout(sizer)
        ##self.SetClientSize(p.GetSize())





    def Creer(self):
##        self.parent.creer_feuille() # nouvelle feuille de travail
        # style des lignes :
        style, epaisseur = self._param_.style_suites_recurrentes
        kw_lignes = {"style": style, "epaisseur": epaisseur}

        # Les suites s'enregistrent auprès du module traceur
#        if not hasattr(self.parent, "suites"):
#            self.parent.suites = {}

        objets = self.parent.feuille_actuelle.objets
        i = self.fonction.currentIndex()
        nom_courbe = 'Cf' + str(i + 1)

        if objets.has_key(nom_courbe):
            courbe = objets[nom_courbe]
            fonction = courbe.fonction
        elif self.parent.boites[i].text():
            self.parent.valider(i=i)
            courbe = objets[nom_courbe]
            fonction = courbe.fonction
        else:
            # TODO: afficher un vrai message d'erreur
            raise KeyError,  "courbe inexistante : %s" %nom_courbe


        if self.mode.currentIndex() == 0: # cas des suites définies par récurrence
            u0 = eval_safe(self.un0.text())
            n0 = self.n0.value()

            d = objets.suiteDroited = Droite(Point(0, 0), Point(1, 1))
            d.label("$y\ =\ x$")
            M = objets.suitePointM0 = Point(u0, 0)
            M.label("$u_%s$" %(n0))
#            self.parent.suites["u"] = [d, M]

            for i in xrange(self.termes.value() - 1):
                # (Attention, ça ne va pas marcher pour les fonctions définies par morceau)
                u1 = fonction(u0)
                N = Point(u0, u1, visible=self._param_.afficher_points_de_construction)
                N.etiquette.visible = False
                s = Segment(M, N, **kw_lignes)
                P = Point(0, u1)
                P.label("$u_%s$" %(i + n0 + 1))
                t = Segment(N, P, **kw_lignes)
                Q = Point(u1, u1, visible = self._param_.afficher_points_de_construction)
                Q.etiquette.visible = False
                r = Segment(P, Q, **kw_lignes)
                M = Point(u1, 0)
                M.label("$u_%s$" %(i + n0 + 1))
                #self.parent.suites[u"u"].append([M, N, P, s, t])
                setattr(objets, "SuitePointN" + str(i), N)
                setattr(objets, "suitePointP" + str(i), P)
                setattr(objets, "suitePointQ" + str(i), Q)
                setattr(objets, "suiteSegments" + str(i), s)
                setattr(objets, "suiteSegmentt" + str(i), t)
                setattr(objets, "suiteSegmentr" + str(i), r)
                setattr(objets, "suitePointM" + str(i + 1), M)
                a = Segment(Q, M, **kw_lignes)
                setattr(objets, "suiteSegmenta" + str(i), a)
                u0 = u1
            self.parent.canvas.zoom_auto()

        else:   # suites définies explicitement
            n0 = self.n0.text()
#            self.parent.suites[u"u"] = []
            for i in xrange(n0, n0 + self.termes.text()):
                yi = fonction(i)
                M = Point(i, 0)
                M.label(str(i))
                N = Point(i, yi)
                N.etiquette.visible = False
                P = Point(0, yi)
                P.label("$u_%s$" %i)
                s = Segment(M, N, **kw_lignes)
                t = Segment(N, P, **kw_lignes)
                setattr(objets, "suitePointM" + str(i), M)
                setattr(objets, "suitePointN" + str(i), N)
                setattr(objets, "suitePointP" + str(i), P)
                setattr(objets, "suiteSegments" + str(i), s)
                setattr(objets, "suiteSegmentt" + str(i), t)
            self.parent.canvas.zoom_auto()



    def EvtChoixMode(self, index):
        if index == 1:
            self.label_init.hide()
            self.un0.hide()
        else:
            self.un0.show()
            self.label_init.show()


    def EvtChoixFonction(self, index):
        for i in xrange(self.parent.nombre_courbes):
            self.parent.boites[i].setChecked(i==index)
class ReactionProfile(QWidget):
    def __init__(self, reaction, readonly):
        super(ReactionProfile, self).__init__()
        self._painter = QPainter()
        self._canshowreaction = True
        self._IsReadOnly = readonly
        # Show labels checkbox widget
        self._showlabels = QCheckBox("Show data", self)
        self._showlabels.setChecked(False)
        self._showlabels.setGeometry(0, 0, 80, 20)
        self._showlabels.clicked.connect(self.update)
        # The buttons
        if self._IsReadOnly:
            self._CurrentReaction = copy.deepcopy(reaction)
        else:
            self._CurrentReaction = reaction
            self._rcolbtn = QPushButton("Set reactant colour", self)
            self._rcolbtn.setGeometry(140, 60, 110, 30)
            self._rcolbtn.clicked.connect(self.SetReactantColour)
            self._pcolbtn = QPushButton("Set product colour", self)
            self._pcolbtn.setGeometry(350, 60, 110, 30)
            self._pcolbtn.clicked.connect(self.SetProductColour)
            self._clonebtn = QPushButton("Compare reaction", self)
            self._clonebtn.setGeometry(10, 310, 120, 30)
            self._clonebtn.clicked.connect(self.Clone)
            self._concbtn = QPushButton("Concentration graphs", self)
            self._concbtn.setGeometry(10, 100, 120, 30)
            self._concbtn.clicked.connect(self.MakeConcGraphs)
            self._ratebtn = QPushButton("Rate graphs", self)
            self._ratebtn.setGeometry(10, 130, 120, 30)
            self._ratebtn.clicked.connect(self.MakeRateGraphs)
        self._getkcbtn = QPushButton("Calculate Kc", self)
        self._getkcbtn.setGeometry(10, 180, 120, 30)
        self._getkcbtn.clicked.connect(self.GetKc)
        self._workingbtn = QPushButton("Show working", self)
        self._workingbtn.setGeometry(10, 225, 120, 30)
        self._workingbtn.clicked.connect(self.ShowWorking)
        self._startanim = QPushButton("Start animation", self)
        self._startanim.setGeometry(10, 260, 120, 30)
        self._startanim.clicked.connect(self.StartAnimation)
        # The labels
        self._catalabel = QLabel("", self)
        self._catalabel.setGeometry(250, 60, 100, 40)
        self._catalabel.setAlignment(Qt.AlignCenter)
        self._kclabel = QLabel(self)
        self._kclabel.setGeometry(20, 205, 140, 20)
        self._volumelabel = QLabel(self)
        self._volumelabel.setGeometry(200, 317, 140, 20)
        # Set up reactant and product labels
        formulafont = QFont()
        formulafont.setBold(True)
        formulafont.setPointSize(12)
        self._rpalette = QPalette()
        self._ppalette = QPalette()
        self._reactantlabel = QLabel("", self)
        self._reactantlabel.setGeometry(0, 20, 268, 32)
        self._reactantlabel.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
        self._reactantlabel.setFont(formulafont)
        self._reactantlabel.setPalette(self._rpalette)
        self._reactantlabel.show()
        self._productlabel = QLabel("", self)
        self._productlabel.setGeometry(332, 20, 268, 32)
        self._productlabel.setAlignment(Qt.AlignVCenter)
        self._productlabel.setFont(formulafont)
        self._productlabel.setPalette(self._ppalette)
        self._productlabel.show()
        # Other properties
        self._Squares = []
        for x in range(100):
            self._Squares.append(Square(200+((x % 10) * 20), 120 + ((x // 10) * 20), self._CurrentReaction))
        self._timer = QTimer(self)
        self._timer.setInterval(30)
        self._timer.setSingleShot(False)
        self._timer.timeout.connect(self.ContinueAnimation)
        self._no_of_anim_updates = 0
        self._ExtraWindows = []
        self._kcdifference = ""
        self._rflipchance = 0
        self._pflipchance = 0
        self._graphs = None

    def paintEvent(self, e):
        reactantside = ""
        productside = ""
        for x in range(len(self._CurrentReaction.GetReactants())):
            reactant = self._CurrentReaction.GetReactants()[x]
            if reactant.GetUsed():
                if x > 0:
                    reactantside += " + "
                reactantside += reactant.GetFormulaForLabels()
        for x in range(len(self._CurrentReaction.GetProducts())):
            product = self._CurrentReaction.GetProducts()[x]
            if product.GetUsed():
                if x > 0:
                    productside += " + "
                productside += product.GetFormulaForLabels()
        self._rpalette.setColor(QPalette.WindowText, self._CurrentReaction.GetReactantColour())
        self._ppalette.setColor(QPalette.WindowText, self._CurrentReaction.GetProductColour())
        self._reactantlabel.setPalette(self._rpalette)
        self._productlabel.setPalette(self._ppalette)
        self._painter.begin(self)
        self._painter.setFont(QFont("Arial", 20, 50, False))
        self._painter.setPen(QPen(self._CurrentReaction.GetReactantColour()))
        if self._CurrentReaction.GetCatalyst().GetUsed():
            self._catalabel.setText("Catalyst: "+
                                    self._CurrentReaction.GetCatalyst().GetFormulaForLabels()+"<br>Moles: "+
                                    str(self._CurrentReaction.GetCatalyst().GetInitialMoles())+"<br>Strength: "+
                                    self._CurrentReaction.GetCatalyst().GetEfficacyAsString())
            self._catalabel.show()
        else:
            self._catalabel.hide()
        self._reactantlabel.setText(reactantside)
        self._productlabel.setText(productside)
        target = QRectF(278, 20, 44, 32)
        arrows = QPixmap("assets/double arrow h.png")
        portion = QRectF(10, 0, 44, 32)
        self._painter.drawPixmap(target, arrows, portion)
        self._painter.setPen(QPen(self._CurrentReaction.GetProductColour()))
        self._painter.setPen(QPen(QColor(0, 0, 0, 255)))
        self._painter.setFont(QFont("Arial", 8, 50, False))
        self._volumelabel.setText("Vessel volume: "+str(self._CurrentReaction.GetVolume())+" dm<sup>3</sup>")
        self._painter.drawText(200, 340, "Vessel temperature: "+str(self._CurrentReaction.GetTemperature())+" K")
        if self._CurrentReaction.GetEndothermic():
            self._painter.drawText(200, 350, "Reaction is endothermic")
        else:
            self._painter.drawText(200, 350, "Reaction is exothermic")
        if self._showlabels.isChecked():
            if self._kcdifference == "":
                self._kclabel.show()
            else:
                self._kclabel.hide()
            self._painter.drawText(420, 330, self._kcdifference)
        else:
            self._kclabel.hide()
        for x in self._Squares:
            x.Draw(self._painter)
        self._painter.end()

    def SetReaction(self, reaction):
        if self._IsReadOnly:
            self._CurrentReaction = copy.deepcopy(reaction)
        else:
            self._CurrentReaction = reaction
        self.update()

    def GetReaction(self):
        return self._CurrentReaction

    def MakeConcGraphs(self):
        gwg = GraphWindowGroup(GraphWindow(self._CurrentReaction, "Concentration", self, False),
                               GraphWindow(self.parent().parent().parent().GetComparingReaction(), "Concentration", self, False),
                               self)
        gwg.setGeometry(0, 400, 800, 320)
        self._ExtraWindows.append(gwg)
        self._ExtraWindows[-1].show()

    def MakeRateGraphs(self):
        gwg = GraphWindowGroup(GraphWindow(self._CurrentReaction, "Rate", self, False),
                               GraphWindow(self.parent().parent().parent().GetComparingReaction(), "Rate", self, False),
                               self)
        gwg.setGeometry(420, 400, 800, 320)
        self._ExtraWindows.append(gwg)
        self._ExtraWindows[-1].show()

    def SetReactantColour(self):
        picker = QColorDialog()
        picker.exec_()
        if picker.selectedColor() is not None:
            self._CurrentReaction.SetReactantColour(picker.selectedColor())

    def SetProductColour(self):
        picker = QColorDialog()
        picker.exec_()
        if picker.selectedColor() is not None:
            self._CurrentReaction.SetProductColour(picker.selectedColor())

    def GetKc(self):
        kc = self._CurrentReaction.GetKc()
        newkc = "K<sub>c</sub>"
        x = 2
        while x in range(len(kc)):
            if kc[x] == "^":
                x += 1
                newkc += "<sup>"
                newkc += kc[x]
                newkc += "</sup>"
            else:
                newkc += kc[x]
            x += 1
        self._kclabel.setText(newkc)
        self.update()

    def ShowWorking(self):
        getcontext().prec = 3
        working = QPlainTextEdit()
        working.setWindowTitle("Kc calculation")
        reactants = []
        products = []
        for x in self._CurrentReaction.GetReactants():
            if x.GetUsed():
                reactants.append(x)
        for x in self._CurrentReaction.GetProducts():
            if x.GetUsed():
                products.append(x)
        working.appendPlainText("Concentration = moles / volume")
        volume = self._CurrentReaction.GetVolume()
        working.appendPlainText("Volume = "+str(volume)+" dm^3")
        pvalues = []
        rvalues = []
        for x in products:
            working.appendPlainText("Concentration of "+x.GetFormula()+" = "+str(Decimal(x.GetConcentration(volume)) + Decimal(0.0))+" mol dm^-3")
            pvalues.append(x.GetConcentration(volume))
            pvalues.append(x.GetSRatio())
        for x in reactants:
            working.appendPlainText("Concentration of "+x.GetFormula()+" = "+str(Decimal(x.GetConcentration(volume)) + Decimal(0.0))+" mol dm^-3")
            rvalues.append(x.GetConcentration(volume))
            rvalues.append(x.GetSRatio())
        kcvalue = "Value of Kc ="
        x = 0
        while x < len(pvalues):
            kcvalue += " ("+str(Decimal(pvalues[x]) + Decimal(0.0))+")^"
            x += 1
            kcvalue += str(pvalues[x])
            x += 1
        kcvalue += " /"
        x = 0
        while x < len(rvalues):
            kcvalue += " ("+str(Decimal(rvalues[x]) + Decimal(0.0))+")^"
            x += 1
            kcvalue += str(rvalues[x])
            x += 1
        working.appendPlainText(kcvalue)
        rproductsum = 0
        for x in reactants:
            rproductsum += x.GetSRatio()
        pproductsum = 0
        for x in products:
            pproductsum += x.GetSRatio()
        working.appendPlainText("There are "+str(len(reactants))+" reactants, with units mol dm^-3.")
        working.appendPlainText("The product of these units is mol^"+str(rproductsum)+" dm^"+str(rproductsum * -3)+".")
        working.appendPlainText("There are "+str(len(products))+" products, with units mol dm^-3.")
        working.appendPlainText("The product of these units is mol^"+str(pproductsum)+" dm^"+str(pproductsum * -3)+".")
        working.appendPlainText("The product units must be divided by the reactant units, so")
        working.appendPlainText(self._CurrentReaction.GetKc())
        self._ExtraWindows.append(working)
        working.show()

    def StartAnimation(self):
        self._no_of_anim_updates = 0
        reactants = []
        for x in self._CurrentReaction.GetReactants():
            if x.GetUsed():
                reactants.append(x)
        products = []
        for x in self._CurrentReaction.GetProducts():
            if x.GetUsed():
                products.append(x)
        self._eqmratio = self.GetRPRatio(reactants, products)
        self._rflipchance = int(self._eqmratio * 100)
        # self._pflipchance = int((1 / self._eqmratio) * 100)
        self._pflipchance = int((1 - self._eqmratio) * 100)
        if self._CurrentReaction.GetCatalyst().GetUsed():
            efficacy = self._CurrentReaction.GetCatalyst().GetEfficacy()
            self._rflipchance /= efficacy
            self._pflipchance /= efficacy
            flipchancechangefromcata = 2.0 * (self._CurrentReaction.GetCatalyst().GetInitialMoles() / 100)
            if efficacy > 1:
                flipchancechangefromcata *= -1
            self._rflipchance = int(self._rflipchance + flipchancechangefromcata)
            self._pflipchance = int(self._pflipchance + flipchancechangefromcata)
        for x in self._Squares:
            x.Reset()
        self._timer.start()

    def ContinueAnimation(self):
        self._no_of_anim_updates += 1
        reactantsquares = 0
        for x in self._Squares:
            if x.GetIsReactant():
                reactantsquares += 1
        print("Reactant squares: "+str(reactantsquares))
        # currentratio = reactantsquares / (101 - reactantsquares)
        currentratio = reactantsquares / 100
        newrflipchance = self._rflipchance
        newpflipchance = self._pflipchance
        if currentratio < int(self._eqmratio * 100):
            newrflipchance -= currentratio * 0.2
            newpflipchance += currentratio * 0.2
        elif currentratio > int(self._eqmratio * 100):
            newrflipchance += currentratio * 0.2
            newpflipchance -= currentratio * 0.2
        for x in self._Squares:
            x.Flip(newrflipchance, newpflipchance)
        self.update()
        for x in self._ExtraWindows:
            if type(x) == GraphWindowGroup:
                x.update()
        if self._no_of_anim_updates > 1000:
            self._timer.stop()

    def RemoveMe(self, qwidg):
        self._ExtraWindows.remove(qwidg)

    def Clone(self):
        self.parent().parent().parent().SetComparingReaction(self._CurrentReaction)

    def SetKcDifference(self, string):
        self._kcdifference = string

    def PrintGraph(self, painter, graphof):
        GraphWindow(self._CurrentReaction, graphof, self, True).render(painter)

    def GetRPRatio(self, reactants, products):
        # volume = self._CurrentReaction.GetVolume()
        # arc = 0
        # for x in reactants:
        #     arc += x.GetConcentration(volume)
        # arc /= len(reactants)
        # apc = 0
        # for x in products:
        #     apc += x.GetConcentration(volume)
        # apc /= len(products)
        # return arc / apc
        rm = 0
        for x in reactants:
            rm += x.GetInitialMoles()
        pm = 0
        for x in products:
            pm += x.GetInitialMoles()
        return rm / (rm + pm)

    def GetAnimUpdates(self):
        return self._no_of_anim_updates
Beispiel #36
0
class LdapWidget(DirectoryWidget):
    def __init__(self, config, specific_config, mainwindow, parent=None):
        assert config is not None
        assert specific_config is not None
        DirectoryWidget.__init__(self, config, specific_config, mainwindow, parent)
        self.buildInterface(config)
        self.updateView(self.specific_config)

    def buildInterface(self, config):
        #<server uri>
        self.uri = QLineEdit()
        self.texts.add(self.uri)
        self.connect(self.uri, SIGNAL('textChanged(QString)'), self.setUri)
        self.connect(self.uri, SIGNAL('textChanged(QString)'), self.signalModified)
        self.connect(self.uri, SIGNAL('textEdited(QString)'), self.helpURI)
        self.connect(self.uri, SIGNAL('editingFinished()'), self.noHelpURI)
        self.connect(self.uri, SIGNAL('editingFinished()'), self.updateUri)
        self.form.addRow(tr('LDAP Server(s) uri'), self.uri)

        self.uri.setToolTip(help_uri_tooltip)
        self.connect(self.uri, SIGNAL('returnPressed()'), self.signalModified)

        self.uri_message_area = MessageArea()
        self.empty_uri_label = QLabel()
        self.form.addRow(self.empty_uri_label, self.uri_message_area)
        self.empty_uri_label.hide()
        self.uri_message_area.hide()
        self.uri_message_area.setMessage(help_uri_title, help_uri_message_area)

        self.numeric_uri_warning = MessageArea()
        empty  = QLabel()
        self.form.addRow(empty, self.numeric_uri_warning)
        empty.hide()
        self.numeric_uri_warning.hide()
        self.numeric_uri_warning.warning(numeric_warning_title, numeric_warning)
        self.numeric_uri_warning.setWidth(60)

        #</server uri>

        #<other fields>
        for args in self._genTextFieldsData():
            text_input = self.addTextInput(*args[1:])
            setattr(self, args[0], text_input)
            self.connect(text_input, SIGNAL('editingFinished(QString)'), self.valid)
        #</other fields>

        self.ssl_box = self.mkSslBox()
        self.connect(self.ssl_box, SIGNAL('toggled(bool)'), self.toggleSsl)
        self.form.addRow(self.ssl_box)

        self.form.addRow(separator())

        test_widget = QPushButton(tr("Test this configuration"))
        self.form.addRow("", test_widget)
        test_widget.connect(test_widget, SIGNAL('clicked()'), self.test_ldap)

    def _genTextFieldsData(self):
        return (
            ('dn_users', tr('LDAP DN for users'), self.setDnUsers),
            ('dn_groups', tr('LDAP DN for groups'), self.setDnGroups),
            ('user', tr('DN used to log in on the LDAP server'), self.setUser),
            ('password', tr('Password used to log in on the LDAP server'), self.setPassword, False)
        )

    def test_ldap(self):
        dc, base, uri, filter, password = self.specific_config.generateTest()
        if uri is None or uri == '':
            QMessageBox.critical(
                self,
                "Missing data",
                "Please fill URI field"
                )
            return
        if dc is None:
            dc == ''

        filter, ok = QInputDialog.getText(
            self,
            tr("LDAP Filter"),
            tr("Please enter a filter:"),
            QLineEdit.Normal,
            filter
            )

        if not ok:
            return

        async = self.mainwindow.client.async()
        async.call(
            'nuauth',
            'testLDAP',
            dc, base, uri, unicode(filter), password,
            callback = self.success_test,
            errback = self.error_test
            )

    def success_test(self, result):

        ans_no = tr("OK")
        ans_yes = tr("Show the server's answer")
        show_details = QMessageBox.question(
            self,
            tr('LDAP test results'),
            tr('LDAP test completed without error'),
            ans_no,
            ans_yes
            )

        if show_details == 0:
            return

        title = tr('LDAP test results')
        QMessageBox.information(
            self,
            title,
            '<span><h2>%s</h2><pre>%s</pre></span>' % (title, unicode(result))
            )

    def error_test(self, result):
        basic_text = tr('LDAP test completed with an error')
        formatted_text = u"""\
<span>
%s
<pre>
%s
</pre>
</span>
""" % (basic_text, unicode(result))
        QMessageBox.warning(
            self,
            tr('LDAP test results'),
            formatted_text
            )

    def helpURI(self, text):
        self.uri_message_area.show()

    def noHelpURI(self):
        self.uri_message_area.hide()

    def toggleSsl(self, value):
        if value:
            self.selectCustomOrNupki(NUPKI)
        else:
            self.specific_config.custom_or_nupki = SSL_DISABLED
        self.signalModified()

    def setUri(self, uris_text):
        self.specific_config.setUri(self.readString(uris_text))
        self.signalModified()

        self.numeric_uri_warning.setVisible(ip_in_ldapuri(self.specific_config.uri))

    def setUser(self, user):
        self.specific_config.user = self.readString(user)

    def setPassword(self, password):
        self.specific_config.password = self.readString(password)

    def setDnUsers(self, dn):
        self.specific_config.dn_users = self.readString(dn)

    def setDnGroups(self, dn):
        self.specific_config.dn_groups = self.readString(dn)

    def mkSslBox(self):
        group = QGroupBox(tr("Check server certificate"))
        group.setCheckable(True)
        box = QVBoxLayout(group)

        #id 0
        nupki = QRadioButton(tr("Upload certificate"))
        #id 1
        custom = QRadioButton(tr("Use an internal PKI"))

        hbox = QHBoxLayout()
        box.addLayout(hbox)
        self.nupki_or_custom = QButtonGroup()
        self.connect(self.nupki_or_custom, SIGNAL('buttonClicked(int)'), self.toggleCustomOrNupki)
        for index, radio in enumerate((custom, nupki)):
            hbox.addWidget(radio)
            self.nupki_or_custom.addButton(radio, index)

        self.file_selector_widget = QWidget()
        vbox = QVBoxLayout(self.file_selector_widget)
        selector_label = QLabel(tr("Manually uploaded LDAP certificate"))
        vbox.addWidget(selector_label)
        add_cert_trigger = AddButton(text=tr("Upload a certificate"))
        vbox.addWidget(add_cert_trigger)
        vbox.addWidget(separator())

        self.has_cert_message = QLabel(
            tr("There is no manually uploaded server certificate")
            )
        self.del_cert = RemButton(
            tr("Delete certificate file from server")
            )
        vbox.addWidget(self.has_cert_message)
        vbox.addWidget(self.del_cert)

        self.connect(add_cert_trigger, SIGNAL('clicked()'), self.upload_server_cert)

        self.connect(self.del_cert, SIGNAL('clicked()'), self.delete_server_cert)

        self.nupki_message = MessageArea()
        self.nupki_message.setMessage(tr("Warning"),
            tr(
                "There is no server certificate in the internal PKI.<br/>"
                "Please import or generate one using an internal PKI."
            )
            )

        for anti_button, widget in ((custom, self.nupki_message), (nupki, self.file_selector_widget)):
            box.addWidget(widget)
            self.connect(anti_button, SIGNAL('toggled(bool)'), widget.setVisible)

        self.selectCustomOrNupki(CUSTOM)

        return group

    def upload_server_cert(self):
        dialog = UploadDialog(
            selector_label=tr("LDAP certificate"),
            filter=tr("Certificate file (*.crt *.pem *)")
            )
        accepted = dialog.exec_()

        if accepted != QDialog.Accepted:
            return

        filename = dialog.filename

        if not filename:
            return
        with open(filename, 'rb') as fd:
            content = fd.read()

        content = encodeFileContent(content)

        self.mainwindow.addToInfoArea(tr('Uploading of a certificate file for the ldap server'))
        async = self.mainwindow.client.async()
        async.call("nuauth", "upload_ldap_server_cert", content,
            callback = self.success_upload,
            errback = self.error_upload
            )

    def success_upload(self, value):
        self.mainwindow.addToInfoArea(tr('[LDAP server cert upload] Success!'))
        self.specific_config.server_cert_set = True
        self.setServerCert()

        self.signalModified()

    def error_upload(self, value):
        self.mainwindow.addToInfoArea(tr('[LDAP server cert upload] Error!'), COLOR_ERROR)
        self.mainwindow.addToInfoArea(tr('[LDAP server cert upload] %s') % value, COLOR_ERROR)

    def setServerCert(self):
        if self.specific_config.server_cert_set:
            self.del_cert.show()
            self.has_cert_message.hide()
        else:
            self.del_cert.hide()
            self.has_cert_message.show()

    def delete_server_cert(self):
        confirm_box = QMessageBox(self)
        confirm_box.setText(
            tr(
                "Please confirm the deletion of the "
                "manually uploaded LDAP server certificate."
            )
            )
        confirm_box.setInformativeText(
            tr("Do you really want to delete the certificate file?")
            )
        confirm_box.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
        confirm_box.setDefaultButton(QMessageBox.Cancel)
        confirm = confirm_box.exec_()

        if confirm != QMessageBox.Ok:
            return

        async = self.mainwindow.client.async()
        async.call("nuauth", "delete_ldap_server_cert",
            callback = self.success_delete,
            errback = self.error_delete
            )

    def success_delete(self, value):
        self.mainwindow.addToInfoArea(tr('[LDAP server cert deletion] Success!'))
        self.specific_config.server_cert_set = False
        self.setServerCert()

        self.signalModified()

    def error_delete(self, value):
        self.mainwindow.addToInfoArea(tr('[LDAP server cert deletion] Error!'), COLOR_ERROR)
        self.mainwindow.addToInfoArea(tr('[LDAP server cert deletion] %s') % value, COLOR_ERROR)

    def toggleCustomOrNupki(self, id):
        if id == 0:
            self.specific_config.custom_or_nupki = NUPKI
        else:
            self.specific_config.custom_or_nupki = CUSTOM
        self.signalModified()

    def selectCustomOrNupki(self, custom_or_nupki):
        if custom_or_nupki == CUSTOM:
            self.file_selector_widget.setEnabled(True)
            self.nupki_message.hide()
            id = 1
        else:
            custom_or_nupki = NUPKI
            self.file_selector_widget.hide()
            id = 0
        self.nupki_or_custom.button(id).setChecked(True)

    def setSslData(self, config):
        ssl_enabled = (SSL_DISABLED != config.custom_or_nupki)
        self.ssl_box.setChecked(ssl_enabled)
        if ssl_enabled:
            self.selectCustomOrNupki(config.custom_or_nupki)

    def updateUri(self, config=None):
        if config is None:
            config = self.specific_config
        self.setText(self.uri, config.uri)

    def updateView(self, config=None):
        if config is None:
            config = self.specific_config
        self.updateUri(config=config)
        self.setSslData(config)
        #never copy this one:
        self.setDefaultText(self.dn_users, self.specific_config.dn_users)
        self.setDefaultText(self.dn_groups, self.specific_config.dn_groups)
        self.setDefaultText(self.user, config.user)
        self.setDefaultText(self.password, config.password)
        self.setServerCert()
Beispiel #37
0
class LaserRangeFinder(PluginBase):
    def __init__(self, *args):
        PluginBase.__init__(self, BrickletLaserRangeFinder, *args)

        self.lrf = self.device

        self.cbe_distance = CallbackEmulator(self.lrf.get_distance,
                                             self.cb_distance,
                                             self.increase_error_count)
        self.cbe_velocity = CallbackEmulator(self.lrf.get_velocity,
                                             self.cb_velocity,
                                             self.increase_error_count)

        self.current_distance = None  # int, cm
        self.current_velocity = None  # float, m/s

        plots_distance = [('Distance', Qt.red, lambda: self.current_distance,
                           format_distance)]
        plots_velocity = [('Velocity', Qt.red, lambda: self.current_velocity,
                           '{:.2f} m/s'.format)]
        self.plot_widget_distance = PlotWidget('Distance [cm]', plots_distance)
        self.plot_widget_velocity = PlotWidget('Velocity [m/s]',
                                               plots_velocity)

        self.mode_label = QLabel('Mode:')
        self.mode_combo = QComboBox()
        self.mode_combo.addItem("Distance: 1cm resolution, 40m max")
        self.mode_combo.addItem("Velocity: 0.10 m/s resolution, 12.70m/s max")
        self.mode_combo.addItem("Velocity: 0.25 m/s resolution, 31.75m/s max")
        self.mode_combo.addItem("Velocity: 0.50 m/s resolution, 63.50m/s max")
        self.mode_combo.addItem("Velocity: 1.00 m/s resolution, 127.00m/s max")
        self.mode_combo.currentIndexChanged.connect(self.mode_changed)
        self.mode_combo.hide()

        self.label_average_distance = QLabel('Moving Average for Distance:')

        self.spin_average_distance = QSpinBox()
        self.spin_average_distance.setMinimum(0)
        self.spin_average_distance.setMaximum(50)
        self.spin_average_distance.setSingleStep(1)
        self.spin_average_distance.setValue(10)
        self.spin_average_distance.editingFinished.connect(
            self.spin_average_finished)

        self.label_average_velocity = QLabel('Moving Average for Velocity:')

        self.spin_average_velocity = QSpinBox()
        self.spin_average_velocity.setMinimum(0)
        self.spin_average_velocity.setMaximum(50)
        self.spin_average_velocity.setSingleStep(1)
        self.spin_average_velocity.setValue(10)
        self.spin_average_velocity.editingFinished.connect(
            self.spin_average_finished)

        self.enable_laser = QCheckBox("Enable Laser")
        self.enable_laser.stateChanged.connect(self.enable_laser_changed)

        self.label_acquisition_count = QLabel('Acquisition Count:')
        self.spin_acquisition_count = QSpinBox()
        self.spin_acquisition_count.setMinimum(1)
        self.spin_acquisition_count.setMaximum(255)
        self.spin_acquisition_count.setSingleStep(1)
        self.spin_acquisition_count.setValue(128)

        self.enable_qick_termination = QCheckBox("Quick Termination")

        self.label_threshold = QLabel('Threshold:')
        self.threshold = QCheckBox("Automatic Threshold")

        self.spin_threshold = QSpinBox()
        self.spin_threshold.setMinimum(1)
        self.spin_threshold.setMaximum(255)
        self.spin_threshold.setSingleStep(1)
        self.spin_threshold.setValue(1)

        self.label_frequency = QLabel('Frequency [Hz]:')
        self.frequency = QCheckBox(
            "Automatic Frequency (Disable for Velocity)")

        self.spin_frequency = QSpinBox()
        self.spin_frequency.setMinimum(10)
        self.spin_frequency.setMaximum(500)
        self.spin_frequency.setSingleStep(1)
        self.spin_frequency.setValue(10)

        self.spin_acquisition_count.editingFinished.connect(
            self.configuration_changed)
        self.enable_qick_termination.stateChanged.connect(
            self.configuration_changed)
        self.spin_threshold.editingFinished.connect(self.configuration_changed)
        self.threshold.stateChanged.connect(self.configuration_changed)
        self.spin_frequency.editingFinished.connect(self.configuration_changed)
        self.frequency.stateChanged.connect(self.configuration_changed)

        layout_h1 = QHBoxLayout()
        layout_h1.addWidget(self.plot_widget_distance)
        layout_h1.addWidget(self.plot_widget_velocity)

        layout_h2 = QHBoxLayout()
        layout_h2.addWidget(self.mode_label)
        layout_h2.addWidget(self.mode_combo)
        layout_h2.addWidget(self.label_average_distance)
        layout_h2.addWidget(self.spin_average_distance)
        layout_h2.addWidget(self.label_average_velocity)
        layout_h2.addWidget(self.spin_average_velocity)
        layout_h2.addStretch()
        layout_h2.addWidget(self.enable_laser)

        layout_h3 = QHBoxLayout()
        layout_h3.addWidget(self.label_frequency)
        layout_h3.addWidget(self.spin_frequency)
        layout_h3.addWidget(self.frequency)
        layout_h3.addStretch()
        layout_h3.addWidget(self.enable_qick_termination)

        layout_h4 = QHBoxLayout()
        layout_h4.addWidget(self.label_threshold)
        layout_h4.addWidget(self.spin_threshold)
        layout_h4.addWidget(self.threshold)
        layout_h4.addStretch()
        layout_h4.addWidget(self.label_acquisition_count)
        layout_h4.addWidget(self.spin_acquisition_count)

        self.widgets_distance = [
            self.plot_widget_distance, self.spin_average_distance,
            self.label_average_distance
        ]
        self.widgets_velocity = [
            self.plot_widget_velocity, self.spin_average_velocity,
            self.label_average_velocity
        ]

        for w in self.widgets_distance:
            w.hide()
        for w in self.widgets_velocity:
            w.hide()

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

        layout = QVBoxLayout(self)
        layout.addLayout(layout_h1)
        layout.addWidget(line)
        layout.addLayout(layout_h2)
        layout.addLayout(layout_h3)
        layout.addLayout(layout_h4)

        self.has_sensor_hardware_version_api = self.firmware_version >= (2, 0,
                                                                         3)
        self.has_configuration_api = self.firmware_version >= (2, 0, 3)

    def start(self):
        if self.has_sensor_hardware_version_api:
            async_call(self.lrf.get_sensor_hardware_version, None,
                       self.get_sensor_hardware_version_async,
                       self.increase_error_count)
        else:
            self.get_sensor_hardware_version_async(1)

        if self.has_configuration_api:
            async_call(self.lrf.get_configuration, None,
                       self.get_configuration_async, self.increase_error_count)

        async_call(self.lrf.get_mode, None, self.get_mode_async,
                   self.increase_error_count)
        async_call(self.lrf.is_laser_enabled, None,
                   self.is_laser_enabled_async, self.increase_error_count)
        async_call(self.lrf.get_moving_average, None,
                   self.get_moving_average_async, self.increase_error_count)
        async_call(self.lrf.get_distance, None, self.cb_distance,
                   self.increase_error_count)
        async_call(self.lrf.get_velocity, None, self.cb_velocity,
                   self.increase_error_count)
        self.cbe_distance.set_period(25)
        self.cbe_velocity.set_period(25)

        self.plot_widget_distance.stop = False
        self.plot_widget_velocity.stop = False

    def stop(self):
        self.cbe_distance.set_period(0)
        self.cbe_velocity.set_period(0)

        self.plot_widget_distance.stop = True
        self.plot_widget_velocity.stop = True

    def destroy(self):
        pass

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

    def is_laser_enabled_async(self, enabled):
        if enabled:
            self.enable_laser.setChecked(True)
        else:
            self.enable_laser.setChecked(False)

    def enable_laser_changed(self, state):
        if state == Qt.Checked:
            self.lrf.enable_laser()
        else:
            self.lrf.disable_laser()

    def mode_changed(self, value):
        if value < 0 or value > 4:
            return

        self.lrf.set_mode(value)
        if value == 0:
            for w in self.widgets_velocity:
                w.hide()
            for w in self.widgets_distance:
                w.show()
        else:
            for w in self.widgets_distance:
                w.hide()
            for w in self.widgets_velocity:
                w.show()

    def cb_distance(self, distance):
        self.current_distance = distance

    def cb_velocity(self, velocity):
        self.current_velocity = velocity / 100.0

    def configuration_changed(self):
        acquisition_count = self.spin_acquisition_count.value()
        enable_quick_termination = self.enable_qick_termination.isChecked()

        if self.threshold.isChecked():
            threshold = 0
        else:
            threshold = self.spin_threshold.value()

        if self.frequency.isChecked():
            frequency = 0
            for w in self.widgets_velocity:
                w.hide()
        else:
            frequency = self.spin_frequency.value()
            for w in self.widgets_velocity:
                w.show()

        self.spin_threshold.setDisabled(threshold == 0)
        self.spin_frequency.setDisabled(frequency == 0)

        self.lrf.set_configuration(acquisition_count, enable_quick_termination,
                                   threshold, frequency)

    def get_configuration_async(self, conf):
        self.spin_acquisition_count.blockSignals(True)
        self.spin_acquisition_count.setValue(conf.acquisition_count)
        self.spin_acquisition_count.blockSignals(False)

        self.enable_qick_termination.blockSignals(True)
        self.enable_qick_termination.setChecked(conf.enable_quick_termination)
        self.enable_qick_termination.blockSignals(False)

        self.spin_threshold.blockSignals(True)
        self.spin_threshold.setValue(conf.threshold_value)
        self.spin_threshold.setDisabled(conf.threshold_value == 0)
        self.spin_threshold.blockSignals(False)

        self.spin_frequency.blockSignals(True)
        self.spin_frequency.setValue(conf.measurement_frequency)
        self.spin_frequency.setDisabled(conf.measurement_frequency == 0)
        self.spin_frequency.blockSignals(False)

        self.threshold.blockSignals(True)
        self.threshold.setChecked(conf.threshold_value == 0)
        self.threshold.blockSignals(False)

        self.frequency.blockSignals(True)
        self.frequency.setChecked(conf.measurement_frequency == 0)
        self.frequency.blockSignals(False)

        self.configuration_changed()

    def get_sensor_hardware_version_async(self, value):
        if value == 1:
            self.mode_combo.show()
            self.mode_label.show()
            self.label_acquisition_count.hide()
            self.spin_acquisition_count.hide()
            self.enable_qick_termination.hide()
            self.label_threshold.hide()
            self.spin_threshold.hide()
            self.threshold.hide()
            self.label_frequency.hide()
            self.spin_frequency.hide()
            self.frequency.hide()
        else:
            self.mode_combo.hide()
            self.mode_label.hide()
            self.label_acquisition_count.show()
            self.spin_acquisition_count.show()
            self.enable_qick_termination.show()
            self.label_threshold.show()
            self.spin_threshold.show()
            self.threshold.show()
            self.label_frequency.show()
            self.spin_frequency.show()
            self.frequency.show()

            for w in self.widgets_distance:
                w.show()
            for w in self.widgets_velocity:
                w.show()

    def get_mode_async(self, value):
        self.mode_combo.setCurrentIndex(value)
        self.mode_changed(value)

    def get_moving_average_async(self, avg):
        self.spin_average_distance.setValue(avg.distance_average_length)
        self.spin_average_velocity.setValue(avg.velocity_average_length)

    def spin_average_finished(self):
        self.lrf.set_moving_average(self.spin_average_distance.value(),
                                    self.spin_average_velocity.value())
Beispiel #38
0
class WFramework(QWidget, Logger.ClassLogger):
    """
    Framework widget
    """
    # action, description, misc, parameters
    AddStep = pyqtSignal(str, str, str, dict)  
    UpdateStep = pyqtSignal(str, str, str, dict)  
    CancelEdit = pyqtSignal()
    def __init__(self, parent):
        """
        Constructor
        """
        QWidget.__init__(self)

        self.createActions()
        self.createWidgets()
        self.createToolbar()
        self.createConnections()
    
    def createActions(self):
        """
        Create qt actions
        """
        self.addAction = QPushButton(QIcon(":/add_black.png"), '&Add Action', self)
        self.addAction.setMinimumHeight(40)
        self.addAction.setMaximumWidth(200)
        
        self.cancelAction = QtHelper.createAction(self, "&Cancel", self.cancelStep, 
                                            icon=QIcon(":/undo.png"), tip = 'Cancel update')
        self.cancelAction.setEnabled(False)
        
        self.optionsAction = QtHelper.createAction(self, "&", self.openOptions, 
                                            icon=QIcon(":/recorder-basic-small.png"), tip = 'Framework options')
        
    def openOptions(self):
        """
        Open options dialog
        """
        if self.optionsDialog.exec_() == QDialog.Accepted:
            pass
              
    def createWidgets(self):
        """
        Create all qt widgets
        """
        self.optionsDialog  = OptionsDialog(self)
        
        self.validatorUpper = ValidatorUpper(self)
        self.validatorAll = ValidatorAll(self)
        self.validatorInt = QIntValidator(self)

        font = QFont()
        font.setBold(True)

        self.actionsComboBox = QComboBox(self)
        self.actionsComboBox.setMinimumHeight(40)
        for i in xrange(len(GuiSteps.ACTION_FRAMEWORK_DESCR)):
            if not len( GuiSteps.ACTION_FRAMEWORK_DESCR[i] ):
                self.actionsComboBox.insertSeparator(i+1)
            else:
                el = GuiSteps.ACTION_FRAMEWORK_DESCR[i].keys()
                self.actionsComboBox.addItem( list(el)[0] )
            
        self.labelActionDescr = QLabel(self)
        self.labelActionDescr.setText( "%s\n" % GuiSteps.ACTION_FRAMEWORK_DESCR[0][GuiSteps.FRAMEWORK_INFO])
        self.labelActionDescr.setWordWrap(True)
        self.labelActionDescr.hide()
        
        self.descriptionLine = QLineEdit(self)
        self.descriptionLine.hide()

        actionLayout2 = QGridLayout()

        self.createWidgetGetText()        
        self.createWidgetGetWait()
        self.createWidgetCacheSet()
        self.createWidgetCheckString()
        self.createWidgetGetAsk()

        actionLayout2.addWidget( self.setCacheGroup , 0, 0)
        actionLayout2.addWidget( self.getCheckGroup , 1, 0)
        actionLayout2.addWidget( self.getTextGroup , 2, 0)
        actionLayout2.addWidget( self.getWaitGroup , 3, 0)
        actionLayout2.addWidget( self.getAskGroup , 4, 0)

        labelAct = QLabel( self.tr("Action: ") )
        labelAct.setFont( font) 
        
        self.arrowLabel = QLabel("")
        self.arrowLabel.setPixmap(QPixmap(":/arrow-right.png").scaledToWidth(32))

        self.arrowLabel2 = QLabel("")
        self.arrowLabel2.setPixmap(QPixmap(":/arrow-right.png").scaledToWidth(32))

        layoutFinal = QHBoxLayout()
        layoutFinal.addWidget( labelAct )
        layoutFinal.addWidget(self.actionsComboBox)
        layoutFinal.addWidget( self.arrowLabel )
        layoutFinal.addLayout( actionLayout2 )
        layoutFinal.addWidget( self.arrowLabel2 )
        layoutFinal.addWidget(self.addAction)

        layoutFinal.addStretch(1)
        self.setLayout(layoutFinal)
        
    def createToolbar(self):
        """
        Create toolbar
        """
        pass

    def createWidgetCheckString(self):
        """
        Create widget to check string
        """
        self.getCheckGroup = QGroupBox(self.tr(""))

        # check in ?
        self.checkInTextLine = QLineEdit(self)
        self.checkInTextLine.setMinimumWidth(300)
        self.checkInTextCombo = QComboBox(self)
        self.checkInTextCombo.addItems( [ "CACHE" ] )

        # operator   
        self.checkComboBox = QComboBox(self)
        self.checkComboBox.addItems( [ GuiSteps.OP_CONTAINS, GuiSteps.OP_NOTCONTAINS, GuiSteps.OP_REGEXP, GuiSteps.OP_NOTREGEXP,
                                       GuiSteps.OP_STARTSWITH, GuiSteps.OP_NOTSTARTSWITH, GuiSteps.OP_ENDSWITH, 
                                       GuiSteps.OP_NOTENDSWITH ] )
        
        # check what ?
        self.checkOutTextLine = QLineEdit(self)
        self.checkOutTextLine.setMinimumWidth(300)
        self.checkOutTextCombo = QComboBox(self)
        self.checkOutTextCombo.addItems( LIST_TYPES )

        # final layout
        mainChecklayout = QGridLayout()
        mainChecklayout.addWidget(  QLabel( self.tr("Checking from:") ), 0, 0 )
        mainChecklayout.addWidget(  self.checkInTextCombo, 0, 1 )
        mainChecklayout.addWidget(  self.checkInTextLine, 0, 2 )
        mainChecklayout.addWidget(  QLabel( self.tr("If:") ), 1, 0 )
        mainChecklayout.addWidget(  self.checkComboBox, 1, 1 )
        mainChecklayout.addWidget(  QLabel( self.tr("The Value:") ), 2, 0  )
        mainChecklayout.addWidget(  self.checkOutTextCombo, 2, 1 )
        mainChecklayout.addWidget(  self.checkOutTextLine, 2, 2 )

        self.getCheckGroup.setLayout(mainChecklayout)
        self.getCheckGroup.hide()
        
    def createWidgetGetText(self):
        """
        Create text widget 
        """
        self.getTextGroup = QGroupBox(self.tr(""))

        self.basicTextLine = QLineEdit(self)
        self.basicTextLine.setMinimumWidth(300)
        self.basicTextCombo = QComboBox(self)
        self.basicTextCombo.addItems( LIST_TYPES )

        mainTextlayout = QGridLayout()
        mainTextlayout.addWidget(  QLabel( self.tr("Value:") ), 0, 0 )
        mainTextlayout.addWidget(  self.basicTextCombo, 0, 1 )
        mainTextlayout.addWidget(  self.basicTextLine, 0, 2 )

        self.getTextGroup.setLayout(mainTextlayout)
    
    def createWidgetGetAsk(self):
        """
        Create ask widget
        """
        # ask
        self.getAskGroup = QGroupBox(self.tr(""))

        self.askTextLine = QLineEdit(self)
        self.askTextLine.setMinimumWidth(300)
        self.askTextCombo = QComboBox(self)
        self.askTextCombo.addItems( LIST_TYPES )

        self.askTextCacheLine = QLineEdit(self)
        self.askTextCacheLine.setMinimumWidth(300)
        self.askTextCacheCombo = QComboBox(self)
        self.askTextCacheCombo.addItems( [ "CACHE" ] )
        
        mainAsklayout = QGridLayout()
        mainAsklayout.addWidget(  QLabel( self.tr("User input prompt:") ), 0, 0 )
        mainAsklayout.addWidget(  self.askTextCombo, 0, 1 )
        mainAsklayout.addWidget(  self.askTextLine, 0, 2 )
        mainAsklayout.addWidget(  QLabel( self.tr("And save response in:") ), 1, 0 )
        mainAsklayout.addWidget(  self.askTextCacheCombo, 1, 1 )
        mainAsklayout.addWidget(  self.askTextCacheLine, 1, 2 )
        
        self.getAskGroup.setLayout(mainAsklayout)
        self.getAskGroup.hide()
        
    def createWidgetGetWait(self):
        """
        Create wait text widget
        """
        self.getWaitGroup = QGroupBox(self.tr(""))

        self.valueWaitLine = QLineEdit(self)
        self.valueWaitLine.setMinimumWidth(300)
        self.valueWaitLine.setValidator(self.validatorInt)
        self.valueWaitCombo = QComboBox(self)
        self.valueWaitCombo.addItems( LIST_TYPES )

        mainTextlayout = QGridLayout()
        mainTextlayout.addWidget(  QLabel( self.tr("Value (in seconds):") ), 0, 0 )
        mainTextlayout.addWidget(  self.valueWaitCombo, 0, 1 )
        mainTextlayout.addWidget(  self.valueWaitLine, 0, 2 )

        self.getWaitGroup.setLayout(mainTextlayout)
        self.getWaitGroup.hide()
        
    def createWidgetCacheSet(self):
        """
        Create cache widget
        """
        self.setCacheGroup = QGroupBox(self.tr(""))
        
        setCacheLayout = QGridLayout()
        
        self.cacheKeyName = QLineEdit(self)
        self.cacheKeyName.setMinimumWidth(300)
        
        setCacheLayout.addWidget( QLabel( self.tr("Key name:") ) , 0, 1)
        setCacheLayout.addWidget( self.cacheKeyName , 0, 2)

        self.setCacheGroup.setLayout(setCacheLayout)
        self.setCacheGroup.hide()
        
    def createConnections(self):
        """
        Createa qt connections
        """
        self.actionsComboBox.currentIndexChanged.connect(self.onActionChanged)
        self.addAction.clicked.connect(self.addStep)
        
        self.basicTextCombo.currentIndexChanged.connect(self.onBasicTextTypeChanged)
        self.valueWaitCombo.currentIndexChanged.connect(self.onValueWaitTypeChanged)
        self.checkOutTextCombo.currentIndexChanged.connect(self.onCheckOutTextTypeChanged)
        self.askTextCombo.currentIndexChanged.connect(self.onAskTextTypeChanged)
        
    def onAskTextTypeChanged(self):
        """
        On ask type changed
        """
        if self.askTextCombo.currentText() in [ "TEXT", "CACHE" ]:
            self.askTextLine.setValidator(self.validatorAll)
            
        if self.askTextCombo.currentText() == "ALIAS":
            self.askTextLine.setText( self.askTextLine.text().upper() )
            self.askTextLine.setValidator(self.validatorUpper)
            
    def onCheckOutTextTypeChanged(self):
        """
        On check out type changed
        """
        if self.checkOutTextCombo.currentText() in [ "TEXT", "CACHE" ]:
            self.checkOutTextLine.setValidator(self.validatorAll)
            
        if self.checkOutTextCombo.currentText() == "ALIAS":
            self.checkOutTextLine.setText( self.checkOutTextLine.text().upper() )
            self.checkOutTextLine.setValidator(self.validatorUpper)
            
    def onValueWaitTypeChanged(self):
        """
        On value wait changed
        """
        if self.valueWaitCombo.currentText() in [ "TEXT" ]:
            self.valueWaitLine.setText( "0" )
            self.valueWaitLine.setValidator(self.validatorInt)
            
        if self.valueWaitCombo.currentText() in [ "CACHE" ]:
            self.valueWaitLine.setValidator(self.validatorAll)
            
        if self.valueWaitCombo.currentText() == "ALIAS":
            self.valueWaitLine.setText( self.valueWaitLine.text().upper() )
            self.valueWaitLine.setValidator(self.validatorUpper)
            
    def onBasicTextTypeChanged(self):
        """
        On basic text changed
        """
        if self.basicTextCombo.currentText() in [ "TEXT", "CACHE" ]:
            self.basicTextLine.setValidator(self.validatorAll)

        if self.basicTextCombo.currentText() == "ALIAS":
            self.basicTextLine.setText( self.basicTextLine.text().upper() )
            self.basicTextLine.setValidator(self.validatorUpper)
            
    def pluginDataAccessor(self):
        """
        Return data for plugins
        """
        return { "data": "" } 
        
    def onPluginImport(self, dataJson):
        """
        On call from plugin
        """
        pass 
    
    def onRadioAskChanged(self, button):
        """
        On radio ask changed
        """
        if button.text() == 'From alias parameter':
            self.askTextLine.setText( self.askTextLine.text().upper() )
            self.askTextLine.setValidator(self.validAskUpper)
        else:
            self.askTextLine.setValidator(self.validAskAll)

    def onActionChanged(self):
        """
        On action changed
        """
        descr = 'No description available!'
        i = 0
        for el in GuiSteps.ACTION_FRAMEWORK_DESCR:
            if isinstance(el, dict):
                if self.actionsComboBox.currentText() in el:
                    descr = GuiSteps.ACTION_FRAMEWORK_DESCR[i][self.actionsComboBox.currentText()]
                    break
            i += 1
        self.labelActionDescr.setText( "%s\n" % descr )
        
        if self.actionsComboBox.currentText() in [ GuiSteps.FRAMEWORK_INFO, GuiSteps.FRAMEWORK_WARNING ]:
            self.getTextGroup.show()
            self.getWaitGroup.hide()
            self.setCacheGroup.hide()
            self.getCheckGroup.hide()
            self.getAskGroup.hide()
            
            self.arrowLabel.show()
            self.arrowLabel2.show()
            
        elif self.actionsComboBox.currentText() in [ GuiSteps.FRAMEWORK_WAIT ]:
            self.getWaitGroup.show()
            self.getTextGroup.hide()
            self.setCacheGroup.hide()
            self.getCheckGroup.hide()
            self.getAskGroup.hide()
            
            self.arrowLabel.show()
            self.arrowLabel2.show()
            
        elif self.actionsComboBox.currentText() in [ GuiSteps.FRAMEWORK_CACHE_SET ]:
            self.getTextGroup.show()
            self.getWaitGroup.hide()
            self.setCacheGroup.show()
            self.getCheckGroup.hide()
            self.getAskGroup.hide()
            
            self.arrowLabel.show()
            self.arrowLabel2.show()
            
        elif self.actionsComboBox.currentText() in [ GuiSteps.FRAMEWORK_CHECK_STRING ]:
            self.getCheckGroup.show()
            self.getTextGroup.hide()
            self.getWaitGroup.hide()
            self.setCacheGroup.hide()
            self.getAskGroup.hide()
            
            self.arrowLabel.show()
            self.arrowLabel2.show()
            
        elif self.actionsComboBox.currentText() in [ GuiSteps.FRAMEWORK_INTERACT ]:
            self.getCheckGroup.hide()
            self.getTextGroup.hide()
            self.getWaitGroup.hide()
            self.setCacheGroup.hide()
            self.getAskGroup.show()
            
            self.arrowLabel.show()
            self.arrowLabel2.show()
            
        elif self.actionsComboBox.currentText() in [ GuiSteps.FRAMEWORK_USERCODE, GuiSteps.FRAMEWORK_CACHE_RESET ]:
            self.getCheckGroup.hide()
            self.getTextGroup.hide()
            self.getWaitGroup.hide()
            self.setCacheGroup.hide()
            self.getAskGroup.hide()
            
            self.arrowLabel.hide()
            self.arrowLabel2.show()
            
        else:
            self.getTextGroup.hide()
            self.getWaitGroup.hide()
            self.setCacheGroup.hide()
            self.getCheckGroup.hide()
            self.getAskGroup.hide()
            
            self.arrowLabel.hide()
            self.arrowLabel2.hide()

    def addStep(self):
        """
        Add step
        """
        action = self.actionsComboBox.currentText()
        descr = self.descriptionLine.text()
        descr = unicode(descr).replace('"', '')
        
        signal = self.AddStep
        if self.cancelAction.isEnabled():
            signal = self.UpdateStep

        if action in [ GuiSteps.FRAMEWORK_INFO, GuiSteps.FRAMEWORK_WARNING ]:
            fromCache = False
            if self.basicTextCombo.currentText() == "CACHE": fromCache = True
            fromAlias = False
            if self.basicTextCombo.currentText() == "ALIAS": fromAlias = True
            
            newText = self.basicTextLine.text()
            if not len(newText):
                QMessageBox.warning(self, "Assistant" , "Please to set a value!")
            else:
                parameters = { 'text': newText, 'from-cache': fromCache, 'from-alias': fromAlias }
                signal.emit( str(action), unicode(descr), EMPTY_VALUE, parameters )
        
        elif action in [ GuiSteps.FRAMEWORK_INTERACT ]:
            # read text from cache, alias or not ?
            fromCache = False
            if self.askTextCombo.currentText() == "CACHE": fromCache = True
            fromAlias = False
            if self.askTextCombo.currentText() == "ALIAS": fromAlias = True
            
            askText = self.askTextLine.text()
            if not len(askText):
                QMessageBox.warning(self, "Assistant" , "Please to set question to ask!")
            else:
                saveAskText = self.askTextCacheLine.text()
                if not len(saveAskText):
                    QMessageBox.warning(self, "Assistant" , "Please to set key destination cache!")
                else:
                    parameters = { 'key': saveAskText, 'value': askText, 'from-cache': fromCache, 'from-alias': fromAlias }
                    signal.emit( str(action), unicode(descr), EMPTY_VALUE, parameters )
                        
        elif action in [ GuiSteps.FRAMEWORK_CHECK_STRING ]:
            fromCache = False
            if self.checkOutTextCombo.currentText() == "CACHE": fromCache = True
            fromAlias = False
            if self.checkOutTextCombo.currentText() == "ALIAS": fromAlias = True
            
            inText = self.checkInTextLine.text()
            if not len(inText):
                QMessageBox.warning(self, "Assistant" , "Please to set a cache key value!")
            else:
                outText = self.checkOutTextLine.text()
                if not len(outText):
                    QMessageBox.warning(self, "Assistant" , "Please to set a value!")
                else:
                    op = self.checkComboBox.currentText()
                    parameters = { 'key': inText, 'value': outText, 'from-cache': fromCache,
                                    'from-alias': fromAlias, "operator": op }
                    signal.emit( str(action), unicode(descr), EMPTY_VALUE, parameters )
                    
        elif action in [ GuiSteps.FRAMEWORK_WAIT ]:
            fromCache = False
            if self.valueWaitCombo.currentText() == "CACHE": fromCache = True
            fromAlias = False
            if self.valueWaitCombo.currentText() == "ALIAS": fromAlias = True
            
            miscStr = self.valueWaitLine.text()
            if not len(miscStr):
                QMessageBox.warning(self, "Assistant" , "Please to set a value!")
            else:
                parameters = {'from-cache': fromCache, 'from-alias': fromAlias}
                signal.emit( str(action), unicode(descr), miscStr, parameters )
                
        elif action in [ GuiSteps.FRAMEWORK_CACHE_SET ]:
            fromCache = False
            if self.basicTextCombo.currentText() == "CACHE": fromCache = True
            fromAlias = False
            if self.basicTextCombo.currentText() == "ALIAS": fromAlias = True
            
            newText = self.basicTextLine.text()
            if not len(newText):
                QMessageBox.warning(self, "Assistant" , "Please to set a text value!")
            else:
                miscStr = self.cacheKeyName.text()
                if not len(miscStr):
                    QMessageBox.warning(self, "Assistant" , "Please to set a key name!")
                else:
                    parameters = { 'key': miscStr, 'value': newText, 'from-cache': fromCache, 'from-alias': fromAlias }
                    signal.emit( str(action), unicode(descr), EMPTY_VALUE, parameters )

        else:
            signal.emit( str(action), unicode(descr), EMPTY_VALUE, {} )
            
    def cancelStep(self):
        """
        Cancel step
        """
        self.addAction.setText( "&Add" )
        
        buttonFont = QFont()
        buttonFont.setBold(False)
        self.addAction.setFont(buttonFont)
        self.cancelAction.setEnabled(False)
        
        self.CancelEdit.emit()
    
    def finalizeUpdate(self):
        """
        Finalize update 
        """
        self.addAction.setText( "&Add Action" )
        
        buttonFont = QFont()
        buttonFont.setBold(False)
        self.addAction.setFont(buttonFont)
        self.cancelAction.setEnabled(False)

    def editStep(self, stepData):
        """
        Edit step
        """
        self.addAction.setText( "&Update" )
        buttonFont = QFont()
        buttonFont.setBold(True)
        self.addAction.setFont(buttonFont)
        
        self.cancelAction.setEnabled(True)
        
            
        # set the current value for actions combo
        for i in xrange(self.actionsComboBox.count()):
            item_text = self.actionsComboBox.itemText(i)
            if unicode(stepData["action"]) == unicode(item_text):
                self.actionsComboBox.setCurrentIndex(i)
                break
        # and then refresh options
        self.onActionChanged()
        
        # finally fill all fields
        self.descriptionLine.setText( stepData["description"] )
                
        if self.actionsComboBox.currentText() in [ GuiSteps.FRAMEWORK_INFO, GuiSteps.FRAMEWORK_WARNING ] :
            self.basicTextLine.setText ( stepData["parameters"]["text"] )
            if stepData["parameters"]["from-cache"]:
                self.basicTextLine.setValidator(self.validatorAll)
                self.basicTextCombo.setCurrentIndex(INDEX_CACHE)
            elif stepData["parameters"]["from-alias"]:
                self.basicTextLine.setValidator(self.validatorUpper)
                self.basicTextCombo.setCurrentIndex(INDEX_ALIAS)
            else:
                self.basicTextLine.setValidator(self.validatorAll)
                self.basicTextCombo.setCurrentIndex(INDEX_TEXT)

        if self.actionsComboBox.currentText() in [ GuiSteps.FRAMEWORK_WAIT ]:
            self.valueWaitLine.setText ( stepData["misc"] )
            if stepData["parameters"]["from-cache"]:
                self.valueWaitLine.setValidator(self.validatorAll)
                self.valueWaitCombo.setCurrentIndex(INDEX_CACHE)
            elif stepData["parameters"]["from-alias"]:
                self.valueWaitLine.setValidator(self.validatorUpper)
                self.valueWaitCombo.setCurrentIndex(INDEX_ALIAS)
            else:
                self.valueWaitLine.setValidator(self.validatorInt)
                self.valueWaitCombo.setCurrentIndex(INDEX_TEXT)
 
        if self.actionsComboBox.currentText() in [ GuiSteps.FRAMEWORK_CACHE_SET ]:
            self.basicTextLine.setText ( stepData["parameters"]["value"] )
            if stepData["parameters"]["from-cache"]:
                self.basicTextLine.setValidator(self.validatorAll)
                self.basicTextCombo.setCurrentIndex(INDEX_CACHE)
                
            elif stepData["parameters"]["from-alias"]:
                self.basicTextLine.setValidator(self.validatorUpper)
                self.basicTextCombo.setCurrentIndex(INDEX_ALIAS)
            else:
                self.basicTextLine.setValidator(self.validatorAll)
                self.basicTextCombo.setCurrentIndex(INDEX_TEXT)
                
            self.cacheKeyName.setText( stepData["parameters"]["key"] ) 
            
        if self.actionsComboBox.currentText() in [ GuiSteps.FRAMEWORK_CHECK_STRING ]:

            self.checkOutTextLine.setText ( stepData["parameters"]["value"] )
                        
            if stepData["parameters"]["from-cache"]:
                self.checkOutTextLine.setValidator(self.validatorAll)
                self.checkOutTextCombo.setCurrentIndex(INDEX_CACHE)
            elif stepData["parameters"]["from-alias"]:
                self.checkOutTextLine.setValidator(self.validatorUpper)
                self.checkOutTextCombo.setCurrentIndex(INDEX_ALIAS)
            else:
                self.checkOutTextLine.setValidator(self.validatorAll)
                self.checkOutTextCombo.setCurrentIndex(INDEX_TEXT)

            self.checkInTextLine.setText ( stepData["parameters"]["key"] )
            
            for i in xrange(self.checkComboBox.count()):
                item_text = self.checkComboBox.itemText(i)
                if unicode(stepData["parameters"]["operator"]) == unicode(item_text):
                    self.checkComboBox.setCurrentIndex(i)
                    break

        if self.actionsComboBox.currentText() in [ GuiSteps.FRAMEWORK_INTERACT ]:
            self.askTextLine.setText ( stepData["parameters"]["value"] )
            if stepData["parameters"]["from-cache"]:
                self.askTextLine.setValidator(self.validatorAll)
                self.askTextCombo.setCurrentIndex(INDEX_CACHE)
            elif stepData["parameters"]["from-alias"]:
                self.askTextLine.setValidator(self.validatorUpper)
                self.askTextCombo.setCurrentIndex(INDEX_ALIAS)
            else:
                self.askTextLine.setValidator(self.validatorAll)
                self.askTextCombo.setCurrentIndex(INDEX_TEXT)

            self.askTextCacheLine.setText ( stepData["parameters"]["key"] )
            
    def getTimeout(self):
        """
        Return timeout
        """
        return self.optionsDialog.timeoutLine.text() 
        
    def setTimeout(self, timeout):
        """
        Set the timeout
        """
        return self.optionsDialog.timeoutLine.setText(timeout) 
Beispiel #39
0
class RunDialog(QDialog):
    def __init__(self, run_model, parent):
        QDialog.__init__(self, parent)
        self.setWindowFlags(self.windowFlags()
                            & ~Qt.WindowContextHelpButtonHint)
        self.setWindowFlags(self.windowFlags() & ~Qt.WindowCloseButtonHint)
        self.setModal(True)
        self.setWindowModality(Qt.WindowModal)
        self.setWindowTitle("Simulations")

        assert isinstance(run_model, BaseRunModel)
        self._run_model = run_model

        layout = QVBoxLayout()
        layout.setSizeConstraint(QLayout.SetFixedSize)

        self.simulations_tracker = SimulationsTracker()
        states = self.simulations_tracker.getStates()

        self.total_progress = SimpleProgress()
        layout.addWidget(self.total_progress)

        status_layout = QHBoxLayout()
        status_layout.addStretch()
        self.__status_label = QLabel()
        status_layout.addWidget(self.__status_label)
        status_layout.addStretch()
        layout.addLayout(status_layout)

        self.progress = Progress()
        self.progress.setIndeterminateColor(self.total_progress.color)
        for state in states:
            self.progress.addState(state.state, QColor(*state.color),
                                   100.0 * state.count / state.total_count)

        layout.addWidget(self.progress)

        self.detailed_progress = None

        legend_layout = QHBoxLayout()
        self.legends = {}
        for state in states:
            self.legends[state] = Legend("%s (%d/%d)", QColor(*state.color))
            self.legends[state].updateLegend(state.name, 0, 0)
            legend_layout.addWidget(self.legends[state])

        layout.addLayout(legend_layout)

        self.running_time = QLabel("")

        ert = None
        if isinstance(run_model, BaseRunModel):
            ert = run_model.ert()

        self.plot_tool = PlotTool()
        self.plot_tool.setParent(None)
        self.plot_button = QPushButton(self.plot_tool.getName())
        self.plot_button.clicked.connect(self.plot_tool.trigger)
        self.plot_button.setEnabled(ert is not None)

        self.kill_button = QPushButton("Kill simulations")
        self.done_button = QPushButton("Done")
        self.done_button.setHidden(True)
        self.restart_button = QPushButton("Restart")
        self.restart_button.setHidden(True)
        self.show_details_button = QPushButton("Details")

        self.realizations_view = QListView()
        self.realizations_view.setModel(
            QStandardItemModel(self.realizations_view))
        self.realizations_view.setVisible(False)

        button_layout = QHBoxLayout()

        size = 20
        spin_movie = resourceMovie("ide/loading.gif")
        spin_movie.setSpeed(60)
        spin_movie.setScaledSize(QSize(size, size))
        spin_movie.start()

        self.processing_animation = QLabel()
        self.processing_animation.setMaximumSize(QSize(size, size))
        self.processing_animation.setMinimumSize(QSize(size, size))
        self.processing_animation.setMovie(spin_movie)

        button_layout.addWidget(self.processing_animation)
        button_layout.addWidget(self.running_time)
        button_layout.addStretch()
        button_layout.addWidget(self.show_details_button)
        button_layout.addWidget(self.plot_button)
        button_layout.addWidget(self.kill_button)
        button_layout.addWidget(self.done_button)
        button_layout.addWidget(self.restart_button)

        layout.addStretch()
        layout.addLayout(button_layout)

        layout.addWidget(self.realizations_view)

        self.setLayout(layout)

        self.kill_button.clicked.connect(self.killJobs)
        self.done_button.clicked.connect(self.accept)
        self.restart_button.clicked.connect(self.restart_failed_realizations)
        self.show_details_button.clicked.connect(self.show_detailed_progress)

        self.__updating = False
        self.__update_queued = False
        self.__simulation_started = False

        self.__update_timer = QTimer(self)
        self.__update_timer.setInterval(500)
        self.__update_timer.timeout.connect(self.updateRunStatus)
        self._simulations_argments = {}

    def startSimulation(self, arguments):

        self._simulations_argments = arguments

        if not 'prev_successful_realizations' in self._simulations_argments:
            self._simulations_argments['prev_successful_realizations'] = 0
        self._run_model.reset()

        def run():
            self._run_model.startSimulations(self._simulations_argments)

        simulation_thread = Thread(name="ert_gui_simulation_thread")
        simulation_thread.setDaemon(True)
        simulation_thread.run = run
        simulation_thread.start()

        self.__update_timer.start()

    def checkIfRunFinished(self):
        if self._run_model.isFinished():

            self.update_realizations_view()
            self.hideKillAndShowDone()

            if self._run_model.hasRunFailed():
                error = self._run_model.getFailMessage()
                QMessageBox.critical(
                    self, "Simulations failed!",
                    "The simulation failed with the following error:\n\n%s" %
                    error)
                self.reject()

    def updateRunStatus(self):
        self.checkIfRunFinished()

        self.total_progress.setProgress(self._run_model.getProgress())

        self.__status_label.setText(self._run_model.getPhaseName())

        states = self.simulations_tracker.getStates()

        if self._run_model.isIndeterminate():
            self.progress.setIndeterminate(True)

            for state in states:
                self.legends[state].updateLegend(state.name, 0, 0)

        else:
            if self.detailed_progress:
                self.detailed_progress.set_progress(
                    *self._run_model.getDetailedProgress())

            self.progress.setIndeterminate(False)
            total_count = self._run_model.getQueueSize()
            queue_status = self._run_model.getQueueStatus()

            for state in states:
                state.count = 0
                state.total_count = total_count

            for state in states:
                for queue_state in queue_status:
                    if queue_state in state.state:
                        state.count += queue_status[queue_state]

                self.progress.updateState(
                    state.state, 100.0 * state.count / state.total_count)
                self.legends[state].updateLegend(state.name, state.count,
                                                 state.total_count)

        self.setRunningTime()

    def setRunningTime(self):
        days = 0
        hours = 0
        minutes = 0
        seconds = self._run_model.getRunningTime()

        if seconds >= 60:
            minutes, seconds = divmod(seconds, 60)

        if minutes >= 60:
            hours, minutes = divmod(minutes, 60)

        if hours >= 24:
            days, hours = divmod(hours, 24)

        if days > 0:
            self.running_time.setText(
                "Running time: %d days %d hours %d minutes %d seconds" %
                (days, hours, minutes, seconds))
        elif hours > 0:
            self.running_time.setText(
                "Running time: %d hours %d minutes %d seconds" %
                (hours, minutes, seconds))
        elif minutes > 0:
            self.running_time.setText("Running time: %d minutes %d seconds" %
                                      (minutes, seconds))
        else:
            self.running_time.setText("Running time: %d seconds" % seconds)

    def killJobs(self):
        kill_job = QMessageBox.question(
            self, "Kill simulations?",
            "Are you sure you want to kill the currently running simulations?",
            QMessageBox.Yes | QMessageBox.No)

        if kill_job == QMessageBox.Yes:
            if self._run_model.killAllSimulations():
                self.reject()

    def hideKillAndShowDone(self):
        self.__update_timer.stop()
        self.processing_animation.hide()
        self.kill_button.setHidden(True)
        self.done_button.setHidden(False)
        self.realizations_view.setVisible(True)
        self.restart_button.setVisible(self.has_failed_realizations())
        self.restart_button.setEnabled(self._run_model.support_restart)

    def has_failed_realizations(self):
        completed = self._run_model.completed_realizations_mask
        initial = self._run_model.initial_realizations_mask
        for (index, successful) in enumerate(completed):
            if initial[index] and not successful:
                return True
        return False

    def count_successful_realizations(self):
        """
        Counts the realizations completed in the prevoius ensemble run
        :return:
        """
        completed = self._run_model.completed_realizations_mask
        return completed.count(True)

    def create_mask_from_failed_realizations(self):
        """
        Creates a BoolVector mask representing the failed realizations
        :return: Type BoolVector
        """
        completed = self._run_model.completed_realizations_mask
        initial = self._run_model.initial_realizations_mask
        inverted_mask = BoolVector(default_value=False)
        for (index, successful) in enumerate(completed):
            inverted_mask[index] = initial[index] and not successful
        return inverted_mask

    def restart_failed_realizations(self):

        msg = QMessageBox(self)
        msg.setIcon(QMessageBox.Information)
        msg.setText(
            "Note that workflows will only be executed on the restarted realizations and that this might have unexpected consequences."
        )
        msg.setWindowTitle("Restart Failed Realizations")
        msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
        result = msg.exec_()

        if result == QMessageBox.Ok:
            active_realizations = self.create_mask_from_failed_realizations()
            self._simulations_argments[
                'active_realizations'] = active_realizations
            self._simulations_argments[
                'prev_successful_realizations'] += self.count_successful_realizations(
                )
            self.startSimulation(self._simulations_argments)

    def update_realizations_view(self):
        completed = self._run_model.completed_realizations_mask
        for (index, successful) in enumerate(completed):
            items = self.realizations_view.model().findItems(str(index))
            if not items:
                item = QStandardItem(str(index))
                self.realizations_view.model().appendRow(item)
            else:
                item = items[0]
            item.setCheckState(successful or item.checkState())

    def show_detailed_progress(self):
        if not self.detailed_progress:
            self.detailed_progress = DetailedProgressDialog(
                self, self.simulations_tracker.getStates())
        self.detailed_progress.set_progress(
            *self._run_model.getDetailedProgress())
        self.detailed_progress.show()
Beispiel #40
0
class WDocumentProperties(QWidget, Logger.ClassLogger):
    """
    Document properties widget
    """
    RefreshLocalRepository = pyqtSignal()
    def __init__(self, parent=None, iRepo=None, lRepo=None, rRepo=None):
        """
        Widget document properties

        @param parent: 
        @type parent:

         / Description \_/ Parameters \_ / Probes \___
        |                                             |
        |                                             |
        | ____________________________________________|
        """
        QWidget.__init__(self, parent)
        
        self.descrs = None
        self.parameters = None
        self.probes = None
        self.agents = None
        self.steps = None
        self.adapters = None
        self.libraries = None
        self.parametersTab = None
        self.currentDoc = None
        self.currentTab = None
        self.iRepo = iRepo
        self.lRepo = lRepo # local repo dialog
        self.rRepo = rRepo # remote repo dialog
        self.wdoc  = None
        
        self.createActions()
        self.createWidgets()
        self.createConnections()    
        
        self.initToolbarParameters()

    def createWidgets(self):
        """
        Create qt widgets

        QTabWidget
         / QWidget \/ QWidget \_________________
        |                                       |
        | ______________________________________|
        """
        self.steps = Steps.StepsQWidget(self)
        self.descrs = Descriptions.DescriptionsQWidget(self)
        self.parameters = Parameters.ParametersQWidget(self)
        self.parametersOutput = Parameters.ParametersQWidget(self, forParamsOutput=True)
        self.probes = Probes.ProbesQWidget(self)
        self.agents = Agents.AgentsQWidget(self)
        self.adapters = Adapters.AdaptersQWidget(self, testParams=self, testDescrs=self.descrs)
        self.libraries = Libraries.LibrariesQWidget(self, testParams=self, testDescrs=self.descrs)
        
        self.parametersTab = QTabWidget()
        self.parametersTab.setTabPosition(QTabWidget.North)
        self.parametersTab.setStyleSheet("QTabWidget { border: 0px; }") # remove 3D border
        self.parametersTab.addTab(self.descrs, QIcon(":/test-config.png"), "Description")
        self.parametersTab.addTab(self.steps, QIcon(":/run-state.png"), "Steps")

        self.paramsTab = QTabWidget()
        self.paramsTab.setStyleSheet("QTabWidget { border: 0px; }") # remove 3D border
        self.paramsTab.setTabPosition(QTabWidget.North)
        self.paramsTab.addTab(self.parameters, QIcon(":/test-input.png"), "Inputs")
        self.paramsTab.addTab(self.parametersOutput, QIcon(":/test-output.png"), "Outputs")
        self.paramsTab.addTab(self.adapters, QIcon(":/adapters.png"), "Adapters")
        self.paramsTab.addTab(self.libraries, QIcon(":/libraries.png"), "Libraries")

        self.miscsTab = QTabWidget()
        self.miscsTab.setStyleSheet("QTabWidget { border: 0px; }") # remove 3D border
        self.miscsTab.setTabPosition(QTabWidget.North)
        self.miscsTab.addTab(self.agents, QIcon(":/agent.png"), "Agents")
        self.miscsTab.addTab(self.probes, QIcon(":/probe.png"), "Probes")

        self.title = QLabel("Test Properties")
        font = QFont()
        font.setBold(True)
        self.title.setFont(font)

        self.labelHelp = QLabel("Prepare the test.")
        font = QFont()
        font.setItalic(True)
        self.labelHelp.setFont(font)

        self.mainTab = QTabWidget()
        self.mainTab.setTabPosition(QTabWidget.North)
        
        self.mainTab.addTab(self.parametersTab, QIcon(":/test-description.png"), "Test Design")
        self.mainTab.addTab(self.paramsTab, QIcon(":/repository.png"), "Test Data")
        self.mainTab.addTab(self.miscsTab, QIcon(":/server-config.png"), "Miscellaneous")


        if Settings.instance().readValue( key = 'TestProperties/inputs-default-tab' ) == "True":
            self.mainTab.setCurrentIndex(1)
            self.paramsTab.setCurrentIndex(TAB_INPUTS)

        layout = QVBoxLayout()
        layout.addWidget( self.title )
        layout.addWidget( self.labelHelp )

        layout.addWidget(self.mainTab)
        layout.setContentsMargins(0,0,0,0)

        self.setLayout(layout)
    
    def hideWidgetsHeader(self):
        """
        Hide the title of the widget
        """
        self.title.hide()
        self.labelHelp.hide()
        
    def showWidgetsHeader(self):
        """
        Show widget header
        """
        self.title.show()
        self.labelHelp.show()
        
    def createConnections(self):
        """
        Create qt connections
         * DescriptionTableView <=> dataChanged
         * ParametersTableView <=> dataChanged
         * ProbesTableView <=> dataChanged
        """
        self.descrs.table().DataChanged.connect(self.dataChanged)

        self.parameters.table().DataChanged.connect(self.dataChanged)
        if Settings.instance().readValue( key = 'TestProperties/parameters-rename-auto' ) == "True":
            self.parameters.table().NameParameterUpdated.connect(self.inputNameChanged)
        self.parameters.table().NbParameters.connect(self.onUpdateInputsNumber)
        
        self.parametersOutput.table().DataChanged.connect(self.dataChanged)
        if Settings.instance().readValue( key = 'TestProperties/parameters-rename-auto' ) == "True":
            self.parametersOutput.table().NameParameterUpdated.connect(self.outputNameChanged)
        self.parametersOutput.table().NbParameters.connect(self.onUpdateOutputsNumber)
        
        self.probes.table().DataChanged.connect(self.dataChanged)
        self.agents.table().DataChanged.connect(self.dataChanged)

        # to support test abstract
        self.steps.table().DataChanged.connect(self.dataChanged)
        self.adapters.table().DataChanged.connect(self.dataChanged)
        self.libraries.table().DataChanged.connect(self.dataChanged)

    def createActions (self):
        """
        Actions defined:
         * import 
         * export
        """
        self.importAction = QtHelper.createAction(self, "&Import inputs", self.importInputs, 
                    icon = QIcon(":/tc-import.png"), tip = 'Import inputs from Test Config' )
        self.exportAction = QtHelper.createAction(self, "&Export inputs", self.exportInputs, 
                    icon = QIcon(":/tc-export.png"), tip = 'Export inputs as Test Config' )
        self.importOutputsAction = QtHelper.createAction(self, "&Import outputs", self.importOutputs, 
                    icon = QIcon(":/tc-import.png"), tip = 'Import outputs from Test Config' )
        self.exportOutputsAction = QtHelper.createAction(self, "&Export outputs", self.exportOutputs,
                    icon = QIcon(":/tc-export.png"), tip = 'Export outputs as Test Config' )
                    
        self.markUnusedAction = QtHelper.createAction(self, "&Mark unused inputs", self.markUnusedInputs,
                    icon = QIcon(":/input-unused.png"), tip = 'Marks all unused inputs' )
        self.markUnusedOutputsAction = QtHelper.createAction(self, "&Mark unused ouputs", self.markUnusedOutputs,
                    icon = QIcon(":/input-unused.png"), tip = 'Marks all unused outputs' )

    def onUpdateInputsNumber(self, nbParams):
        """
        On update the number of inputs in the tabulation name
        """
        self.paramsTab.setTabText(0, "Inputs (%s)" % nbParams )

    def onUpdateOutputsNumber(self, nbParams):
        """
        On update the number of outputs in the tabulation name
        """
        self.paramsTab.setTabText(1, "Outputs (%s)" % nbParams )
        
    def initToolbarParameters(self):
        """
        Init toolbar parameters
        """
        self.parameters.toolbar().addSeparator()
        self.parameters.toolbar().addAction(self.markUnusedAction)
        self.parameters.toolbar().addSeparator()
        self.parameters.toolbar().addAction(self.importAction)
        self.parameters.toolbar().addAction(self.exportAction)

        self.parametersOutput.toolbar().addSeparator()
        self.parametersOutput.toolbar().addAction(self.markUnusedOutputsAction)
        self.parametersOutput.toolbar().addSeparator()
        self.parametersOutput.toolbar().addAction(self.importOutputsAction)
        self.parametersOutput.toolbar().addAction(self.exportOutputsAction)
        
    def setDocument(self, wdoc):
        """
        Save the address to the document
        """
        self.wdoc = wdoc
        
    def enableMarkUnused(self):
        """
        Active the button mark inputs as unused
        """
        self.markUnusedAction.setEnabled(True)
        self.markUnusedOutputsAction.setEnabled(True)
        
    def disableMarkUnused(self):
        """
        Disable the mark button
        """
        self.markUnusedAction.setEnabled(False)
        self.markUnusedOutputsAction.setEnabled(False)
 
    def markUnusedInputs(self):
        """
        Mark all inputs unused
        """
        if self.wdoc is None: return
        
        editorExec = None
        editorSrc = None
        
        if isinstance(self.wdoc, TestUnit.WTestUnit):
            editorSrc = self.wdoc.srcEditor
            
        if isinstance(self.wdoc, TestSuite.WTestSuite):
            editorSrc = self.wdoc.srcEditor
            editorExec = self.wdoc.execEditor
        
        self.parameters.markUnusedInputs(editorSrc=editorSrc, editorExec=editorExec)
        
    def markUnusedOutputs(self):
        """
        Mark all outputs unused
        """
        if self.wdoc is None: return
        
        editorExec = None
        editorSrc = None
        
        if isinstance(self.wdoc, TestUnit.WTestUnit):
            editorSrc = self.wdoc.srcEditor
            
        if isinstance(self.wdoc, TestSuite.WTestSuite):
            editorSrc = self.wdoc.srcEditor
            editorExec = self.wdoc.execEditor
        
        self.parameters.markUnusedOutputs(editorSrc=editorSrc, editorExec=editorExec)
        
    def addNew(self):
        """
        Add item on parameters or probes 
        """
        self.currentTab.insertItem()

    def delSelection(self):
        """
        Delete selected item on parameters or probes 
        """
        self.currentTab.removeItem()

    def exportOutputs (self):
        """
        Export all outputs
        """
        return self.export(inputs=False)

    def exportInputs (self):
        """
        Export all inputs
        """
        return self.export(inputs=True)

    def export (self, inputs):
        """
        Export test config, dispatch to local, remote or other 
        """
        ret = False
        
        self.localConfigured = Settings.instance().readValue( key = 'Repositories/local-repo' )
        
        # first in local repo if configured
        if self.localConfigured != "Undefined": 
            buttons = QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel
            answer = QMessageBox.question(self, Settings.instance().readValue( key = 'Common/name' ), 
                            self.tr("Export to local repository") , buttons)
            if answer == QMessageBox.Yes:
                ret = self.saveToLocal(inputs=inputs)
            elif answer == QMessageBox.No:
                if RCI.instance().isAuthenticated: # no then perhaps in remo repo if connected?
                     ret = self.saveToRemote(inputs=inputs)
                else:
                    QMessageBox.warning(self, "Save" , "Connect to the test center first!")
        
        # not configured then in remo repo if connected ?
        elif RCI.instance().isAuthenticated:
             ret = self.saveToRemote(inputs=inputs)
        else:
            QMessageBox.warning(self, "Save" , "Connect to the test center first!")
        return ret 

    def splitFileName(self, fileName):
        """
        Split the filename
        """
        tmp = str(fileName).rsplit("/", 1)
        path = tmp[0]
        filename = tmp[1]
        return (path, filename)

    def saveToLocal(self, inputs=True):
        """
        Export test config to local repository
        """
        ret = False
        dialog = self.lRepo.SaveOpenToRepoDialog( parent=self, filename=DEFAULT_NAME )
        #
        if dialog.exec_() == QDialog.Accepted:
            fileName = dialog.getSelection()
            path, filename = self.splitFileName(fileName=fileName)
 
            doc = TestConfig.WTestConfig(self, path = path, filename=filename, extension=self.rRepo.EXTENSION_TCX) 
            if inputs:
                doc.dataModel.properties['properties']['parameters']['parameter'] = self.parameters.table().model.getData()
            else:
                doc.dataModel.properties['properties']['parameters']['parameter'] = self.parametersOutput.table().model.getData()
            ret = doc.write(force = True, fromExport=True)
            if ret:
                self.RefreshLocalRepository.emit()
        return ret

    def saveToRemote(self, inputs=True):
        """
        Export test config to remote repository
        """
        ret = False
        project = self.iRepo.remote().getCurrentProject()
        prjId = self.iRepo.remote().getProjectId(project=str(project))
        self.iRepo.remote().saveAs.setFilename(filename=DEFAULT_NAME, project=project)
        dialog = self.iRepo.remote().saveAs
        if dialog.exec_() == QDialog.Accepted:
            fileName = dialog.getSelection()
            path, filename = self.splitFileName(fileName=fileName)
            doc = TestConfig.WTestConfig(self,path = path, filename=filename, extension=self.rRepo.EXTENSION_TCX, remoteFile=True)
            if inputs:
                doc.dataModel.properties['properties']['parameters']['parameter'] = self.parameters.table().model.getData()
            else:
                doc.dataModel.properties['properties']['parameters']['parameter'] = self.parametersOutput.table().model.getData()
            
            # rest call
            RCI.instance().uploadTestFile(filePath=doc.path, 
                                          fileName=doc.filename, 
                                          fileExtension=doc.extension, 
                                          fileContent=doc.getraw_encoded(), 
                                          projectId=int(prjId), 
                                          updateMode=False, 
                                          closeTabAfter=False)
                       
            ret = True
        return ret

    def saveToAnywhere (self, inputs=True):
        """
        Save test config to anywhere
        Deprecated function
        """

        fileName = QFileDialog.getSaveFileName(self, "Export Test Config", "", "*.%s" % self.rRepo.EXTENSION_TCX )
        if fileName.isEmpty():
                return

        config = FileModelTestConfig.DataModel()
        if inputs:
            config.properties['properties']['parameters']['parameter'] = self.parameters.table().model.getData()
        else:
            config.properties['properties']['parameters']['parameter'] = self.parametersOutput.table().model.getData()
        config.write( absPath=fileName )
        del config

    def importOutputs(self):
        """
        Import all outputs
        """
        self.import__(inputs=False)

    def importInputs(self):
        """
        Import all inputs
        """
        self.import__(inputs=True)

    def import__(self, inputs):
        """
        Import test config, dispatch to local, remote or other 
        """
        # import from local repo
        self.localConfigured = Settings.instance().readValue( key = 'Repositories/local-repo' )
        if self.localConfigured != "Undefined":
            buttons = QMessageBox.Yes | QMessageBox.No
            answer = QMessageBox.question(self, Settings.instance().readValue( key = 'Common/name' ), 
                            self.tr("Import Test Config from local repository") , buttons)
            if answer == QMessageBox.Yes:
                self.loadFromLocal(inputs=inputs) # load local test config file
            else:
                if RCI.instance().isAuthenticated: # no then perhaps in remo repo if connected?
                    self.loadFromRemote(inputs=inputs) # load remote test config file
                else:
                    QMessageBox.warning(self, "Save" , "Connect to the test center first!")
        
        # import from remote repo
        elif RCI.instance().isAuthenticated: # no then perhaps in remo repo if connected?
            self.loadFromRemote(inputs=inputs) # load remote test config file
        else:
            QMessageBox.warning(self, "Save" , "Connect to the test center first!")        

    def loadFromRemote(self, inputs=True):
        """
        Load test config from remote repository
        """
        project = self.iRepo.remote().getCurrentProject()
        prjId = self.iRepo.remote().getProjectId(project=str(project))

        self.iRepo.remote().saveAs.getFilename(type=self.rRepo.EXTENSION_TCX, project=project)
        dialog = self.iRepo.remote().saveAs
        if dialog.exec_() == QDialog.Accepted:
            if inputs:
                RCI.instance().openFileTests(projectId=int(prjId), 
                                             filePath=dialog.getSelection(), 
                                             ignoreLock=False, 
                                             readOnly=False, 
                                             customParam=None, 
                                             actionId=UCI.ACTION_IMPORT_INPUTS, 
                                             destinationId=UCI.FOR_DEST_ALL)
            else:
                RCI.instance().openFileTests(projectId=int(prjId), 
                                             filePath=dialog.getSelection(), 
                                             ignoreLock=False, 
                                             readOnly=False, 
                                             customParam=None, 
                                             actionId=UCI.ACTION_IMPORT_OUTPUTS, 
                                             destinationId=UCI.FOR_DEST_ALL)
    def loadFromLocal(self, inputs=True):
        """
        Load test config from local repository
        """
        dialog = self.lRepo.SaveOpenToRepoDialog( self , "", type = self.lRepo.MODE_OPEN, typeFile=self.lRepo.EXTENSION_TCX ) 
        dialog.hideFiles(hideTsx=True, hideTpx=True, hideTcx=False, hideTdx=True)
        if dialog.exec_() == QDialog.Accepted:
            self.loadFromAnywhere(pathFilename=dialog.getSelection(), inputs=inputs)

    def loadFromAnywhere (self, pathFilename=None, inputs=True):
        """
        Load test config from anywhere
        Deprecated function

        @param pathFilename: 
        @type pathFilename: 
        """
        if pathFilename is None:
            fileName = QFileDialog.getOpenFileName(self, self.tr("Import File"), "", "Tcx Config Files (*.%s)" % self.rRepo.EXTENSION_TCX )
            # new in v18 to support qt5
            if QtHelper.IS_QT5:
                _fileName, _type = fileName
            else:
                _fileName = fileName
            # end of new
            
            if _fileName.isEmpty():
                return

            if not ( str(_fileName).endswith( self.rRepo.EXTENSION_TCX ) ):
                QMessageBox.critical(self, "Open Failed" , "File not supported")
                return
        else:
            _fileName=pathFilename
        
        config = FileModelTestConfig.DataModel()
        res = config.load( absPath = _fileName )
        if not res:
            QMessageBox.critical(self, "Open Failed" , "Corrupted file")
            return  
        
        if inputs:
            self.parameters.table().loadData(  data = config.properties['properties']['parameters'] )
            self.currentDoc.dataModel.properties['properties']['inputs-parameters'] = config.properties['properties']['parameters']
        else:
            self.parametersOutput.table().loadData(  data = config.properties['properties']['parameters'] )
            self.currentDoc.dataModel.properties['properties']['outputs-parameters'] = config.properties['properties']['parameters']

        self.currentDoc.setModify()

        del config

    def addRemoteTestConfigToTestsuite(self, data, inputs=True):
        """
        Add remote test config to a test

        @param data: 
        @type data: 
        """
        path_file, name_file, ext_file, encoded_data, project = data
        content = base64.b64decode(encoded_data)

        config = FileModelTestConfig.DataModel()
        res = config.load( rawData=content )
        if not res:
            QMessageBox.critical(self, "Open Failed" , "Corrupted file")
            return  
        
        if inputs:
            self.parameters.table().loadData(  data = config.properties['properties']['parameters'] )
            self.currentDoc.dataModel.properties['properties']['inputs-parameters'] = config.properties['properties']['parameters']
        else:
            self.parametersOutput.table().loadData(  data = config.properties['properties']['parameters'] )
            self.currentDoc.dataModel.properties['properties']['outputs-parameters'] = config.properties['properties']['parameters']
        self.currentDoc.setModify()
        del config

    def dataChanged (self):
        """
        Called when data on all table view changed
        On description
        """
        if self.currentDoc is not None:  
            if isinstance(self.currentDoc, self.lRepo.TestPlan.WTestPlan):
                self.currentDoc.updateStatsTestPlan()
            self.currentDoc.setModify()

    def clear (self):
        """
        Clear contents
        """
        self.descrs.clear()
        self.descrs.table().defaultActions()
        
        self.parameters.clear()
        self.parametersOutput.clear()
        
        self.probes.clear()
        self.agents.clear()
        
        self.steps.clear()
        self.adapters.clear()
        self.libraries.clear()

    def addDescriptions (self, wdoc):
        """
        Add description

        @param wdoc: 
        @type wdoc:
        """
        if isinstance(wdoc, TestData.WTestData):
            self.descrs.table().setDatasetView()
        else:
            self.descrs.table().setDefaultView()
        if type(wdoc) == dict:
            if not 'descriptions' in wdoc:
                wdoc['descriptions'] = { 'description': [  { 'key': 'author', 'value': '' }, 
                                                            { 'key':  'date', 'value':  '' },
                                                            { 'key': 'summary', 'value': '' } ] }
            self.descrs.table().loadData( data = wdoc['descriptions'] )
        else:
            self.currentDoc = wdoc
            data = wdoc.dataModel.properties['properties']['descriptions']
            self.descrs.table().loadData( data = data )
            self.descrs.table().setWdoc( wdoc=wdoc )

    def addAgents (self, wdoc):
        """
        Add agents

        @param wdoc: 
        @type wdoc:
        """
        if type(wdoc) == dict:
            self.agents.table().loadData( data = wdoc['agents'] )
        else:
            self.currentDoc = wdoc
            data = wdoc.dataModel.properties['properties']['agents']
            self.agents.table().loadData( data = data )

    def addParameters (self, wdoc):
        """
        Add parameters

        @param wdoc: 
        @type wdoc:
        """
        if isinstance(wdoc, TestData.WTestData):
            self.parameters.table().setDatasetView()
        else:
            self.parameters.table().setDefaultView()
        if type(wdoc) == dict:
            self.parameters.table().loadData( data = wdoc['inputs-parameters'] )
        else:
            self.currentDoc = wdoc
            data = wdoc.dataModel.properties['properties']['inputs-parameters']
            self.parameters.table().loadData( data = data )

    def addParametersOutput (self, wdoc):
        """
        Add parameters

        @param wdoc: 
        @type wdoc:
        """
        if isinstance(wdoc, TestData.WTestData):
            self.parametersOutput.table().setDatasetView()
        else:
            self.parametersOutput.table().setDefaultView()
        if type(wdoc) == dict:
            self.parametersOutput.table().loadData( data = wdoc['outputs-parameters'] )
        else:
            self.currentDoc = wdoc
            data = wdoc.dataModel.properties['properties']['outputs-parameters']
            self.parametersOutput.table().loadData( data = data )

    def addProbes (self, wdoc):
        """
        Add probes

        @param wdoc: 
        @type wdoc:
        """
        if type(wdoc) == dict:
            self.probes.table().loadData( data = wdoc['probes'] )
        else:
            self.currentDoc = wdoc
            data = wdoc.dataModel.properties['properties']['probes']
            self.probes.table().loadData(data = data)

    def addSteps (self, wdoc):
        """
        Add steps

        @param wdoc: 
        @type wdoc:
        """
        self.steps.table().setSteps(steps=wdoc.dataModel.steps['steps']['step'] )

    def addAdapters (self, wdoc):
        """
        Add adapters

        @param wdoc: 
        @type wdoc:
        """
        self.adapters.table().setAdapters(adapters=wdoc.dataModel.adapters['adapters']['adapter'] )

    def addLibraries (self, wdoc):
        """
        Add libraries

        @param wdoc: 
        @type wdoc:
        """
        self.libraries.table().setLibraries(libraries=wdoc.dataModel.libraries['libraries']['library'] )

    def disableOutputParameters(self):
        """
        Disable output parameters tabulation
        """
        self.parametersOutput.clear()
        self.paramsTab.setTabEnabled(TAB_OUTPUTS, False)

    def enableOutputParameters(self):
        """
        Enable output parameters tabulation
        """
        self.paramsTab.setTabEnabled(TAB_OUTPUTS, True)

    def disableAgents(self):
        """
        Disable agents tabulation
        """
        self.agents.clear()
        self.miscsTab.setTabEnabled(TAB_AGENTS, False)

    def enableAgents(self):
        """
        Enable agents tabulation
        """
        self.miscsTab.setTabEnabled(TAB_AGENTS, True)

    def disableProbes(self):
        """
        Disable probes tabulation
        """
        self.probes.clear()
        self.miscsTab.setTabEnabled(TAB_PROBES, False)

    def enableProbes(self):
        """
        Enable probes tabulation
        """
        self.miscsTab.setTabEnabled(TAB_PROBES, True)

    def disableSteps(self):
        """
        Disable steps tabulation
        """
        self.steps.clear()
        self.parametersTab.setTabEnabled(TAB_STEPS, False)

    def enableSteps(self):
        """
        Enable steps tabulation
        """
        self.parametersTab.setTabEnabled(TAB_STEPS, True)

    def disableAdapters(self):
        """
        Disable adapters tabulation
        """
        self.adapters.clear()
        self.paramsTab.setTabEnabled(TAB_ADAPTERS, False)

    def enableAdapters(self):
        """
        Enable adapters tabulation
        """
        self.paramsTab.setTabEnabled(TAB_ADAPTERS, True)

    def disableLibraries(self):
        """
        Disable libraries tabulation
        """
        self.libraries.clear()
        self.paramsTab.setTabEnabled(TAB_LIBRARIES, False)

    def enableLibraries(self):
        """
        Enable libraries tabulation
        """
        self.paramsTab.setTabEnabled(TAB_LIBRARIES, True)

    def inputNameChanged(self, oldName, newName):
        """
        On input name changed
        """
        if self.currentDoc is not None:
            if isinstance(self.currentDoc, TestUnit.WTestUnit):
                editor = self.currentDoc.srcEditor
                newText = editor.text().replace("input('%s')" % oldName, "input('%s')" % newName)
                editor.setText(newText)
            elif isinstance(self.currentDoc, TestSuite.WTestSuite):
                editorSrc = self.currentDoc.srcEditor
                editorExec = self.currentDoc.execEditor
                editorSrc.setText( editorSrc.text().replace("input('%s')" % oldName, "input('%s')" % newName) )
                editorExec.setText( editorExec.text().replace("input('%s')" % oldName, "input('%s')" % newName) )
            else:
                self.error('unknown file type')

    def outputNameChanged(self, oldName, newName):
        """
        On output name changed
        """
        if self.currentDoc is not None:
            if isinstance(self.currentDoc, TestUnit.WTestUnit):
                editor = self.currentDoc.srcEditor
                newText = editor.text().replace("output('%s')" % oldName, "output('%s')" % newName)
                editor.setText(newText)
            elif isinstance(self.currentDoc, TestSuite.WTestSuite):
                editorSrc = self.currentDoc.srcEditor
                editorExec = self.currentDoc.execEditor
                editorSrc.setText( editorSrc.text().replace("output('%s')" % oldName, "output('%s')" % newName) )
                editorExec.setText( editorExec.text().replace("output('%s')" % oldName, "output('%s')" % newName) )
            else:
                self.error('unknown file type')
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        self.clean_up_queue = []
        self.summoner = SummonerData()
        self.summoner.getStaticData()

        ### Search Bar ###
        ##################

        #label
        self.search_label = QLabel(self)
        self.search_label.move(20, 15)
        self.search_label.resize(220, 25)
        self.search_label.setText('Enter summoner name(s):')
        self.search_label.setStyleSheet("QLabel {font:14pt}")

        #text field
        self.search_field = QLineEdit(self)
        self.search_field.move(260, 15)
        self.search_field.resize(250, 25)
        self.search_field.setPlaceholderText("ex: mcnuggets, teltor, ...")
        self.search_field.setFocusPolicy(Qt.ClickFocus)

        #search button
        self.search_button = QPushButton(self)
        self.search_button.move(520, 15)
        self.search_button.resize(150, 25)
        self.search_button.setText('Search Summoner')

        #region combobox
        self.region_list = QComboBox(self)
        self.region_list.move(680, 15)
        self.region_list.resize(75, 25)
        regions = ['NA', 'LAN', 'BR', 'LAS', 'EUW', 'EUNE', 'TR', 'RU', 'OCE']
        self.region_list.addItems(regions)

        #error label
        self.error_label = QLabel(self)
        self.error_label.move(775, 15)
        self.error_label.resize(160, 25)
        self.error_label.setStyleSheet("QLabel {font:14pt}")

        ### Summoner Information ###
        ############################

        #summoner Icon label
        self.icon_label = QLabel(self)
        self.icon_label.setScaledContents(True)
        self.icon_label.move(260, 50)
        self.icon_label.resize(110, 110)

        #name label
        self.name_label = QLabel(self)
        self.name_label.move(380, 50)
        self.name_label.resize(620, 50)
        self.name_label.setText('SUMMONER NAME')
        self.name_label.setStyleSheet("QLabel {font:32pt}")

        #rank label
        self.rank_label = QLabel(self)
        self.rank_label.move(380, 100)
        self.rank_label.resize(200, 60)
        self.rank_label.setText('summoner rank')
        self.rank_label.setStyleSheet("QLabel {font:18pt}")

        #miniseries labels
        self.series_labels = {}
        self.pixmap_win = QPixmap()
        self.pixmap_loss = QPixmap()
        self.pixmap_n = QPixmap()
        self.pixmap_win.load("./images/win.png")
        self.pixmap_loss.load("./images/loss.png")
        self.pixmap_n.load("./images/n.png")
        xPos = 600
        for x in range(5):
            match_label = QLabel(self)
            match_label.move(xPos, 120)
            match_label.resize(35, 35)
            match_label.setScaledContents(True)
            match_label.hide()
            self.series_labels[x] = match_label
            xPos += 40

        #mastery image labels
        print 'loading mastery images ...'
        self.ferocity_tree_images = self.getMasteryImages(
            self.summoner.ferocityMasteryTree())
        self.cunning_tree_images = self.getMasteryImages(
            self.summoner.cunningMasteryTree())
        self.resolve_tree_images = self.getMasteryImages(
            self.summoner.resolveMasteryTree())
        print 'Done'

        #champion icon image labels
        print 'loading champion icon images ...'
        self.championIcons = self.getChampionIconImages(
            self.summoner.championList())
        print 'Done'

        #overview widget
        self.overview_widget = QWidget()
        self.overview_menu = QTabWidget(self.overview_widget)
        self.overview_menu.resize(720, 270)

        #runes widget
        self.runes_widget = QWidget()
        self.runes_menu = QTabWidget(self.runes_widget)
        self.runes_menu.resize(720, 270)

        #masteries widget
        self.masteries_widget = QWidget()
        self.masteries_menu = QTabWidget(self.masteries_widget)
        self.masteries_menu.resize(720, 270)

        #summoner menu
        self.menu = QTabWidget(self)
        self.menu.move(260, 180)
        self.menu.resize(720, 300)
        self.menu.addTab(self.overview_widget, "Overview")
        self.menu.addTab(self.runes_widget, "Runes")
        self.menu.addTab(self.masteries_widget, "Masteries")
        self.menu.hide()

        #summoners buttons
        self.button_list = {}
        yPos = 150
        for x in range(10):
            sum_button = QPushButton(self)
            sum_button.move(50, yPos)
            sum_button.resize(150, 25)
            sum_button.hide()
            self.button_list[x] = sum_button
            yPos += 25

        ### Connecting Widgets ###
        ##########################

        self.connect(self.search_button, QtCore.SIGNAL("clicked()"),
                     self.getData)
        self.connect(self.search_button, QtCore.SIGNAL("clicked()"),
                     self.getRankedData)
        self.connect(self.button_list[0], QtCore.SIGNAL("clicked()"),
                     lambda: self.displayData(str(self.button_list[0].text())))
        self.connect(self.button_list[1], QtCore.SIGNAL("clicked()"),
                     lambda: self.displayData(str(self.button_list[1].text())))
        self.connect(self.button_list[2], QtCore.SIGNAL("clicked()"),
                     lambda: self.displayData(str(self.button_list[2].text())))
        self.connect(self.button_list[3], QtCore.SIGNAL("clicked()"),
                     lambda: self.displayData(str(self.button_list[3].text())))
        self.connect(self.button_list[4], QtCore.SIGNAL("clicked()"),
                     lambda: self.displayData(str(self.button_list[4].text())))
        self.connect(self.button_list[5], QtCore.SIGNAL("clicked()"),
                     lambda: self.displayData(str(self.button_list[5].text())))
        self.connect(self.button_list[6], QtCore.SIGNAL("clicked()"),
                     lambda: self.displayData(str(self.button_list[6].text())))
        self.connect(self.button_list[7], QtCore.SIGNAL("clicked()"),
                     lambda: self.displayData(str(self.button_list[7].text())))
        self.connect(self.button_list[8], QtCore.SIGNAL("clicked()"),
                     lambda: self.displayData(str(self.button_list[8].text())))
        self.connect(self.button_list[9], QtCore.SIGNAL("clicked()"),
                     lambda: self.displayData(str(self.button_list[9].text())))

        ### Window Configuration ###
        ############################

        #window settings
        self.setGeometry(200, 150, 1000, 500)
        self.setMaximumSize(1000, 500)
        self.setWindowTitle('summoner App')

        self.show()
Beispiel #42
0
class FeatureFormWidget(Ui_Form, QWidget):
    # Raise the cancel event, takes a reason and a level
    canceled = pyqtSignal(str, int)
    featuresaved = pyqtSignal()
    featuredeleted = pyqtSignal()

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

        toolbar = QToolBar()
        size = QSize(48, 48)
        toolbar.setIconSize(size)
        style = Qt.ToolButtonTextUnderIcon
        toolbar.setToolButtonStyle(style)
        self.actionDelete = toolbar.addAction(QIcon(":/icons/delete"),
                                              "Delete")
        self.actionDelete.triggered.connect(self.delete_feature)

        label = '<b style="color:red">*</b> Required fields'
        self.missingfieldsLabel = QLabel(label)
        self.missingfieldsLabel.hide()
        self.missingfieldaction = toolbar.addWidget(self.missingfieldsLabel)

        titlespacer = QWidget()
        titlespacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        toolbar.addWidget(titlespacer)
        self.titlellabel = QLabel(label)
        self.titlellabel.setProperty("headerlabel", True)
        self.titlelabelaction = toolbar.addWidget(self.titlellabel)

        spacer = QWidget()
        spacer2 = QWidget()
        spacer2.setMinimumWidth(40)
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        spacer2.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        toolbar.addWidget(spacer)
        self.actionCancel = toolbar.addAction(QIcon(":/icons/cancel"),
                                              "Cancel")
        toolbar.addWidget(spacer2)
        self.actionSave = toolbar.addAction(QIcon(":/icons/save"), "Save")
        self.actionSave.triggered.connect(self.save_feature)

        self.layout().setContentsMargins(0, 3, 0, 3)
        self.layout().insertWidget(0, toolbar)
        self.actiontoolbar = QToolBar()
        self.actiontoolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.actiontoolbar.addWidget(spacer)
        self.layout().insertWidget(1, self.actiontoolbar)

        self.flickwidget = FlickCharm()
        self.flickwidget.activateOn(self.scrollArea)

        self.featureform = None
        self.values = {}
        self.config = {}
        self.feature = None

    def set_featureform(self, featureform):
        """
        Note: There can only be one feature form.  If you need to show another one make a new FeatureFormWidget
        """
        self.featureform = featureform
        self.titlellabel.setText(self.featureform.windowTitle())
        self.featureform.formvalidation.connect(self._update_validation)
        self.featureform.helprequest.connect(
            functools.partial(RoamEvents.helprequest.emit, self))
        self.featureform.showlargewidget.connect(RoamEvents.show_widget.emit)
        self.featureform.enablesave.connect(self.actionSave.setEnabled)
        self.featureform.enablesave.connect(self.actionSave.setVisible)
        self.featureform.rejected.connect(self.canceled.emit)
        self.featureform.accepted.connect(self.featuresaved)

        actions = self.featureform.form_actions()
        if actions:
            for action in actions:
                self.actiontoolbar.addAction(action)
        else:
            self.actiontoolbar.hide()

        self.featureform.setContentsMargins(0, 0, 0, 0)
        self.featureformarea.layout().addWidget(self.featureform)

    def delete_feature(self):
        try:
            msg = self.featureform.deletemessage
        except AttributeError:
            msg = 'Do you really want to delete this feature?'

        box = DeleteFeatureDialog(msg)

        if not box.exec_():
            return

        try:
            self.featureform.delete()
        except featureform.DeleteFeatureException as ex:
            RoamEvents.raisemessage(*ex.error)

        self.featureform.featuredeleted(self.feature)
        self.featuredeleted.emit()

    def feature_saved(self):
        self.featuresaved.emit()
        RoamEvents.featuresaved.emit()

    def save_feature(self):
        try:
            self.featureform.save()
        except featureform.MissingValuesException as ex:
            RoamEvents.raisemessage(*ex.error)
            return
        except featureform.FeatureSaveException as ex:
            RoamEvents.raisemessage(*ex.error)

        self.feature_saved()

    def set_config(self, config):
        self.config = config
        editmode = config['editmode']
        allowsave = config.get('allowsave', True)
        self.feature = config.get('feature', None)
        tools = config.get('tools', [])
        candelete = True
        if tools:
            candelete = "delete" in tools
        self.featureform.feature = self.feature
        self.featureform.editingmode = editmode
        self.actionDelete.setVisible(editmode and candelete)
        self.actionSave.setEnabled(allowsave)

    def _update_validation(self, passed):
        # Show the error if there is missing fields
        self.missingfieldaction.setVisible(not passed)

    def bind_values(self, values):
        self.values = values
        self.featureform.bindvalues(values)

    def after_load(self):
        self.featureform.loaded()

    def before_load(self):
        self.featureform.load(self.config['feature'], self.config['layers'],
                              self.values)
Beispiel #43
0
class Entity(QWidget):

    def __init__(self, base_image, parent=None):
        super().__init__(parent)
        self._base_label = QLabel(self)
        self._base_image = base_image

        self._decor_label = QLabel(self)
        self._decor_pixmap = None

        self.__pixmap = None
        """:type: PyQt4.QtGui.QPixmap"""

        self.__cord_x = 0
        self.__cord_y = 0
        self.__angle = 0
        self.setAlignment(Qt.AlignCenter)
        self.updatePixmap()

        if _debugging:
            self.setStyleSheet("border: 1px solid black")

    @property
    def angle(self):
        return self.__angle

    @angle.setter
    def angle(self, angle):
        self.__angle = angle
        self.updatePixmap()

    @property
    def cord_x(self):
        return self.__cord_x

    @cord_x.setter
    def cord_x(self, cord):
        self.__cord_x = cord
        self.move(self.cord_x, self.cord_y)

    @property
    def cord_y(self):
        return self.__cord_y

    @cord_y.setter
    def cord_y(self, cord):
        self.__cord_y = cord
        self.move(self.cord_x, self.cord_y)

    def add_decoration(self, path):
        if path is None:
            self._decor_label.hide()
        else:
            self._decor_label = QLabel(self)
            self._decor_pixmap = QPixmap(path)
            self._decor_pixmap = self._decor_pixmap.scaled(self._decor_pixmap.width() * _SCALE,
                                                           self._decor_pixmap.height() * _SCALE)
            self._decor_pixmap = self._decor_pixmap.transformed(QTransform().rotate(self.angle))
            self._decor_label.setPixmap(self._decor_pixmap)

    def updatePixmap(self):
        path = _PATH + os.sep + "assets" + os.sep + self._base_image
        self.__pixmap = QPixmap(path)
        self.__pixmap = self.__pixmap.scaled(self.__pixmap.width()*_SCALE, self.__pixmap.height()*_SCALE)
        self.__pixmap = self.__pixmap.transformed(QTransform().rotate(self.angle))
        self._base_label.setPixmap(self.__pixmap)
        self.setFixedSize(self.__pixmap.width(), self.__pixmap.height())

    def setFixedSize(self, x, y):
        super().setFixedSize(x, y)
        self._base_label.setFixedSize(x, y)

    def setAlignment(self, alignment):
        self._base_label.setAlignment(alignment)
        self._decor_label.setAlignment(alignment)
Beispiel #44
0
class parcial(QWidget):
    def __init__(self):

        self.ingresar = QApplication(sys.argv)
        super(parcial, self).__init__(None)

        self.ingreso = QWidget()
        self.ingreso.resize(440, 320)
        self.ingreso.setWindowTitle('Autenticacion de Ingreso')

        self.sistema = QWidget()
        self.sistema.resize(480, 320)
        self.sistema.setWindowTitle('Identificador de Numeros Telefonicos')

    def inicio(self, u=0, c=0):

        self.imaje = QLabel(self.ingreso)
        self.imaje.setGeometry(10, 10, 225, 225)
        self.imaje.setPixmap(QPixmap(getcwd() + "/logo.gif"))

        self.u = QLabel('Nombre de Usuario:', self.ingreso)
        self.u.move(288, 162)

        self.c = QLabel('Clave:', self.ingreso)
        self.c.move(333, 202)

        self.m = QLabel('Usuario y(o) Clave Incorrecta', self.ingreso)
        self.m.move(250, 303)
        self.m.hide()

        self.User = QLineEdit(self.ingreso)
        self.User.setGeometry(280, 180, 140, 20)

        self.Pass = QLineEdit(self.ingreso)
        self.Pass.setGeometry(280, 220, 140, 20)

        self.entra = QPushButton('Entrar', self.ingreso)
        self.entra.setGeometry(320, 260, 60, 30)

        self.ingreso.connect(self.entra, SIGNAL('clicked()'),
                             lambda: self.revisar(self.User, self.Pass))

        self.ingreso.show()

        sys.exit(self.ingresar.exec_())

    def revisar(self, user, passw, flag=0):

        u = user.text()
        c = passw.text()
        #print u+''+c
        login = open('login.txt', 'rU')
        for i in login:
            if i == u + ',' + c + '\n':
                flag = 1
                self.m.hide()
                m = menu()
                m.exec_()

        if flag == 0:
            self.m.show()

        self.ingreso.update()
        login.close()
class ComponentSearchForm():

    data_source = None
    
    related_mashups = None
    
    widget = None
    
    table = None
    
    add_btn = None
    
    graph_form = None
    
    highlighted_api = None
    
    highlighted_mashup = None
    
    def show_main_window(self):
        self.graph_form = matplotlibWidget()
        if self.widget:
            self.widget.destroy()
            self.widget = None;
        self.widget = QWidget()
        self.widget.setMinimumSize(800, 600)
        btn_api = QtGui.QPushButton("Recommend Modules", self.widget)
        btn_api.move(30, 20)

        btn_mashup = QtGui.QPushButton("Recommend Workflows", self.widget)
        btn_mashup.move(200, 20)

        self.textboxLabel = QLabel(self.widget)
        self.textboxLabel.setText("Describe your goals:")
        self.textboxLabel.move(35, 60)
        self.textboxLabel.show
        
        self.textbox = QTextEdit(self.widget)
        self.textbox.move(30, 80)
        self.textbox.setFixedWidth(300)
        self.textbox.setFixedHeight(28)

        btn_api.clicked.connect(self.api_button_clicked)
        btn_mashup.clicked.connect(self.mashups_button_clicked)

        self.table = QTableView(self.widget)
        self.table.clicked.connect(self.table_clicked)
        self.table.setMinimumSize(740, 500)
        self.table.resizeColumnsToContents()
        self.table.move(30, 120)

        self.widget.show()
        
        self.add_btn = QPushButton(self.widget)
        self.add_btn.clicked.connect(self.add_new_api)
        self.add_btn.setText("Add to Palette")
        self.add_btn.hide()
        self.add_btn.move(650, 20)
        
        self.recommendLabel = QLabel(self.widget)
        self.recommendLabel.setText("Also Used")
        self.recommendLabel.move(30, 95)
        self.recommendLabel.hide()
        
        self.switch_btn_apis = QPushButton(self.widget)
        self.switch_btn_apis.clicked.connect(self._show_related_apis)
        self.switch_btn_apis.setText("Related Mashup")
        self.switch_btn_apis.move(500, 20)
        self.switch_btn_apis.hide()
        
        self.switch_btn_mashups = QPushButton(self.widget)
        self.switch_btn_mashups.clicked.connect(self._show_related_mashups)
        self.switch_btn_mashups.setText("Related API")
        self.switch_btn_mashups.move(500, 20)
        self.switch_btn_mashups.hide()

    def __init__(self, parent=None):
        self.data_source = DataSource()
        
    def table_clicked(self):
        """
        Click the table, the graph form may change according to the selection.
        """
        model = self.table.selectionModel()
        indexes = model.selectedIndexes()
        for index in indexes:
            row = index.row()
            data = index.model().headerData(0,Qt.Horizontal).toString()
            newIndex = index.model().index(row, 0)
            if data == "API":
                api_id = get_api_full_name(newIndex.model().data(newIndex).toString())
                api = self.data_source.api_by_id(api_id)
                print api
                mashups = self.data_source.mashups_by_api(api)
                apis = []
                for mashup in mashups:
                    apis.extend(self.data_source.apis_by_mashup(mashup))
                self.graph_form.draw_apis(apis, api, self.highlighted_api)
            else:
                mashup_id = get_mashup_full_name(newIndex.model().data(newIndex).toString())
                mashup = self.data_source.mashup_by_id(mashup_id)
                if not mashup:
                    return
                apis = self.data_source.apis_by_mashup(mashup)
                mashups = []
                if len(apis) > 0:
                    mashups.extend(self.data_source.mashups_by_api(apis[0]))
                self.graph_form.draw_mashups(mashups, mashup, self.highlighted_mashup)
            return


    def _show_apis(self, apis, recommend=False):
        self.switch_btn_apis.hide()
        self.switch_btn_mashups.hide()
        self.recommendLabel.hide()

        row = 0
        model = QStandardItemModel(len(apis), 4)
        model.setColumnCount(4)
        for api in apis:
            model.setData(model.index(row, 0), QVariant(get_api_name(api)))
            model.setData(model.index(row, 1), QVariant(api['protocols']))
            model.setData(model.index(row, 2), QVariant(api['provider']))
            model.setData(model.index(row, 3), QVariant(api['version']))
            row += 1

        model.setHeaderData(0, Qt.Horizontal, QVariant("Module"))
        model.setHeaderData(1, Qt.Horizontal, QVariant("Protocol"))
        model.setHeaderData(2, Qt.Horizontal, QVariant("Provider"))
        model.setHeaderData(3, Qt.Horizontal, QVariant("Version"))

#        model.setHeaderData(0, Qt.Horizontal, QVariant("API"))
#        model.setHeaderData(1, Qt.Horizontal, QVariant("Protocols"))
#        model.setHeaderData(2, Qt.Horizontal, QVariant("Provider"))
#        model.setHeaderData(3, Qt.Horizontal, QVariant("Version"))

        self.table.setModel(model)
        self.table.resizeColumnsToContents()
        
        if recommend:
            self.recommendLabel.show()
        
        self.add_btn.show()

    def _show_mashups(self, mashups):
        self.switch_btn_apis.hide()
        self.switch_btn_mashups.hide()
        self.recommendLabel.hide()

        row = 0
        model = QStandardItemModel(len(mashups), 4)
        model.setColumnCount(4)
        for mashup in mashups:
            model.setData(model.index(row, 0), QVariant(get_mashup_name(mashup)))
            model.setData(model.index(row, 1), QVariant(mashup['title']))
            model.setData(model.index(row, 2), QVariant(mashup['self']))
            model.setData(model.index(row, 3), QVariant(mashup['description']))
            
            row += 1
        
        model.setHeaderData(0, Qt.Horizontal, QVariant("Workflow"))
        model.setHeaderData(1, Qt.Horizontal, QVariant("Short Description"))
        model.setHeaderData(2, Qt.Horizontal, QVariant("Provider"))
        model.setHeaderData(3, Qt.Horizontal, QVariant("Detailed Info"))

#        model.setHeaderData(0, Qt.Horizontal, QVariant("Info"))
#        model.setHeaderData(1, Qt.Horizontal, QVariant("Title"))
#        model.setHeaderData(2, Qt.Horizontal, QVariant("self"))
#        model.setHeaderData(3, Qt.Horizontal, QVariant("Description"))

        self.table.setModel(model)
        self.table.resizeColumnsToContents()
        self.add_btn.show()

    def api_button_clicked(self):
        """
        Trigger to search APIs
        """        
        self.graph_form.draw_api()
        self.graph_form.show()

        apis = self.data_source.apis()
        key = str(self.textbox.toPlainText())
        #Has key or not has key, it is different.
        if key:
            self.api_search_button_clicked()
        else:
            self._show_apis(apis)

    def mashups_button_clicked(self):
        """
        Trigger to search mashups
        """
        self.graph_form.draw_mashup()
        self.graph_form.show()

        key = str(self.textbox.toPlainText())
        if key:
            self.mashup_search_button_clicked()
        else:
            self._show_mashups(self.data_source.mashups())

    #Should probably refactor this into one method.
    def api_search_button_clicked(self):
        """
        Search when no keyword
        """
        self.highlighted_api = None
        self.highlighted_mashup = None
        key = str(self.textbox.toPlainText())
        if key != "":
            apis = self.data_source.search_api(key)
            self._show_apis(apis)

    def mashup_search_button_clicked(self):
        """
        Search when no keyword
        """
        self.highlighted_api = None
        self.highlighted_mashup = None
        key = str(self.textbox.toPlainText())
        if key != "":
            mashups = self.data_source.search_mashup(key)
            self._show_mashups(mashups)
    
    def add_new_api(self):
        """
        Add new api to the modules package.
        """
        apis = self.data_source.apis()
        model = self.table.selectionModel()
        indexes = model.selectedIndexes()
        for index in indexes:
            api = apis[index.row()]
            self._add_new_api(api)
            return
    
    def add_related_api(self):
        objs = []
        for mashup in self.related_mashups:
            objs.append(mashup)
            for api in mashup["related_mashups"]:
                objs.append(api)
        model = self.table.selectionModel()
        indexes = model.selectedIndexes()
        for index in indexes:
            api = objs[index.row()]
            if api.get("protocols"):
                self._add_new_api(api)
                return

    def _show_related_mashups(self):
        self.switch_btn_apis.hide()
        self.switch_btn_mashups.hide()
        self.recommendLabel.hide()
        
        apis = []
        objs = []
        for mashup in self.related_mashups:
            apis.extend(mashup["related_mashups"])

        for api in apis:
            objs.append(api)
            mashups = self.data_source.mashups_by_api(api)
            objs.extend(mashups)

        row = 0
        model = QStandardItemModel(len(objs), 4)
        model.setColumnCount(4)
        for obj in objs:
            if obj.get('protocols'):
                model.setData(model.index(row, 0), QVariant(get_api_name(obj)))
                model.setData(model.index(row, 1), QVariant(obj['protocols']))
                model.setData(model.index(row, 2), QVariant(obj['provider']))
            else:
                model.setData(model.index(row, 3), QVariant(get_mashup_name(obj)))
            row += 1

        model.setHeaderData(0, Qt.Horizontal, QVariant("API"))
        model.setHeaderData(1, Qt.Horizontal, QVariant("Protocols"))
        model.setHeaderData(2, Qt.Horizontal, QVariant("Provider"))
        model.setHeaderData(3, Qt.Horizontal, QVariant("Mashup"))
        self.table.setModel(model)
        self.table.resizeColumnsToContents()
        self.switch_btn_apis.show()

    def _show_related_apis(self):
        self.switch_btn_apis.hide()
        self.switch_btn_mashups.hide()
        self.recommendLabel.hide()
        
        row = 0
        objs = []
        for mashup in self.related_mashups:
            objs.append(mashup)
            for api in mashup["related_mashups"]:
                objs.append(api)
        #Combining similarity and related.
        similar_apis = self.data_source.search_api_similarity(self.highlighted_api)
        #return str(mashup['id'])[(len("http://www.programmableweb.com/mashup/")):]
        objs.append({'id': "http://www.programmableweb.com/mashup/Using-Similarity-Metric"})
        objs.extend(similar_apis)
        #Combining similarity and related.

        model = QStandardItemModel(len(objs), 5)
        for obj in objs:
            if obj.get('protocols'):
                model.setData(model.index(row, 1), QVariant(get_api_name(obj)))
                model.setData(model.index(row, 2), QVariant(obj['protocols']))
                model.setData(model.index(row, 3), QVariant(obj['provider']))
                model.setData(model.index(row, 4), QVariant(obj['version']))
            else:
                model.setData(model.index(row, 0), QVariant(get_mashup_name(obj)))
            row += 1

        model.setHeaderData(0, Qt.Horizontal, QVariant("Mashup"))
        model.setHeaderData(1, Qt.Horizontal, QVariant("API"))
        model.setHeaderData(2, Qt.Horizontal, QVariant("Protocols"))
        model.setHeaderData(3, Qt.Horizontal, QVariant("Provider"))
        model.setHeaderData(4, Qt.Horizontal, QVariant("Version"))

        self.table.setModel(model)
        self.switch_btn_mashups.show()

    def _add_new_api(self, api):
        self.highlighted_api = api
        mashups = self.data_source.mashups_by_api(api)
        for mashup in mashups:
            mashup['related_mashups'] = (self.data_source.apis_by_mashup(mashup))
        if len(mashups) > 0:
            self.related_mashups = mashups
            self._show_related_apis()
        manager = core.packagemanager.get_package_manager()
        reg = core.modules.module_registry.get_module_registry()
        package = manager.get_package("edu.cmu.sv.components", "1.0.0")
        core.modules.module_registry.set_current_package(package)

        if (api["protocols"] == "SOAP" and api["wsdl"] != ""):
            s = Service(api["wsdl"])
            add_new_service(s, api["wsdl"])
        else:
            new_module = vistrails_module.new_module(Module, get_api_name(api))
            reg.add_module(new_module)
    
            reg.add_input_port(new_module, "value1",
                         (core.modules.basic_modules.String, 'the first argument'))
            reg.add_input_port(new_module, "value2",
                         (core.modules.basic_modules.String, 'the second argument'))
            reg.add_output_port(new_module, "value",
                          (core.modules.basic_modules.String, 'the result'))
Beispiel #46
0
class RunDialog(QDialog):

    def __init__(self, run_model):
        QDialog.__init__(self)
        self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint)
        self.setWindowFlags(self.windowFlags() & ~Qt.WindowCloseButtonHint)
        self.setModal(True)
        self.setWindowTitle("Simulations")

        assert isinstance(run_model, RunModelMixin)
        self.__run_model = run_model

        layout = QVBoxLayout()
        layout.setSizeConstraint(QLayout.SetFixedSize)

        self.simulations_tracker = SimulationsTracker()
        states = self.simulations_tracker.getList()

        self.total_progress = SimpleProgress()
        layout.addWidget(self.total_progress)


        status_layout = QHBoxLayout()
        status_layout.addStretch()
        self.__status_label = QLabel()
        status_layout.addWidget(self.__status_label)
        status_layout.addStretch()
        layout.addLayout(status_layout)

        self.progress = Progress()
        self.progress.setIndeterminateColor(self.total_progress.color)
        for state in states:
            self.progress.addState(state.state, QColor(*state.color), 100.0 * state.count / state.total_count)

        layout.addWidget(self.progress)

        legend_layout = QHBoxLayout()
        self.legends = {}
        for state in states:
            self.legends[state] = Legend("%s (%d/%d)", QColor(*state.color))
            self.legends[state].updateLegend(state.name, 0, 0)
            legend_layout.addWidget(self.legends[state])

        layout.addLayout(legend_layout)

        self.running_time = QLabel("")

        ert = None
        if isinstance(run_model, ErtConnector):
            ert = run_model.ert()

        self.plot_tool = PlotTool(ert)
        self.plot_tool.setParent(self)
        self.plot_button = QPushButton(self.plot_tool.getName())
        self.plot_button.clicked.connect(self.plot_tool.trigger)
        self.plot_button.setEnabled(ert is not None)
        
        self.kill_button = QPushButton("Kill simulations")
        self.done_button = QPushButton("Done")
        self.done_button.setHidden(True)

        button_layout = QHBoxLayout()

        size = 20
        spin_movie = util.resourceMovie("ide/loading.gif")
        spin_movie.setSpeed(60)
        spin_movie.setScaledSize(QSize(size, size))
        spin_movie.start()

        self.processing_animation = QLabel()
        self.processing_animation.setMaximumSize(QSize(size, size))
        self.processing_animation.setMinimumSize(QSize(size, size))
        self.processing_animation.setMovie(spin_movie)

        button_layout.addWidget(self.processing_animation)
        button_layout.addWidget(self.running_time)
        button_layout.addStretch()
        button_layout.addWidget(self.plot_button)
        button_layout.addWidget(self.kill_button)
        button_layout.addWidget(self.done_button)

        layout.addStretch()
        layout.addLayout(button_layout)

        self.setLayout(layout)

        self.kill_button.clicked.connect(self.killJobs)
        self.done_button.clicked.connect(self.accept)

        self.__updating = False
        self.__update_queued = False
        self.__simulation_started = False

        self.__update_timer = QTimer(self)
        self.__update_timer.setInterval(500)
        self.__update_timer.timeout.connect(self.updateRunStatus)


    def startSimulation(self):
        self.__run_model.reset( )

        simulation_thread = Thread(name="ert_gui_simulation_thread")
        simulation_thread.setDaemon(True)
        simulation_thread.run = self.__run_model.startSimulations
        simulation_thread.start()

        self.__update_timer.start()


    def checkIfRunFinished(self):
        if self.__run_model.isFinished():
            self.hideKillAndShowDone()

            if self.__run_model.hasRunFailed():
                error = self.__run_model.getFailMessage()
                QMessageBox.critical(self, "Simulations failed!", "The simulation failed with the following error:\n\n%s" % error)
                self.reject()


    def updateRunStatus(self):
        self.checkIfRunFinished()

        self.total_progress.setProgress(self.__run_model.getProgress())

        self.__status_label.setText(self.__run_model.getPhaseName())

        states = self.simulations_tracker.getList()

        if self.__run_model.isIndeterminate():
            self.progress.setIndeterminate(True)

            for state in states:
                self.legends[state].updateLegend(state.name, 0, 0)

        else:
            self.progress.setIndeterminate(False)
            total_count = self.__run_model.getQueueSize()
            queue_status = self.__run_model.getQueueStatus()

            for state in states:
                state.count = 0
                state.total_count = total_count

            for state in states:
                for queue_state in queue_status:
                    if queue_state in state.state:
                        state.count += queue_status[queue_state]

                self.progress.updateState(state.state, 100.0 * state.count / state.total_count)
                self.legends[state].updateLegend(state.name, state.count, state.total_count)

        self.setRunningTime()


    def setRunningTime(self):
        days = 0
        hours = 0
        minutes = 0
        seconds = self.__run_model.getRunningTime()

        if seconds >= 60:
            minutes, seconds = divmod(seconds, 60)

        if minutes >= 60:
            hours, minutes = divmod(minutes, 60)

        if hours >= 24:
            days, hours = divmod(hours, 24)

        if days > 0:
            self.running_time.setText("Running time: %d days %d hours %d minutes %d seconds" % (days, hours, minutes, seconds))
        elif hours > 0:
            self.running_time.setText("Running time: %d hours %d minutes %d seconds" % (hours, minutes, seconds))
        elif minutes > 0:
            self.running_time.setText("Running time: %d minutes %d seconds" % (minutes, seconds))
        else:
            self.running_time.setText("Running time: %d seconds" % seconds)


    def killJobs(self):
        kill_job = QMessageBox.question(self, "Kill simulations?", "Are you sure you want to kill the currently running simulations?", QMessageBox.Yes | QMessageBox.No )

        if kill_job == QMessageBox.Yes:
            self.__run_model.killAllSimulations()
            self.reject()


    def hideKillAndShowDone(self):
        self.__update_timer.stop()
        self.processing_animation.hide()
        self.kill_button.setHidden(True)
        self.done_button.setHidden(False)
Beispiel #47
0
class RunWidget(QWidget):

    """Widget that show the execution output in the MiscContainer."""

    def __init__(self):
        QWidget.__init__(self)
        vbox = QVBoxLayout(self)
        vbox.setSpacing(0)
        vbox.setContentsMargins(0, 0, 0, 0)
        self.output = OutputWidget(self)
        hbox = QHBoxLayout()
        self.input = QLineEdit()
        self.lblInput = QLabel(self.tr("Input:"))
        vbox.addWidget(self.output)
        hbox.addWidget(self.lblInput)
        hbox.addWidget(self.input)
        vbox.addLayout(hbox)

        #process
        self.currentProcess = None
        self.__preScriptExecuted = False
        self._proc = QProcess(self)
        self._preExecScriptProc = QProcess(self)
        self._postExecScriptProc = QProcess(self)
        self.connect(self._proc, SIGNAL("readyReadStandardOutput()"),
            self.output._refresh_output)
        self.connect(self._proc, SIGNAL("readyReadStandardError()"),
            self.output._refresh_error)
        self.connect(self._proc, SIGNAL("finished(int, QProcess::ExitStatus)"),
            self.finish_execution)
        self.connect(self._proc, SIGNAL("error(QProcess::ProcessError)"),
            self.process_error)
        self.connect(self.input, SIGNAL("returnPressed()"), self.insert_input)
        self.connect(self._preExecScriptProc,
            SIGNAL("finished(int, QProcess::ExitStatus)"),
            self.__main_execution)
        self.connect(self._preExecScriptProc,
            SIGNAL("readyReadStandardOutput()"), self.output._refresh_output)
        self.connect(self._preExecScriptProc,
            SIGNAL("readyReadStandardError()"), self.output._refresh_error)
        self.connect(self._postExecScriptProc,
            SIGNAL("finished(int, QProcess::ExitStatus)"),
            self.__post_execution_message)
        self.connect(self._postExecScriptProc,
            SIGNAL("readyReadStandardOutput()"), self.output._refresh_output)
        self.connect(self._postExecScriptProc,
            SIGNAL("readyReadStandardError()"), self.output._refresh_error)

    def process_error(self, error):
        """Listen to the error signals from the running process."""
        self.lblInput.hide()
        self.input.hide()
        self._proc.kill()
        format_ = QTextCharFormat()
        format_.setAnchor(True)
        format_.setForeground(Qt.red)
        if error == 0:
            self.output.textCursor().insertText(self.tr('Failed to start'),
                format_)
        else:
            self.output.textCursor().insertText(
                self.tr('Error during execution, QProcess error: %d' % error),
                format_)

    def finish_execution(self, exitCode, exitStatus):
        """Print a message and hide the input line when the execution ends."""
        self.lblInput.hide()
        self.input.hide()
        format_ = QTextCharFormat()
        format_.setAnchor(True)
        self.output.textCursor().insertText('\n\n')
        if exitStatus == QProcess.NormalExit:
            format_.setForeground(Qt.green)
            self.output.textCursor().insertText(
                self.tr("Execution Successful!"), format_)
        else:
            format_.setForeground(Qt.red)
            self.output.textCursor().insertText(
                self.tr("Execution Interrupted"), format_)
        self.output.textCursor().insertText('\n\n')
        self.__post_execution()

    def insert_input(self):
        """Take the user input and send it to the process."""
        text = self.input.text() + '\n'
        self._proc.writeData(text)
        self.output.textCursor().insertText(text, self.output.plain_format)
        self.input.setText("")

    def start_process(self, fileName, pythonPath=False, PYTHONPATH=None,
        programParams='', preExec='', postExec=''):

        """Prepare the output widget and start the process."""
        self.lblInput.show()
        self.input.show()
        self.fileName = fileName
        self.pythonPath = pythonPath  # FIXME, this is python interpreter
        self.programParams = programParams
        self.preExec = preExec
        self.postExec = postExec
        self.PYTHONPATH = PYTHONPATH

        self.__pre_execution()

    def __main_execution(self):
        """Execute the project."""
        self.output.setCurrentCharFormat(self.output.plain_format)
        message = ''
        if self.__preScriptExecuted:
            self.__preScriptExecuted = False
            message = self.tr(
                "Pre Execution Script Successfully executed.\n\n")
        self.output.setPlainText(message + 'Running: %s (%s)\n\n' %
            (self.fileName, unicode(time.ctime())))
        self.output.moveCursor(QTextCursor.Down)
        self.output.moveCursor(QTextCursor.Down)
        self.output.moveCursor(QTextCursor.Down)

        #runner.run_code_from_file(fileName)
        if not self.pythonPath:
            self.pythonPath = settings.PYTHON_PATH
        #change the working directory to the fileName dir
        file_directory = file_manager.get_folder(self.fileName)
        self._proc.setWorkingDirectory(file_directory)
        #force python to unbuffer stdin and stdout
        options = ['-u'] + settings.EXECUTION_OPTIONS.split()
        self.currentProcess = self._proc

        if self.PYTHONPATH:
            envpaths = [path for path in self.PYTHONPATH.splitlines()]
            env = QProcessEnvironment()
            system_environemnt = self._proc.systemEnvironment()
            for e in system_environemnt:
                key, value = unicode(e).split('=', 1)
                env.insert(key, value)
            for path in envpaths:
                env.insert('PYTHONPATH', path)
            self._proc.setProcessEnvironment(env)

        self._proc.start(self.pythonPath, options + [self.fileName] +
            [p.strip() for p in self.programParams.split(',') if p])

    def __pre_execution(self):
        """Execute a script before executing the project."""
        filePreExec = QFile(self.preExec)
        if filePreExec.exists() and \
          bool(QFile.ExeUser & filePreExec.permissions()):
            ext = file_manager.get_file_extension(self.preExec)
            if not self.pythonPath:
                self.pythonPath = settings.PYTHON_PATH
            self.currentProcess = self._preExecScriptProc
            self.__preScriptExecuted = True
            if ext == 'py':
                self._preExecScriptProc.start(self.pythonPath, [self.preExec])
            else:
                self._preExecScriptProc.start(self.preExec)
        else:
            self.__main_execution()

    def __post_execution(self):
        """Execute a script after executing the project."""
        filePostExec = QFile(self.postExec)
        if filePostExec.exists() and \
          bool(QFile.ExeUser & filePostExec.permissions()):
            ext = file_manager.get_file_extension(self.postExec)
            if not self.pythonPath:
                self.pythonPath = settings.PYTHON_PATH
            self.currentProcess = self._postExecScriptProc
            if ext == 'py':
                self._postExecScriptProc.start(self.pythonPath,
                    [self.postExec])
            else:
                self._postExecScriptProc.start(self.postExec)

    def __post_execution_message(self):
        """Print post execution message."""
        self.output.textCursor().insertText('\n\n')
        format_ = QTextCharFormat()
        format_.setAnchor(True)
        format_.setForeground(Qt.green)
        self.output.textCursor().insertText(
            self.tr("Post Execution Script Successfully executed."), format_)

    def kill_process(self):
        """Kill the running process."""
        self._proc.kill()
Beispiel #48
0
class ActionBar(QFrame):
    """
    SIGNALS:
    @changeCurrent(PyQt_PyObject)
    @runFile(QString)
    @reopenTab(QString)
    @recentTabsModified()
    """

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        menu.exec_(QCursor.pos())

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

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

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

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

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

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

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

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

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

    def _show_file_in_explorer(self):
        '''Triggered when the "Show File in Explorer" context
        menu action is selected. Emits the "showFileInExplorer(QString)"
        signal with the current file's full path as argument.'''
        neditable = self.combo.itemData(self.combo.currentIndex())
        self.emit(SIGNAL("showFileInExplorer(QString)"), neditable.file_path)

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

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

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

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

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

    def _close_all_files_except_this(self):
        """Close all the files except the current one."""
        neditable = self.combo.itemData(self.combo.currentIndex())
        for i in reversed(list(range(self.combo.count()))):
            ne = self.combo.itemData(i)
            if ne is not neditable:
                self.about_to_close_file(i)
Beispiel #49
0
class MuWizard(QWizard):

    def __init__(self, R=None, parent=None):
        QWizard.__init__(self, parent)

        self.R = R
        self.data = None

        self.addPage(self.introPage())
        self.addPage(self.loadPage())
        self.addPage(self.modelsPage())
        self.addPage(self.resultsPage())
        self.setWindowTitle('Wizard of muScale')
        self.setPixmap(QWizard.LogoPixmap, QPixmap(RES + ICONS + LOGO))

        self.setStyleSheet('QWizard {' + GRADIENT +'}\
                        QPushButton {\
                            color: #333;\
                            border: 1px solid #555;\
                            border-radius: 11px;\
                            padding: 2px;\
                            background: qradialgradient(cx: 0.3, cy: -0.4,\
                            fx: 0.3, fy: -0.4,\
                            radius: 1.35, stop: 0 #fff, stop: 1 #888);\
                            min-width: 80px;}\
                        QPushButton:hover {\
                            color: #fff;\
                            background: qradialgradient(cx: 0.3, cy: -0.4,\
                            fx: 0.3, fy: -0.4,\
                            radius: 1.35, stop: 0 #fff, stop: 1 #bbb);}\
                        QPushButton:pressed {\
                            color: #800;\
                            background: qradialgradient(cx: 0.4, cy: -0.1,\
                            fx: 0.4, fy: -0.1,\
                            radius: 1.35, stop: 0 #fff, stop: 1 #ddd);}\
                        QPushButton:checked {\
                            background: qradialgradient(cx: 0.4, cy: -0.1,\
                            fx: 0.4, fy: -0.1,\
                            radius: 1.35, stop: 0 #fff, stop: 1 #ddd);}\
                        QComboBox {\
                            color: #333;\
                            border: 1px solid #555;\
                            border-radius: 11px;\
                            padding: 1px 18px 1px 3px;\
                            background: qradialgradient(cx: 0.3, cy: -0.4,\
                            fx: 0.3, fy: -0.4,\
                            radius: 1.35, stop: 0 #fff, stop: 1 #888);\
                            min-width: 20px;}\
                        QComboBox:hover {\
                            color: #fff;\
                            background: qradialgradient(cx: 0.3, cy: -0.4,\
                            fx: 0.3, fy: -0.4,\
                            radius: 1.35, stop: 0 #fff, stop: 1 #bbb);}\
                        QComboBox::down-arrow {\
                             image: url(' + RES + ICONS + ARROW_DOWN + ');}\
                        QComboBox::down-arrow:on {\
                             top: 1px;\
                             left: 1px;}\
                        QComboBox::drop-down {\
                             subcontrol-origin: padding;\
                             subcontrol-position: top right;\
                             width: 15px;\
                             border-left-width: 1px;\
                             border-left-color: darkgray;\
                             border-left-style: solid;\
                             border-top-right-radius: 3px;\
                             border-bottom-right-radius: 3px;}\
                         QToolButton {\
                            color: #333;\
                            border: 1px solid #555;\
                            border-radius: 11px;\
                            padding: 2px;\
                            background: qradialgradient(cx: 0.3, cy: -0.4,\
                            fx: 0.3, fy: -0.4,\
                            radius: 1.35, stop: 0 #fff, stop: 1 #888);\
                            min-width: 20px;}\
                        QToolButton:hover {\
                            color: #fff;\
                            background: qradialgradient(cx: 0.3, cy: -0.4,\
                            fx: 0.3, fy: -0.4,\
                            radius: 1.35, stop: 0 #fff, stop: 1 #bbb);}\
                        QToolButton:pressed {\
                            background: qradialgradient(cx: 0.4, cy: -0.1,\
                            fx: 0.4, fy: -0.1,\
                            radius: 1.35, stop: 0 #fff, stop: 1 #ddd);}\
                        QToolButton:checked {\
                            background: qradialgradient(cx: 0.4, cy: -0.1,\
                            fx: 0.4, fy: -0.1,\
                            radius: 1.35, stop: 0 #fff, stop: 1 #ddd);}')

    def introPage(self):
        intro = QWizardPage()

        intro.setTitle('Hello and welcome')
        label = QLabel('''This is a wizard.
Now you're ready to forecast some time series!
        ''')

        label.setWordWrap(True)
        layout = QVBoxLayout()
        layout.addWidget(label)
        intro.setLayout(layout)

        return intro

    def loadPage(self):
        load = WizardPageEx('loadCheck')

        load.setTitle('Initial data')
        pathLbl = QLabel("<font style='color: gray'>Specify the file with time series to forecast:</font>")
        loadLbl = QLabel("<font style='color: gray'>Click</font>")
        loadLbl.setAlignment(Qt.AlignCenter)

        self.path = QLineEdit()
        self.path.setPlaceholderText('path to file')
        getPath = QToolButton()
        getPath.setText('...')

        self.resultLbl = QLabel()
        self.resultLbl.setAlignment(Qt.AlignCenter)
        self.resultLbl.hide()

        self.preview = QLabel()
        self.preview.setAlignment(Qt.AlignCenter)
        self.preview.setWordWrap(True)
        self.preview.hide()

        self.preview.setAttribute(Qt.WA_Hover)
        self.filter = Filter()
        self.preview.installEventFilter(self.filter)

        getPath.clicked.connect(self.loadData)

        layout = QGridLayout()
        layout.addWidget(pathLbl, 0, 0)
        layout.addWidget(loadLbl, 0, 1)
        layout.addWidget(self.path, 1, 0)
        layout.addWidget(getPath, 1, 1)
        layout.addWidget(self.resultLbl, 2, 0, 1, 2)
        layout.addWidget(self.preview, 3, 0, 1, 2)
        load.setLayout(layout)

        load.previewSeries = SeriesPreview()
        self.previewSeries = load.previewSeries

        # to be able to reference from class namespace
        self.loadCheck = load.check

        return load

    def modelsPage(self):
        models = WizardPageEx('modelCheck')
        models.setTitle('Forecast')

        lbl = QLabel("<font style='color: gray'>Forecast horizon:</font>")
        self.steps = QSpinBox()
        self.steps.setRange(MIN_FORECAST, MAX_FORECAST)
        self.steps.setValue(10)
        self.start = QPushButton('Forecast')
        self.start.clicked.connect(self.modelling)
        self.custom = QPushButton('Advanced')
        self.processing = QLabel()

        self.gifLoading = QMovie(RES + ICONS + PROGRESS, QByteArray(), self)
        self.gifLoading.setCacheMode(QMovie.CacheAll)
        self.gifLoading.setSpeed(100)
        self.processing.setMovie(self.gifLoading)
        self.processing.setAlignment(Qt.AlignCenter)
        self.processing.hide()

        self.status = QLabel()
        self.status.setAlignment(Qt.AlignCenter)
        self.status.hide()

        layout = QGridLayout()
        layout.addWidget(lbl, 0, 0)
        layout.addWidget(self.steps, 0, 1)
        layout.addWidget(self.start, 0, 2)
        layout.addWidget(self.custom, 0, 3)
        layout.addWidget(self.status, 1, 0, 1, 4)
        layout.addWidget(self.processing, 2, 0, 1, 4)
        models.setLayout(layout)

        self.customOpt = CustomOption()
        self.custom.clicked.connect(self.customOpt.show)
        self.modelCheck = models.check

        return models

    def resultsPage(self):
        results = QWizardPage()
        results.setFinalPage(True)
        results.setTitle('Results')

        self.graph = QLabel("<font style='font-size: 16px;'>Plot</font>")
        self.export = QLabel("<font style='font-size: 16px;'>Export</font>")
        self.showData = QLabel("<font style='font-size: 16px;'>Data</font>")
        
        self.plotResult = MplWidget(None)
        self.plotResult.canvas.fig.set_facecolor('white')
        self.resData = QLabel('')
        self.resData.setAlignment(Qt.AlignCenter)
        self.resData.setWordWrap(True)
        self.resData.hide()

        self.resFilter = ResFilter()

        self.resLayout = QVBoxLayout()
        self.resLayout.addWidget(self.export)
        self.resLayout.addWidget(self.graph)
        self.resLayout.addWidget(self.showData)
        self.resLayout.addWidget(self.plotResult)
        self.resLayout.addWidget(self.resData)

        self.plotResult.hide()

        for index in range(0, self.resLayout.count()):
            try:
                self.resLayout.itemAt(index).widget().setAlignment(Qt.AlignCenter)
                self.resLayout.itemAt(index).widget().setStyleSheet('QLabel { color: gray; }')
                self.resLayout.itemAt(index).widget().setAttribute(Qt.WA_Hover)
                self.resLayout.itemAt(index).widget().installEventFilter(self.resFilter)
            except Exception:
                pass

        self.resLayout.setAlignment(Qt.AlignCenter)
        self.resLayout.setSpacing(60)

        results.setLayout(self.resLayout)

        return results

    #---- actions ----#
    def loadData(self):
        fileName = unicode(QFileDialog.getOpenFileName(self, 'Open text file', RES))
        if fileName:
            self.resultLbl.hide()
            self.preview.hide()
            if DataParser.istextfile(fileName):
                self.data = DataParser.getTimeSeriesFromTextData(data=open(fileName, 'r').read())
                if len(self.data[0]) > DATA_LOW_LIMIT:
                    self.resultLbl.setText("<font style='color: gray'>Success! Loaded<b> " + str(len(self.data[0])) +
                                           '</b> values, errors: <b>' + str(
                                            self.data[1]) + '</b></font>')
                    self.resultLbl.show()
                    self.path.setText(fileName)

                    previewLength = 40
                    self.preview.setText("<font style='color: gray'><b>Preview:</b> "+ ' '.join(
                                        [str(e) for e in self.data[0][:previewLength]]) +
                                        "...</font>")
                    self.previewSeries.updateData(self.data)
                    self.preview.show()
                    self.loadCheck.setChecked(True)
                else:
                    self.resultLbl.setText("<font style='color: gray'>Not enough values to form data series.</font>")
                    self.resultLbl.show()
            else:
                self.resultLbl.setText("<font style='color: gray'>Specified file is binary file!</font>")
                self.resultLbl.show()

    def modelling(self):
        self.processing.show()
        self.gifLoading.start()
        self.status.setText('')

        statusText = u"<font style='color: gray'>"

        # decomposition #
        if self.customOpt.options['enable']:
            self.signalEx = self.customOpt.options['signal']
            self.wavelet = pywt.Wavelet(self.customOpt.options['wavelet'])
            wLevel = self.customOpt.options['lvls'] - 1
            maxLevel = pywt.dwt_max_level(len(self.data[0]), self.wavelet)

            if wLevel > maxLevel:
                wLevel = maxLevel

            self.wInitialCoefficients = pywt.wavedec(self.data[0], self.wavelet,
                                                       level=wLevel, mode=self.signalEx)
            self.wCoefficients = self.wInitialCoefficients
        else:
            self.signalEx = pywt.MODES.sp1
            selected = select_wavelet(self.data[0], self.R)
            index = max(selected)
            self.wavelet = pywt.Wavelet(selected[index][1])

            wLevel = calculate_suitable_lvl(self.data[0],
                                         self.wavelet, self.R, swt=False)
            self.wInitialCoefficients = pywt.wavedec(self.data[0], self.wavelet,
                                                     level=wLevel, mode=self.signalEx)
            self.wCoefficients = self.wInitialCoefficients

        statusText += 'Wavelet: <b>' + self.wavelet.family_name + \
                      '</b> (' + self.wavelet.name + ', ' + self.wavelet.symmetry + ', orthogonal: ' + \
                      str(self.wavelet.orthogonal) + ')<br/>'

        statusText += 'Discrete Wavelet Transfom: <b>' + str(wLevel + 1) + ' levels</b><br/>'

        # models #
        options = {}
        options['multi'] = True
        options['fractal'] = False
        options['ljung'] = False
        self.models = auto_model(self.wCoefficients, self.R, options, self.data[0])

        statusText += '<br/>Selected models:<br/>'
        for lvl, model in self.models.iteritems():
            statusText += str(lvl) + '. <b>' + model.enumname.replace('_', ' ') + '</b><br/>'

        # forecasting #
        try:
            frequency = self.customOpt.options['frequency']
        except Exception:
            frequency = 8
        aic = False
        options['hw_gamma'] = True
        options['hw_model'] = 'additive'
        options['hw_period'] = frequency
        options['ar_aic'] = aic
        options['ar_method'] = 'burg'
        options['ar_order'] = 50
        options['arima_auto'] = False
        options['arima_nons'] = True
        options['arima_nons_order'] = [6, 0, 9]
        options['arima_seas'] = True
        options['arima_seas_order'] = [9, 0, 1]
        options['lsf_aic'] = aic
        options['lsf_order'] = 30
        options['ets_auto'] = aic
        options['ets_period'] = frequency
        options['sts_type'] = 'trend'
        options['append_fit'] = True

        self.multi_model_thread = MultiModelThread(self.models,
                                           self.wCoefficients,
                                           self.R,
                                           self.steps.value(),
                                           options,)
        self.multi_model_thread.done.connect(self.multiForecastFinished)
        self.multi_model_thread.start()

        statusText += '<br/>Forecasting...'

        self.status.setText(statusText)
        self.status.show()

    def multiForecastFinished(self, results):
        self.forecast = results
        self.gifLoading.stop()
        self.processing.hide()

        self.status.setText('<br/>'.join(str(self.status.text()).split('<br/>')[:-1]) +
                            '<br/>Forecast complete.')
        self.modelCheck.setChecked(True)

    #---- results -----#
    def togglePlot(self):
        if self.plotResult.isVisible():
            self.plotResult.hide()
            self.export.show()
            self.showData.show()
            self.resLayout.setSpacing(60)
        else:
            self.updateGraph()
            self.plotResult.show()
            self.export.hide()
            self.showData.hide()
            self.resLayout.setSpacing(5)

    def toggleData(self):
        if self.resData.isVisible():
            self.export.show()
            self.graph.show()
            self.showData.show()
            self.resData.hide()
            self.resLayout.setSpacing(60)
            self.adjustSize()
        else:
            self.plotResult.hide()
            self.graph.hide()
            self.export.hide()
            self.showData.show()
            self.resData.show()
            self.resLayout.setSpacing(5)

            res = self.inverseWT()
            max = len(self.data[0]) - 1
            resText = '<table border="0" align="center" style="border-style: groove;">'
            resText += '<tr><td align="center"><i>Initial</i></td><td align="center"><i>Forecast</i></td></tr>'
            resText += '<tr><td align="center">...</td><td></td></tr>'
            table = zip(self.data[0][max-10:max], res[max-10:max])
            for i, j in table:
                resText += '<tr>'
                resText += '<td align="center">' + str(i) + '</td>'
                resText += '<td align="center">' + str(j) + '</td>'
                resText += '</tr>'

            for e in res[max+1:max+10]:
                resText += '<tr>'
                resText += '<td align="center"></td>'
                resText += '<td align="center">' + str(e) + '</td>'
                resText += '</tr>'

            resText += '<tr><td align="center"></td><td align="center">...</td></tr>'
            resText += '</table>'

            self.resData.setText(resText)
            self.adjustSize()

    def inverseWT(self):
        return pywt.waverec(update_dwt([e [1] for e in self.forecast], self.wavelet, self.signalEx),
                                            self.wavelet, mode=self.signalEx)

    def updateGraph(self):
        self.plotResult.updatePlot(self.inverseWT(), label='Simulation', color='r')
        self.plotResult.updatePlot(self.data[0], label='Time series', color='b')

    def exportToXls(self):
        # opening file dialog
        fileName = QFileDialog.getSaveFileName(self,
            'Save as', RES, 'Microsoft Excel Spreadsheet (*.xls)')

        if fileName.count() > 0:
            try:
                COLUMN_WIDTH = 3000

                alignment = Alignment()
                alignment.horizontal = Alignment.HORZ_CENTER
                alignment.vertical = Alignment.VERT_CENTER

                borders = Borders()
                borders.left = Borders.THIN
                borders.right = Borders.THIN
                borders.top = Borders.THIN
                borders.bottom = Borders.THIN

                style = XFStyle()
                style.alignment = alignment
                style.borders = borders

                font = Font()
                font.bold = True
                headerStyle = XFStyle()
                headerStyle.font = font

                separate = Borders()
                separate.left = Borders.THIN
                separate.right = Borders.DOUBLE
                separate.top = Borders.THIN
                separate.bottom = Borders.THIN
                separateStyle = XFStyle()
                separateStyle.borders = separate

                book = Workbook(encoding='utf-8')

                # modelling data
                dec_sheet = book.add_sheet('Data decomposition')

                # decomposition data
                # initial data
                column = 0
                row = 0
                dec_sheet.write(row, column, 'Time series', headerStyle)
                dec_sheet.col(column).width = COLUMN_WIDTH
                row += 1
                for item in self.data[0]:
                    dec_sheet.write(row, column, item, separateStyle)
                    row += 1

                # decomposition
                for lvl in self.wCoefficients:
                    row = 0
                    column += 1
                    dec_sheet.write(row, column, 'Level' + str(column - 1), headerStyle)
                    dec_sheet.col(column).width = COLUMN_WIDTH
                    row += 1
                    for item in lvl:
                        dec_sheet.write(row, column, item, style)
                        row += 1

                # decomposition graphs
                pass

                levels_sheet = book.add_sheet('Multiscale forecast')

                # levels data
                column = 0
                for lvl in self.forecast:
                    row = 0
                    levels_sheet.write(row, column, 'Level' + str(column), headerStyle)
                    levels_sheet.col(column).width = COLUMN_WIDTH
                    row += 1
                    for item in lvl[1]:
                        levels_sheet.write(row, column, float(item), style)
                        row += 1
                    column += 1

                result_sheet = book.add_sheet('Results')

                # initial
                column = 0
                row = 0
                result_sheet.write(row, column, 'Initial data', headerStyle)
                result_sheet.col(column).width = COLUMN_WIDTH
                row += 1
                for item in self.data[0]:
                    result_sheet.write(row, column, item, separateStyle)
                    row += 1

                # forecast
                row = 0
                column += 1
                result_sheet.write(row, column, 'Forecast', headerStyle)
                result_sheet.col(column).width = COLUMN_WIDTH
                row += 1
                for item in self.inverseWT():
                    result_sheet.write(row, column, item, style)
                    row += 1

                row = 0
                column = 2
                self.updateGraph()
                self.plotResult.saveFigure('forecast', format='bmp')

                result_sheet.insert_bitmap(RES + TEMP + 'forecast.bmp', row, column)

                # saving xls
                try:
                    book.save(unicode(fileName))
                except Exception:
                    pass

            except Exception, e:
                pass
Beispiel #50
0
class RunWidget(QWidget):

    """Widget that show the execution output in the MiscContainer."""

    def __init__(self):
        QWidget.__init__(self)
        vbox = QVBoxLayout(self)
        vbox.setSpacing(0)
        vbox.setContentsMargins(0, 0, 0, 0)
        self.output = OutputWidget(self)
        hbox = QHBoxLayout()
        self.input = QLineEdit()
        self.lblInput = QLabel(self.tr("Input:"))
        vbox.addWidget(self.output)
        hbox.addWidget(self.lblInput)
        hbox.addWidget(self.input)
        vbox.addLayout(hbox)

        #process
        self.currentProcess = None
        self.__preScriptExecuted = False
        self._proc = QProcess(self)
        self._preExecScriptProc = QProcess(self)
        self._postExecScriptProc = QProcess(self)
        self.connect(self._proc, SIGNAL("readyReadStandardOutput()"),
            self.output._refresh_output)
        self.connect(self._proc, SIGNAL("readyReadStandardError()"),
            self.output._refresh_error)
        self.connect(self._proc, SIGNAL("finished(int, QProcess::ExitStatus)"),
            self.finish_execution)
        self.connect(self._proc, SIGNAL("error(QProcess::ProcessError)"),
            self.process_error)
        self.connect(self.input, SIGNAL("returnPressed()"), self.insert_input)
        self.connect(self._preExecScriptProc,
            SIGNAL("finished(int, QProcess::ExitStatus)"),
            self.__main_execution)
        self.connect(self._preExecScriptProc,
            SIGNAL("readyReadStandardOutput()"), self.output._refresh_output)
        self.connect(self._preExecScriptProc,
            SIGNAL("readyReadStandardError()"), self.output._refresh_error)
        self.connect(self._postExecScriptProc,
            SIGNAL("finished(int, QProcess::ExitStatus)"),
            self.__post_execution_message)
        self.connect(self._postExecScriptProc,
            SIGNAL("readyReadStandardOutput()"), self.output._refresh_output)
        self.connect(self._postExecScriptProc,
            SIGNAL("readyReadStandardError()"), self.output._refresh_error)

    def process_error(self, error):
        """Listen to the error signals from the running process."""
        self.lblInput.hide()
        self.input.hide()
        self._proc.kill()
        format_ = QTextCharFormat()
        format_.setAnchor(True)
        format_.setForeground(Qt.red)
        if error == 0:
            self.output.textCursor().insertText(self.tr('Failed to start'),
                format_)
        else:
            self.output.textCursor().insertText(
                self.tr('Error during execution, QProcess error: %d' % error),
                format_)

    def finish_execution(self, exitCode, exitStatus):
        """Print a message and hide the input line when the execution ends."""
        self.lblInput.hide()
        self.input.hide()
        format_ = QTextCharFormat()
        format_.setAnchor(True)
        self.output.textCursor().insertText('\n\n')
        if exitStatus == QProcess.NormalExit:
            format_.setForeground(Qt.green)
            self.output.textCursor().insertText(
                self.tr("Execution Successful!"), format_)
        else:
            format_.setForeground(Qt.red)
            self.output.textCursor().insertText(
                self.tr("Execution Interrupted"), format_)
        self.output.textCursor().insertText('\n\n')
        self.__post_execution()

    def insert_input(self):
        """Take the user input and send it to the process."""
        text = self.input.text() + '\n'
        self._proc.writeData(text)
        self.output.textCursor().insertText(text, self.output.plain_format)
        self.input.setText("")

    def start_process(self, fileName, pythonPath=False, PYTHONPATH=None,
        programParams='', preExec='', postExec=''):

        """Prepare the output widget and start the process."""
        self.lblInput.show()
        self.input.show()
        self.fileName = fileName
        self.pythonPath = pythonPath  # FIXME, this is python interpreter
        self.programParams = programParams
        self.preExec = preExec
        self.postExec = postExec
        self.PYTHONPATH = PYTHONPATH

        self.__pre_execution()

    def __main_execution(self):
        """Execute the project."""
        self.output.setCurrentCharFormat(self.output.plain_format)
        message = ''
        if self.__preScriptExecuted:
            self.__preScriptExecuted = False
            message = self.tr(
                "Pre Execution Script Successfully executed.\n\n")
        self.output.setPlainText(message + 'Running: %s (%s)\n\n' %
            (self.fileName, time.ctime()))
        self.output.moveCursor(QTextCursor.Down)
        self.output.moveCursor(QTextCursor.Down)
        self.output.moveCursor(QTextCursor.Down)

        #runner.run_code_from_file(fileName)
        if not self.pythonPath:
            self.pythonPath = settings.PYTHON_PATH
        #change the working directory to the fileName dir
        file_directory = file_manager.get_folder(self.fileName)
        self._proc.setWorkingDirectory(file_directory)
        #force python to unbuffer stdin and stdout
        options = ['-u'] + settings.EXECUTION_OPTIONS.split()
        self.currentProcess = self._proc

        if self.PYTHONPATH:
            envpaths = [path for path in self.PYTHONPATH.splitlines()]
            env = QProcessEnvironment()
            system_environemnt = self._proc.systemEnvironment()
            for e in system_environemnt:
                key, value = e.split('=', 1)
                env.insert(key, value)
            for path in envpaths:
                env.insert('PYTHONPATH', path)
            self._proc.setProcessEnvironment(env)

        self._proc.start(self.pythonPath, options + [self.fileName] +
            [p.strip() for p in self.programParams.split(',') if p])

    def __pre_execution(self):
        """Execute a script before executing the project."""
        filePreExec = QFile(self.preExec)
        if filePreExec.exists() and \
          bool(QFile.ExeUser & filePreExec.permissions()):
            ext = file_manager.get_file_extension(self.preExec)
            if not self.pythonPath:
                self.pythonPath = settings.PYTHON_PATH
            self.currentProcess = self._preExecScriptProc
            self.__preScriptExecuted = True
            if ext == 'py':
                self._preExecScriptProc.start(self.pythonPath, [self.preExec])
            else:
                self._preExecScriptProc.start(self.preExec)
        else:
            self.__main_execution()

    def __post_execution(self):
        """Execute a script after executing the project."""
        filePostExec = QFile(self.postExec)
        if filePostExec.exists() and \
          bool(QFile.ExeUser & filePostExec.permissions()):
            ext = file_manager.get_file_extension(self.postExec)
            if not self.pythonPath:
                self.pythonPath = settings.PYTHON_PATH
            self.currentProcess = self._postExecScriptProc
            if ext == 'py':
                self._postExecScriptProc.start(self.pythonPath,
                    [self.postExec])
            else:
                self._postExecScriptProc.start(self.postExec)

    def __post_execution_message(self):
        """Print post execution message."""
        self.output.textCursor().insertText('\n\n')
        format_ = QTextCharFormat()
        format_.setAnchor(True)
        format_.setForeground(Qt.green)
        self.output.textCursor().insertText(
            self.tr("Post Execution Script Successfully executed."), format_)

    def kill_process(self):
        """Kill the running process."""
        self._proc.kill()
class preferencesDialog(QDialog):
    newMailerMessage = QtCore.Signal(str, str)
    def __init__(self, parent):
        QDialog.__init__(self, parent)
        self.tmpPref = {}
        self.tmpPref['pref'] = copy.deepcopy(self.parent().prm['pref'])
        self.currLocale = self.parent().prm['currentLocale']
        self.currLocale.setNumberOptions(self.currLocale.OmitGroupSeparator | self.currLocale.RejectGroupSeparator)
        self.audioManager = parent.audioManager
        self.mailer = emailSender(self)
        self.newMailerMessage.connect(self.popMailerMessage)
        
        self.tabWidget = QTabWidget()
        self.tabWidget.currentChanged.connect(self.tabChanged)
        self.appPrefWidget = QWidget()
        self.soundPrefWidget = QWidget()
        self.notificationPrefWidget = QWidget()
        self.eegPrefWidget = QWidget()

        #the gui widget for these are in an external dialog
        self.wavsPref = {}
        self.wavsPref['endMessageFiles'] = self.tmpPref['pref']['general']['endMessageFiles']
        self.wavsPref['endMessageFilesUse'] = self.tmpPref['pref']['general']['endMessageFilesUse']
        self.wavsPref['endMessageFilesID'] = self.tmpPref['pref']['general']['endMessageFilesID']
        self.wavsPref['endMessageLevels'] = self.tmpPref['pref']['general']['endMessageLevels']
        #GENERAL PREF
        appPrefGrid = QGridLayout()
        n = 0
        self.languageChooserLabel = QLabel(self.tr('Language (requires restart):'))
        appPrefGrid.addWidget(self.languageChooserLabel, n, 0)
        self.languageChooser = QComboBox()
        self.languageChooser.addItems(self.parent().prm['appData']['available_languages'])
        self.languageChooser.setCurrentIndex(self.languageChooser.findText(self.tmpPref['pref']['language']))
        self.languageChooser.currentIndexChanged[int].connect(self.onLanguageChooserChange)
        appPrefGrid.addWidget(self.languageChooser, n, 1)
        n = n+1
        self.countryChooserLabel = QLabel(self.tr('Country (requires restart):'))
        appPrefGrid.addWidget(self.countryChooserLabel, n, 0)
        self.countryChooser = QComboBox()
        self.countryChooser.addItems(self.parent().prm['appData']['available_countries'][self.tmpPref['pref']['language']])
        self.countryChooser.setCurrentIndex(self.countryChooser.findText(self.tmpPref['pref']['country']))
        appPrefGrid.addWidget(self.countryChooser, n, 1)
        n = n+1

        self.responseBoxLanguageChooserLabel = QLabel(self.tr('Response Box Language (requires restart):'))
        appPrefGrid.addWidget(self.responseBoxLanguageChooserLabel, n, 0)
        self.responseBoxLanguageChooser = QComboBox()
        self.responseBoxLanguageChooser.addItems(self.parent().prm['appData']['available_languages'])
        self.responseBoxLanguageChooser.setCurrentIndex(self.responseBoxLanguageChooser.findText(self.tmpPref['pref']['responseBoxLanguage']))
        self.responseBoxLanguageChooser.currentIndexChanged[int].connect(self.onResponseBoxLanguageChooserChange)
        appPrefGrid.addWidget(self.responseBoxLanguageChooser, n, 1)
        n = n+1
        self.responseBoxCountryChooserLabel = QLabel(self.tr('Response Box Country (requires restart):'))
        appPrefGrid.addWidget(self.responseBoxCountryChooserLabel, n, 0)
        self.responseBoxCountryChooser = QComboBox()
        self.responseBoxCountryChooser.addItems(self.parent().prm['appData']['available_countries'][self.tmpPref['pref']['responseBoxLanguage']])
        self.responseBoxCountryChooser.setCurrentIndex(self.responseBoxCountryChooser.findText(self.tmpPref['pref']['responseBoxCountry']))
        appPrefGrid.addWidget(self.responseBoxCountryChooser, n, 1)
        
        n = n+1
        self.csvSeparatorLabel = QLabel(self.tr('csv separator:'))
        appPrefGrid.addWidget(self.csvSeparatorLabel, n, 0)
        self.csvSeparatorWidget = QLineEdit(self.tmpPref['pref']["general"]["csvSeparator"])
        appPrefGrid.addWidget(self.csvSeparatorWidget, n, 1)
        n = n+1
        self.listenerNameWarnCheckBox = QCheckBox(self.tr('Warn if listener name missing'))
        self.listenerNameWarnCheckBox.setChecked(self.tmpPref["pref"]["general"]["listenerNameWarn"])
        appPrefGrid.addWidget(self.listenerNameWarnCheckBox, n, 0)
        n = n+1
        self.sessionLabelWarnCheckBox = QCheckBox(self.tr('Warn if session label missing'))
        self.sessionLabelWarnCheckBox.setChecked(self.tmpPref["pref"]["general"]["sessionLabelWarn"])
        appPrefGrid.addWidget(self.sessionLabelWarnCheckBox, n, 0)

        n = n+1
        self.dpCorrCheckBox = QCheckBox(self.tr('d-prime correction'))
        self.dpCorrCheckBox.setChecked(self.tmpPref['pref']['general']['dprimeCorrection'])
        self.dpCorrCheckBox.setWhatsThis(self.tr("If checked, when automatically processing result files, convert hit rates of 0 and 1 to 1/2N and 1-1/(2N) respectively, where N is the number of trials, to avoid infinite values of d'"))
        appPrefGrid.addWidget(self.dpCorrCheckBox, n, 0)

        n = n+1
        self.recursionLimitLabel = QLabel(self.tr('Max Recursion Depth (requires restart):'))
        appPrefGrid.addWidget(self.recursionLimitLabel, n, 0)
        self.recursionLimitWidget = QLineEdit(self.currLocale.toString(self.tmpPref["pref"]["general"]["maxRecursionDepth"]))
        self.recursionLimitWidget.setValidator(QIntValidator(self))
        appPrefGrid.addWidget(self.recursionLimitWidget, n, 1)
        n = n+1

        n = n+1
        self.startupCommandLabel = QLabel(self.tr('Execute command at startup:'))
        appPrefGrid.addWidget(self.startupCommandLabel, n, 0)
        self.startupCommandWidget = QLineEdit(self.tmpPref["pref"]["general"]["startupCommand"])
        appPrefGrid.addWidget(self.startupCommandWidget, n, 1)
        n = n+1
        
        self.appPrefWidget.setLayout(appPrefGrid)
        self.appPrefWidget.layout().setSizeConstraint(QLayout.SetFixedSize)
        
        
        #SOUND PREF
        soundPrefGrid = QGridLayout()
        n = 0
        self.playChooser = QComboBox()
        self.playChooser.addItems(self.parent().prm['appData']['available_play_commands'])
        self.playChooser.setCurrentIndex(self.playChooser.findText(self.tmpPref['pref']['sound']['playCommandType']))
        self.playChooser.currentIndexChanged[int].connect(self.onPlayChooserChange)
        self.playChooserLabel = QLabel(self.tr('Play Command:'))
        soundPrefGrid.addWidget(self.playChooserLabel, 0, 0)
        soundPrefGrid.addWidget(self.playChooser, 0, 1)
        n = n+1

        self.playCommandLabel = QLabel(self.tr('Command:'))
        soundPrefGrid.addWidget(self.playCommandLabel, n, 0)
        self.playCommandWidget = QLineEdit(self.tmpPref['pref']['sound']['playCommand'])
        if self.playChooser.currentText() != self.tr('custom'):
            self.playCommandWidget.setReadOnly(True)
        soundPrefGrid.addWidget(self.playCommandWidget, n, 1)
        n = n+1
        foo = self.playChooser.currentText()
        if foo != self.tr('custom'):
            self.playCommandLabel.hide()
            self.playCommandWidget.hide()

        #if alsaaudio is selected, provide device list chooser
        if self.parent().prm["appData"]["alsaaudioAvailable"] == True:
            self.alsaaudioPlaybackCardList = self.listAlsaaudioPlaybackCards()
            self.alsaaudioDeviceLabel = QLabel(self.tr('Device:'))
            soundPrefGrid.addWidget(self.alsaaudioDeviceLabel, n, 0)
            self.alsaaudioDeviceChooser = QComboBox()
            self.alsaaudioDeviceChooser.addItems(self.alsaaudioPlaybackCardList)
            self.alsaaudioDeviceChooser.setCurrentIndex(self.alsaaudioDeviceChooser.findText(self.tmpPref["pref"]["sound"]["alsaaudioDevice"]))
            soundPrefGrid.addWidget(self.alsaaudioDeviceChooser, n, 1)
            n = n+1
            if self.tmpPref['pref']['sound']['playCommandType'] != "alsaaudio":
                self.alsaaudioDeviceLabel.hide()
                self.alsaaudioDeviceChooser.hide()

        #if pyaudio is selected, provide device list chooser
        if self.parent().prm["appData"]["pyaudioAvailable"] == True:
            self.listPyaudioPlaybackDevices()
            self.pyaudioDeviceLabel = QLabel(self.tr('Device:'))
            soundPrefGrid.addWidget(self.pyaudioDeviceLabel, n, 0)
            self.pyaudioDeviceChooser = QComboBox()
            self.pyaudioDeviceChooser.addItems(self.pyaudioDeviceListName)
            try:
                self.pyaudioDeviceChooser.setCurrentIndex(self.pyaudioDeviceListIdx.index(self.tmpPref["pref"]["sound"]["pyaudioDevice"]))
            except:
                self.tmpPref["pref"]["sound"]["pyaudioDevice"] = self.pyaudioDeviceListIdx[0]
                self.parent().prm["pref"]["sound"]["pyaudioDevice"] = self.pyaudioDeviceListIdx[0]
                self.pyaudioDeviceChooser.setCurrentIndex(self.pyaudioDeviceListIdx.index(self.tmpPref["pref"]["sound"]["pyaudioDevice"]))
            soundPrefGrid.addWidget(self.pyaudioDeviceChooser, n, 1)
            n = n+1
            if self.tmpPref['pref']['sound']['playCommandType'] != "pyaudio":
                self.pyaudioDeviceLabel.hide()
                self.pyaudioDeviceChooser.hide()

        if self.parent().prm["appData"]["alsaaudioAvailable"] == True or self.parent().prm["appData"]["pyaudioAvailable"] == True:
            self.bufferSizeLabel = QLabel(self.tr('Buffer Size (samples):'))
            soundPrefGrid.addWidget(self.bufferSizeLabel, n, 0)
            self.bufferSizeWidget =  QLineEdit(self.currLocale.toString(self.tmpPref["pref"]["sound"]["bufferSize"]))
            self.bufferSizeWidget.setValidator(QIntValidator(self))
            soundPrefGrid.addWidget(self.bufferSizeWidget, n, 1)
            n = n+1
            if self.tmpPref['pref']['sound']['playCommandType'] not in ["alsaaudio", "pyaudio"]:
                self.bufferSizeLabel.hide()
                self.bufferSizeWidget.hide()

        self.samplerateLabel = QLabel(self.tr('Default Sampling Rate:'))
        soundPrefGrid.addWidget(self.samplerateLabel, n, 0)
        self.samplerateWidget = QLineEdit(self.tmpPref["pref"]["sound"]["defaultSampleRate"])
        #self.samplerateWidget.setValidator(QIntValidator(self))
        soundPrefGrid.addWidget(self.samplerateWidget, n, 1)
        n = n+1

        self.nbitsLabel = QLabel(self.tr('Default Bits:'))
        self.nbitsChooser = QComboBox()
        self.nbitsChooser.addItems(self.parent().prm["nBitsChoices"])
        self.nbitsChooser.setCurrentIndex(self.parent().prm["nBitsChoices"].index(self.tmpPref["pref"]["sound"]["defaultNBits"])) 
        soundPrefGrid.addWidget(self.nbitsLabel, n, 0)
        soundPrefGrid.addWidget(self.nbitsChooser, n, 1)
        n = n+1

        self.wavmanagerLabel = QLabel(self.tr('Wav Manager (requires restart):'))
        self.wavmanagerChooser = QComboBox()
        self.wavmanagerChooser.addItems(self.parent().prm['appData']['wavmanagers'])
        self.wavmanagerChooser.setCurrentIndex(self.wavmanagerChooser.findText(self.tmpPref['pref']['sound']['wavmanager']))
        soundPrefGrid.addWidget(self.wavmanagerLabel, n, 0)
        soundPrefGrid.addWidget(self.wavmanagerChooser, n, 1)
        n = n+1
        
        self.writewav = QCheckBox(self.tr('Write wav file'))
        self.writewav.setChecked(self.tmpPref["pref"]["sound"]["writewav"])
        soundPrefGrid.addWidget(self.writewav, n, 0)
        n = n+1
        self.writeSndSeqSegments = QCheckBox(self.tr('Write sound sequence segments wavs'))
        self.writeSndSeqSegments.setChecked(self.tmpPref["pref"]["sound"]["writeSndSeqSegments"])
        soundPrefGrid.addWidget(self.writeSndSeqSegments, n, 0)
        n = n+1

        self.appendSilenceLabel = QLabel(self.tr('Append silence to each sound (ms):'))
        soundPrefGrid.addWidget(self.appendSilenceLabel, n, 0)
        self.appendSilenceWidget = QLineEdit(self.currLocale.toString(self.tmpPref["pref"]["sound"]["appendSilence"]))
        soundPrefGrid.addWidget(self.appendSilenceWidget, n, 1)
        n = n+1
        
        self.soundPrefWidget.setLayout(soundPrefGrid)
        self.soundPrefWidget.layout().setSizeConstraint(QLayout.SetFixedSize)
        # NOTIFICATION PREF
        notificationPrefGrid = QGridLayout()
        
        n = 0
        
        self.playEndMessage = QCheckBox(self.tr('Play End Message'))
        self.playEndMessage.setChecked(self.tmpPref["pref"]["general"]["playEndMessage"])
        notificationPrefGrid.addWidget(self.playEndMessage, n, 0)

        self.endMessageButton = QPushButton(self.tr("Choose Wav"), self)
        self.endMessageButton.clicked.connect(self.onClickEndMessageButton)
        notificationPrefGrid.addWidget(self.endMessageButton, n, 1)
        n = n+1

        notificationPrefGrid.addItem(QSpacerItem(20,20,QSizePolicy.Expanding), n, 0)
        n = n+1
        
        self.nBlocksLabel = QLabel(self.tr('blocks before end of experiment:'))
        notificationPrefGrid.addWidget(self.nBlocksLabel, n, 1)
        self.nBlocksWidget = QLineEdit(self.currLocale.toString(self.tmpPref['pref']['email']['nBlocksNotify']))
        notificationPrefGrid.addWidget(self.nBlocksWidget, n, 0)
        n = n+1

        self.emailNotify = QCheckBox(self.tr('Send Notification e-mail'))
        self.emailNotify.setChecked(self.tmpPref["pref"]["email"]["notifyEnd"])
        notificationPrefGrid.addWidget(self.emailNotify, n, 0)
        n = n+1

        self.nBlocksCustomCommandLabel = QLabel(self.tr('Execute custom command:'))
        notificationPrefGrid.addWidget(self.nBlocksCustomCommandLabel, n, 0)
        self.nBlocksCustomCommandWidget = QLineEdit(self.tmpPref["pref"]["general"]["nBlocksCustomCommand"])
        notificationPrefGrid.addWidget(self.nBlocksCustomCommandWidget, n, 1)
        n = n+1


        notificationPrefGrid.addItem(QSpacerItem(20,20,QSizePolicy.Expanding), n, 0)
        n = n+1
        self.atEndLabel = QLabel(self.tr('At the end of the experiment:'))
        notificationPrefGrid.addWidget(self.atEndLabel, n, 0)
        n = n+1
        
        self.sendData = QCheckBox(self.tr('Send data via e-mail'))
        self.sendData.setChecked(self.tmpPref["pref"]["email"]["sendData"])
        notificationPrefGrid.addWidget(self.sendData, n, 0)
        n = n+1

        self.atEndCustomCommandLabel = QLabel(self.tr('Execute custom command:'))
        notificationPrefGrid.addWidget(self.atEndCustomCommandLabel, n, 0)
        self.atEndCustomCommandWidget = QLineEdit(self.tmpPref["pref"]["general"]["atEndCustomCommand"])
        notificationPrefGrid.addWidget(self.atEndCustomCommandWidget, n, 1)
        n = n+1

        notificationPrefGrid.addItem(QSpacerItem(20,20,QSizePolicy.Expanding), n, 0)
        n = n+1
        self.serverLabel = QLabel(self.tr('Outgoing server (SMTP):'))
        notificationPrefGrid.addWidget(self.serverLabel, n, 0)
        self.serverWidget = QLineEdit(self.tmpPref['pref']['email']['SMTPServer'])
        notificationPrefGrid.addWidget(self.serverWidget, n, 1)
        n = n+1

        self.serverPortLabel = QLabel(self.tr('Port:'))
        notificationPrefGrid.addWidget(self.serverPortLabel, n, 0)
        self.serverPortWidget = QLineEdit(self.currLocale.toString(self.tmpPref['pref']['email']['SMTPServerPort']))
        self.serverPortWidget.setValidator(QIntValidator(self))
        notificationPrefGrid.addWidget(self.serverPortWidget, n, 1)
        n = n+1

        self.serverSecurityLabel = QLabel(self.tr('Security:'))
        notificationPrefGrid.addWidget(self.serverSecurityLabel, n, 0)
        self.serverSecurityChooser = QComboBox()
        self.serverSecurityChooser.addItems(["TLS/SSL (a)", "TLS/SSL (b)", "none"])
        self.serverSecurityChooser.setCurrentIndex(self.serverSecurityChooser.findText(self.tmpPref['pref']['email']['SMTPServerSecurity']))
        notificationPrefGrid.addWidget(self.serverSecurityChooser, n, 1)
        n = n+1

        self.serverRequiresAuthCheckBox = QCheckBox(self.tr('Server requires authentication'))
        self.serverRequiresAuthCheckBox.setChecked(self.tmpPref["pref"]["email"]["serverRequiresAuthentication"])
        notificationPrefGrid.addWidget(self.serverRequiresAuthCheckBox, n, 0, 1, 2)
        n = n+1
        
        self.usernameLabel = QLabel(self.tr('Username:'******'pref']['email']['fromUsername'])
        notificationPrefGrid.addWidget(self.usernameWidget, n, 1)
        n = n+1
        
        self.passwordLabel = QLabel(self.tr('Password:'******'pref']['email']['fromPassword'])
        self.passwordWidget.setEchoMode(QLineEdit.Password)
        notificationPrefGrid.addWidget(self.passwordWidget, n, 1)

        n = n+1
        self.passwordWarningLabel = QLabel(self.tr('Password is NOT stored safely (see manual), use at your own risk!'))
        notificationPrefGrid.addWidget(self.passwordWarningLabel, n, 0, 1, 2)
        n = n+1
        self.testEmailButton = QPushButton(self.tr("Send test e-mail"), self)
        self.testEmailButton.clicked.connect(self.onClickTestEmailButton)
        self.testEmailButton.setToolTip(self.tr("Send a test e-mail"))
        notificationPrefGrid.addWidget(self.testEmailButton, n, 0, 1, 2)
        
        self.notificationPrefWidget.setLayout(notificationPrefGrid)
        self.notificationPrefWidget.layout().setSizeConstraint(QLayout.SetFixedSize)


        ##--#--#--#--#--
        # EEG PREF GRID
        eegPrefGrid = QGridLayout()
        
        n = 0
        self.ONTriggerLabel = QLabel(self.tr('ON Trigger:'))
        eegPrefGrid.addWidget(self.ONTriggerLabel, n, 0)
        self.ONTriggerWidget = QLineEdit(self.currLocale.toString(self.tmpPref["pref"]["general"]["ONTrigger"]))
        eegPrefGrid.addWidget(self.ONTriggerWidget, n, 1)

        n = n+1
        self.OFFTriggerLabel = QLabel(self.tr('OFF Trigger:'))
        eegPrefGrid.addWidget(self.OFFTriggerLabel, n, 0)
        self.OFFTriggerWidget = QLineEdit(self.currLocale.toString(self.tmpPref["pref"]["general"]["OFFTrigger"]))
        eegPrefGrid.addWidget(self.OFFTriggerWidget, n, 1)

        n = n+1
        self.triggerDurLabel = QLabel(self.tr('Trigger Duration (ms):'))
        eegPrefGrid.addWidget(self.triggerDurLabel, n, 0)
        self.triggerDurWidget = QLineEdit(self.currLocale.toString(self.tmpPref["pref"]["general"]["triggerDur"]))
        eegPrefGrid.addWidget(self.triggerDurWidget, n, 1)
      
        
        self.eegPrefWidget.setLayout(eegPrefGrid)
        self.eegPrefWidget.layout().setSizeConstraint(QLayout.SetFixedSize)

        # ........................
        self.tabWidget.addTab(self.appPrefWidget, self.tr("Genera&l"))
        self.tabWidget.addTab(self.soundPrefWidget, self.tr("Soun&d"))
        self.tabWidget.addTab(self.notificationPrefWidget, self.tr("Notification&s"))
        self.tabWidget.addTab(self.eegPrefWidget, self.tr("EE&G"))

        buttonBox = QDialogButtonBox(QDialogButtonBox.Apply|QDialogButtonBox.Ok|QDialogButtonBox.Cancel)
        buttonBox.accepted.connect(self.accept)
        buttonBox.rejected.connect(self.reject)
        buttonBox.button(QDialogButtonBox.Apply).clicked.connect(self.permanentApply)
        
        layout = QVBoxLayout()
        layout.addWidget(self.tabWidget)
        layout.addWidget(buttonBox)
        self.setLayout(layout)
       
    def onLanguageChooserChange(self):
        for i in range(self.countryChooser.count()):
            self.countryChooser.removeItem(0)
        self.countryChooser.addItems(self.parent().prm['appData']['available_countries'][self.languageChooser.currentText()])

    def onResponseBoxLanguageChooserChange(self):
        for i in range(self.responseBoxCountryChooser.count()):
            self.responseBoxCountryChooser.removeItem(0)
        self.responseBoxCountryChooser.addItems(self.parent().prm['appData']['available_countries'][self.responseBoxLanguageChooser.currentText()])

    def onPlayChooserChange(self):
        foo = self.playChooser.currentText()
        if foo != self.tr('custom'):
            self.playCommandLabel.hide()
            self.playCommandWidget.hide()
            self.playCommandWidget.setText(foo)
            self.playCommandWidget.setReadOnly(True)
        else:
            self.playCommandWidget.show()
            self.playCommandLabel.show()
            self.playCommandWidget.setReadOnly(False)

        if self.parent().prm["appData"]["alsaaudioAvailable"] == True:
            if foo == "alsaaudio":
                self.alsaaudioDeviceLabel.show()
                self.alsaaudioDeviceChooser.show()
               
            else:
                self.alsaaudioDeviceLabel.hide()
                self.alsaaudioDeviceChooser.hide()
             

        if self.parent().prm["appData"]["pyaudioAvailable"] == True:
            if foo == "pyaudio":
                self.pyaudioDeviceLabel.show()
                self.pyaudioDeviceChooser.show()
            else:
                self.pyaudioDeviceLabel.hide()
                self.pyaudioDeviceChooser.hide()


        if self.parent().prm["appData"]["alsaaudioAvailable"] == True or self.parent().prm["appData"]["pyaudioAvailable"] == True:
            if foo in ["alsaaudio", "pyaudio"]:
                self.bufferSizeLabel.show()
                self.bufferSizeWidget.show()
            else:
                self.bufferSizeLabel.hide()
                self.bufferSizeWidget.hide()
            
    def onClickEndMessageButton(self):
        dialog = wavListDialog(self)
        if dialog.exec_():
            self.wavsList = dialog.wavsList
            self.wavsPref = {}
            self.wavsPref['endMessageFiles'] = []
            self.wavsPref['endMessageFilesUse'] = []
            self.wavsPref['endMessageFilesID'] = []
            self.wavsPref['endMessageLevels'] = []
            keys = sorted(self.wavsList.keys())
            for key in keys:
                self.wavsPref['endMessageFiles'].append(str(self.wavsList[key]['file']))
                self.wavsPref['endMessageFilesUse'].append(self.wavsList[key]['use'])
                self.wavsPref['endMessageLevels'].append(self.wavsList[key]['level'])
                self.wavsPref['endMessageFilesID'].append(key)

    def onClickTestEmailButton(self):
        self.mailer.sendTestEmail()
        
    def popMailerMessage(self, msg, msgtype):
        if msgtype == 'critical':
            QMessageBox.critical(self, self.tr("Error"), msg)
        elif msgtype == 'warning':
            QMessageBox.warning(self, self.tr("Warning"), msg)
        elif msgtype == 'information':
            QMessageBox.information(self, self.tr("Information"), msg)
            
    def tryApply(self):
        self.tmpPref['pref']['language'] = self.tr(self.languageChooser.currentText())
        self.tmpPref['pref']['country'] = self.tr(self.countryChooser.currentText())
        self.tmpPref['pref']['responseBoxLanguage'] = self.tr(self.responseBoxLanguageChooser.currentText())
        self.tmpPref['pref']['responseBoxCountry'] = self.tr(self.responseBoxCountryChooser.currentText())
        self.tmpPref['pref']['general']['csvSeparator'] = self.csvSeparatorWidget.text()
        self.tmpPref['pref']['general']['ONTrigger'] = self.currLocale.toInt(self.ONTriggerWidget.text())[0]
        self.tmpPref['pref']['general']['OFFTrigger'] = self.currLocale.toInt(self.OFFTriggerWidget.text())[0]
        self.tmpPref['pref']['general']['triggerDur'] = self.currLocale.toDouble(self.triggerDurWidget.text())[0]
        self.tmpPref['pref']['general']['maxRecursionDepth'] = self.currLocale.toInt(self.recursionLimitWidget.text())[0]
        self.tmpPref['pref']['general']['startupCommand'] = self.startupCommandWidget.text()
        
        self.tmpPref['pref']['sound']['playCommand'] = self.tr(self.playCommandWidget.text())
        self.tmpPref['pref']['sound']['playCommandType'] = self.tr(self.playChooser.currentText())
        if self.parent().prm["appData"]["alsaaudioAvailable"] == True:
            self.tmpPref['pref']['sound']['alsaaudioDevice'] = self.alsaaudioDeviceChooser.currentText()
        if self.parent().prm["appData"]["pyaudioAvailable"] == True:
            self.tmpPref['pref']['sound']['pyaudioDevice'] =  self.pyaudioDeviceListIdx[self.pyaudioDeviceChooser.currentIndex()]
        self.tmpPref['pref']['sound']['wavmanager'] = str(self.wavmanagerChooser.currentText())
        if self.parent().prm["appData"]["alsaaudioAvailable"] == True or self.parent().prm["appData"]["pyaudioAvailable"] == True:
            self.tmpPref['pref']['sound']['bufferSize'] = self.currLocale.toInt(self.bufferSizeWidget.text())[0]
        self.tmpPref['pref']['sound']['defaultSampleRate'] = self.samplerateWidget.text()
        self.tmpPref['pref']['sound']['defaultNBits'] = self.nbitsChooser.currentText()
        self.tmpPref['pref']['sound']['appendSilence'] = self.currLocale.toInt(self.appendSilenceWidget.text())[0]
        
        self.tmpPref["pref"]["email"]["nBlocksNotify"] = self.currLocale.toInt(self.nBlocksWidget.text())[0]
        self.tmpPref["pref"]["general"]["nBlocksCustomCommand"] = self.nBlocksCustomCommandWidget.text()
        self.tmpPref["pref"]["general"]["atEndCustomCommand"] = self.atEndCustomCommandWidget.text()
        self.tmpPref["pref"]["email"]['SMTPServer'] = self.serverWidget.text()
        self.tmpPref["pref"]["email"]['SMTPServerPort'] = self.currLocale.toInt(self.serverPortWidget.text())[0]
        self.tmpPref["pref"]["email"]['fromUsername'] = self.usernameWidget.text()
        self.tmpPref["pref"]["email"]['SMTPServerSecurity'] = self.serverSecurityChooser.currentText()

        self.tmpPref["pref"]["general"]["endMessageFiles"] = self.wavsPref['endMessageFiles']
        self.tmpPref["pref"]["general"]["endMessageFilesUse"] = self.wavsPref['endMessageFilesUse']
        self.tmpPref["pref"]["general"]["endMessageFilesID"] = self.wavsPref['endMessageFilesID']
        self.tmpPref["pref"]["general"]["endMessageLevels"] = self.wavsPref['endMessageLevels']

        self.tmpPref["pref"]["email"]['fromPassword'] = self.passwordWidget.text()
        
        if self.writewav.isChecked():
            self.tmpPref['pref']['sound']['writewav'] = True
        else:
            self.tmpPref['pref']['sound']['writewav'] = False

        if self.writeSndSeqSegments.isChecked():
            self.tmpPref['pref']['sound']['writeSndSeqSegments'] = True
        else:
            self.tmpPref['pref']['sound']['writeSndSeqSegments'] = False

        if self.dpCorrCheckBox.isChecked():
            self.tmpPref['pref']['general']['dprimeCorrection'] = True
        else:
            self.tmpPref['pref']['general']['dprimeCorrection'] = False

        if self.listenerNameWarnCheckBox.isChecked():
            self.tmpPref['pref']['general']['listenerNameWarn'] = True
        else:
            self.tmpPref['pref']['general']['listenerNameWarn'] = False

        if self.sessionLabelWarnCheckBox.isChecked():
            self.tmpPref['pref']['general']['sessionLabelWarn'] = True
        else:
            self.tmpPref['pref']['general']['sessionLabelWarn'] = False

        if self.emailNotify.isChecked():
            self.tmpPref['pref']['email']['notifyEnd'] = True
        else:
            self.tmpPref['pref']['email']['notifyEnd'] = False

        if self.sendData.isChecked():
            self.tmpPref['pref']['email']['sendData'] = True
        else:
            self.tmpPref['pref']['email']['sendData'] = False

        if self.serverRequiresAuthCheckBox.isChecked():
            self.tmpPref['pref']['email']['serverRequiresAuthentication'] = True
        else:
            self.tmpPref['pref']['email']['serverRequiresAuthentication'] = False

        if self.playEndMessage.isChecked():
            self.tmpPref['pref']['general']['playEndMessage'] = True
        else:
            self.tmpPref['pref']['general']['playEndMessage'] = False

        if self.tmpPref['pref']['email']['notifyEnd'] == True or self.tmpPref['pref']['email']['sendData'] == True:
            if checkUsernameValid(self.tmpPref["pref"]["email"]['fromUsername']) == False:
                errMsg = self.tr("Username invalid. Disabling sending e-mails.")
                QMessageBox.warning(self, self.tr("Warning"), errMsg)
                self.emailNotify.setChecked(False)
                self.sendData.setChecked(False)
                self.tmpPref['pref']['email']['notifyEnd'] = False
                self.tmpPref['pref']['email']['sendData'] = False
            elif checkServerValid(self.tmpPref["pref"]["email"]['SMTPServer']) == False:
                errMsg = self.tr("SMTP server name invalid. Disabling sending e-mails.")
                QMessageBox.warning(self, self.tr("Warning"), errMsg)
                self.emailNotify.setChecked(False)
                self.sendData.setChecked(False)
                self.tmpPref['pref']['email']['notifyEnd'] = False
                self.tmpPref['pref']['email']['sendData'] = False
            
    def revertChanges(self):
        self.languageChooser.setCurrentIndex(self.languageChooser.findText(self.tmpPref['pref']['language']))
        self.countryChooser.setCurrentIndex(self.countryChooser.findText(self.tmpPref['pref']['country']))
        self.responseBoxLanguageChooser.setCurrentIndex(self.responseBoxLanguageChooser.findText(self.tmpPref['pref']['responseBoxLanguage']))
        self.responseBoxCountryChooser.setCurrentIndex(self.responseBoxCountryChooser.findText(self.tmpPref['pref']['responseBoxCountry']))
        self.csvSeparatorWidget.setText(self.tmpPref['pref']['general']['csvSeparator'])
        self.ONTriggerWidget.setText(self.currLocale.toString(self.tmpPref['pref']['general']['ONTrigger']))
        self.OFFTriggerWidget.setText(self.currLocale.toString(self.tmpPref['pref']['general']['OFFTrigger']))
        self.triggerDurWidget.setText(self.currLocale.toString(self.tmpPref['pref']['general']['triggerDur']))
        self.recursionLimitWidget.setText(self.currLocale.toString(self.tmpPref['pref']['general']['maxRecursionDepth']))
        self.startupCommandWidget.setText(self.tmpPref['pref']['general']['startupCommand'])
        
        self.playChooser.setCurrentIndex(self.playChooser.findText(self.tmpPref['pref']['sound']['playCommandType']))
        if self.parent().prm["appData"]["alsaaudioAvailable"] == True:
            self.alsaaudioDeviceChooser.setCurrentIndex(self.alsaaudioDeviceChooser.findText(self.tmpPref['pref']['sound']['alsaaudioDevice']))
        if self.parent().prm["appData"]["pyaudioAvailable"] == True:
            self.pyaudioDeviceChooser.setCurrentIndex(self.pyaudioDeviceListIdx.index(self.tmpPref['pref']['sound']['pyaudioDevice']))
        self.wavmanagerChooser.setCurrentIndex(self.wavmanagerChooser.findText(self.tmpPref['pref']['sound']['wavmanager']))
        self.playCommandWidget.setText(self.tmpPref['pref']['sound']['playCommand'])
        if self.parent().prm["appData"]["alsaaudioAvailable"] == True or self.parent().prm["appData"]["pyaudioAvailable"] == True:
            self.bufferSizeWidget.setText(self.currLocale.toString(self.tmpPref['pref']['sound']['bufferSize']))
        self.samplerateWidget.setText(self.tmpPref['pref']['sound']['defaultSampleRate'])
        self.nbitsChooser.setCurrentIndex(self.nbitsChooser.findText(self.tmpPref['pref']['sound']['defaultNBits']))
        self.appendSilenceWidget.setText(self.currLocale.toString(self.tmpPref['pref']['sound']['appendSilence']))
       

        self.nBlocksWidget.setText(self.currLocale.toString(self.tmpPref['pref']['email']['nBlocksNotify']))
        self.nBlocksCustomCommandWidget.setText( self.tmpPref["pref"]["general"]["nBlocksCustomCommand"])
        self.atEndCustomCommandWidget.setText( self.tmpPref["pref"]["general"]["nBlocksCustomCommand"])
        self.serverWidget.setText(self.tmpPref['pref']['email']['SMTPServer'])
        self.serverPortWidget.setText(self.currLocale.toString(self.tmpPref['pref']['email']['SMTPServerPort']))
        self.usernameWidget.setText(self.tmpPref['pref']['email']['fromUsername'])
        self.passwordWidget.setText(self.tmpPref['pref']['email']['fromPassword'])
        self.serverSecurityChooser.setCurrentIndex(self.serverSecurityChooser.findText(self.tmpPref['pref']['email']['SMTPServerSecurity']))

        self.wavsPref["endMessageFiles"] = self.tmpPref["pref"]["general"]["endMessageFiles"]
        self.wavsPref["endMessageFilesUse"] = self.tmpPref["pref"]["general"]["endMessageFilesUse"]
        self.wavsPref["endMessageFilesID"] = self.tmpPref["pref"]["general"]["endMessageFilesID"]
        self.wavsPref["endMessageLevels"] = self.tmpPref["pref"]["general"]["endMessageLevels"]

        if self.playChooser.currentText() != self.tr('custom'):
            self.playCommandWidget.setReadOnly(True)
        self.writewav.setChecked(self.tmpPref["pref"]["sound"]["writewav"])
        self.writeSndSeqSegments.setChecked(self.tmpPref["pref"]["sound"]["writeSndSeqSegments"])
        self.dpCorrCheckBox.setChecked(self.tmpPref["pref"]["general"]["dprimeCorrection"])
        self.listenerNameWarnCheckBox.setChecked(self.tmpPref["pref"]["general"]["listenerNameWarn"])
        self.sessionLabelWarnCheckBox.setChecked(self.tmpPref["pref"]["general"]["sessionLabelWarn"])

        self.emailNotify.setChecked(self.tmpPref["pref"]["email"]["notifyEnd"])
        self.sendData.setChecked(self.tmpPref["pref"]["email"]["sendData"])
        self.serverRequiresAuthCheckBox.setChecked(self.tmpPref["pref"]["email"]["serverRequiresAuthentication"])
        self.playEndMessage.setChecked(self.tmpPref["pref"]["general"]["playEndMessage"])
        
    def permanentApply(self):
        self.tryApply()
        if self.parent().prm['pref']['email']['fromPassword'] != self.tmpPref['pref']['email']['fromPassword']:
            passwd = bytes(self.passwordWidget.text(),'utf-8')
            encoded_passwd = base64.b64encode(passwd)
            encoded_passwd = str(encoded_passwd, "utf-8")
            #passwd = hashlib.sha1(passwd).hexdigest()
            self.tmpPref["pref"]["email"]['fromPassword'] = encoded_passwd
            self.passwordWidget.setText(self.tmpPref['pref']['email']['fromPassword'])
        
        self.parent().prm['pref'] = copy.deepcopy(self.tmpPref['pref'])
        f = open(self.parent().prm['prefFile'], 'wb')
        pickle.dump(self.parent().prm['pref'], f)
        f.close()
        
    def tabChanged(self):
        self.tryApply()
        if self.tmpPref['pref'] != self.parent().prm['pref']:
            reply = QMessageBox.warning(self, self.tr("Warning"), self.tr('There are unsaved changes. Apply Changes?'), QMessageBox.Yes | 
                                            QMessageBox.No, QMessageBox.Yes)
            if reply == QMessageBox.Yes:
                self.permanentApply()
            else:
                self.tmpPref['pref'] = copy.deepcopy(self.parent().prm['pref'])
                self.revertChanges()

    def listAlsaaudioPlaybackCards(self):
        playbackCardList = []
        for card in alsaaudio.cards():
            try:
                alsaaudio.PCM(type=alsaaudio.PCM_PLAYBACK, mode=alsaaudio.PCM_NORMAL, card=card)
                playbackCardList.append(card)
            except:
                pass
        return playbackCardList
    
    def listPyaudioPlaybackDevices(self):
        self.pyaudioHostApiListName = []
        self.pyaudioHostApiListIdx = []
        self.pyaudioDeviceListName = []
        self.pyaudioDeviceListIdx = []
        paManager = pyaudio.PyAudio()
        nDevices = paManager.get_device_count()
        nApi = paManager.get_host_api_count()
        for i in range(nApi):
            self.pyaudioHostApiListName.append(paManager.get_host_api_info_by_index(i)['name'])
            self.pyaudioHostApiListIdx.append(paManager.get_host_api_info_by_index(i)['index'])
        for i in range(nDevices):
            thisDevInfo = paManager.get_device_info_by_index(i)
            if thisDevInfo["maxOutputChannels"] > 0:
                self.pyaudioDeviceListName.append(thisDevInfo["name"] + ' - ' + self.pyaudioHostApiListName[thisDevInfo["hostApi"]])
                self.pyaudioDeviceListIdx.append(thisDevInfo["index"])
        return 
Beispiel #52
0
class WidgetFFmpeg2theora(QDialog):

    def __init__(self, idCodec, cheminVideoEntre, cheminSorti, valeurNum=0, laisserOuvert=1, systeme=None, cheminFfmpeg2theora=None, tempsApercu=None, optionSpeciale=None, cheminMPlayer=None):

        """widget mplayer"""
        QDialog.__init__(self)

        #=== Paramètres généraux ===#

        self.systeme=systeme

        # système d'exploitation
        if self.systeme=='linux' or self.systeme=='darwin' or self.systeme==None:
            self.cheminFfmpeg2theora=u"ffmpeg2theora"

        elif self.systeme=='windows':
            self.cheminFfmpeg2theora=unicode(cheminFfmpeg2theora)

        # chemins vidéos
        self.cheminVideoEntre = unicode(cheminVideoEntre)
        self.cheminSorti = unicode(cheminSorti)

        # identifiant du codec
        self.idCodec = idCodec

        # valeur de la boite de spin pour l'encodage
        self.valeurNum = valeurNum

        # laisser ouvert la fenêtre après encodage
        self.laisserOuvert = laisserOuvert

        # Conversion minimale du filtre pour avoir un aperçu.
        # Indique le temps où l'aperçu doit être créé
        self.tempsApercu = tempsApercu

        # drapeau pour ne pas lancer 2 fois l'encodage
        self.estLancee = False

        # Est-ce que le 1er % de progression a été récupéré (utile pour montage vidéo -> découper)?
        self.__recupPourcentDebut = 0

        self.log = [] # stocke les infos de mplayer et mencoder

        # Pour le son lors de la découpe vidéo pour l'instant
        if optionSpeciale!=None:
            self.optionSpeciale = optionSpeciale

        self.resize(500, 100)

        #=== Widgets ===#

        self.labelAttente=QLabel()
        self.labelAttente.setText(_(u"Attendez la fin du calcul s'il vous plaît, soyez patient !"))

        self.zoneTexte = QTextEdit("") # là où s'afficheront les infos
        if PYQT_VERSION_STR < "4.1.0":
            self.zoneTexte.setText = self.zoneTexte.setPlainText
        self.zoneTexte.setReadOnly(True)
        self.zoneTexte.hide()

        self.bout_annuler = QPushButton(_(u"Annuler"))

        self.bout_preZoneTexte = QPushButton(_("Voir les informations de l'encodage"))
        self.bout_preZoneTexte.hide()

        self.pbar = QProgressBar()
        self.pbar.setMaximum(100)

        #self.ffmpeg2theoraProcess = QProcess(self)
        self.ffmpeg2theoraProcess = FFmpeg2theora(cheminVideoEntre, cheminSorti, codec = idCodec)

        #=== mise-en-page/plan ===#

        vbox = QVBoxLayout()
        vbox.addWidget(self.labelAttente)
        vbox.addWidget(self.bout_preZoneTexte)
        vbox.addWidget(self.zoneTexte)
        hbox = QHBoxLayout()
        hbox.addWidget(self.pbar)
        hbox.addWidget(self.bout_annuler)
        vbox.addLayout(hbox)
        self.setLayout(vbox)

        #self.adjustSize()

        #=== connexion des widgets à des fonctions ===#

        # TEST # sert à calculer la durée d'exécution du script -> comparaison avec avec et sans traitement
        # des lignes de sortie de QProcess
        # 'readyReadStandardOutput()': signal émis lors de la sortie standart de lecture
        self.connect(self.ffmpeg2theoraProcess, SIGNAL('progress(int)'),
                                            self.pbar.setValue)
        self.connect(self.ffmpeg2theoraProcess, SIGNAL('log(QString)'),
                                            self.zoneTexte.append)
        self.connect(self.ffmpeg2theoraProcess, SIGNAL('finished(int)'),
                                            self.finEncodage)

        self.connect(self.bout_annuler, SIGNAL('clicked()'), self.close)
        self.connect(self.bout_preZoneTexte, SIGNAL('clicked()'), self.afficherLog)

    def close(self):
        """ Annule le traitement en cours """
        self.ffmpeg2theoraProcess.cancel()
        self.ffmpeg2theoraProcess.wait()
        #super(WidgetFFmpeg, self).close() # Python 2.6
        QDialog.close(self)

    def exec_(self):
        """ Surcharge de la fonction exec permettant l'execution hors de l'init"""
        self.demarrerEncodeur('Ffmpeg2theora')
        #super(WidgetFFmpeg, self).exec_() # Python 2.6
        QDialog.exec_(self)

    def demarrerEncodeur(self, encodeur):
        """démarrage de mencoder avec les arguments choisis"""

        if self.estLancee == False: # pas question de démarrer 2 fois l'encodage

            infos = "\n########################\n"
            infos += "# Informations MPlayer :\n"
            infos += "########################\n"

            debug(infos)

            # Utilisation de la classe infovideo (et en particilier la fonction setVideo)
            # présents dans gui_modules_animation/infoVideo.py
            info = infovideo(self.cheminVideoEntre)

            id_filename = 'ID_FILENAME='+self.cheminVideoEntre+'\n'
            debug(id_filename)
            id_demuxer = 'ID_DEMUXER='+info.demux+'\n'
            debug(id_demuxer)
            id_video_format = 'ID_VIDEO_FORMAT='+info.videoFormat+'\n'
            debug(id_video_format)
            id_video_codec = 'ID_VIDEO_CODEC='+info.video_codec+'\n'
            debug(id_video_codec)
            id_video_bitrate = 'ID_VIDEO_BITRATE='+str(info.videoBitrate)+'\n'
            debug(id_video_bitrate)
            id_video_largeur = 'ID_VIDEO_WIDTH='+str(info.videoLargeur)+'\n'
            debug(id_video_largeur)
            id_video_hauteur = 'ID_VIDEO_HEIGHT='+str(info.videoHauteur)+'\n'
            debug(id_video_hauteur)
            id_img_par_sec = 'ID_VIDEO_FPS='+str(info.imgParSec)+'\n'
            debug(id_img_par_sec)
            ##### Donnée très importante pour la suite du calcul (pour ffmpeg.py et ffmpeg2theora) ####
            self.dureeTotaleVideo = float(info.dureeTotaleVideo)
            ###########################################################################################
            id_duree_totale_video = 'ID_LENGTH='+str(info.dureeTotaleVideo)+'\n'
            debug(id_duree_totale_video)
            id_audio_codec = 'ID_AUDIO_CODEC='+info.audioCodec+'\n'
            debug(id_audio_codec)
            id_audio_rate = 'ID_AUDIO_RATE='+str(info.audioRate)+'\n'
            debug(id_audio_rate)
            id_audio_bitrate = 'ID_AUDIO_BITRATE='+str(info.audioBitrate)+'\n'
            debug(id_audio_bitrate)

            self.log.append(infos+id_filename+id_demuxer+id_video_format+id_video_codec+id_video_bitrate+id_video_largeur+id_video_hauteur+id_img_par_sec+id_duree_totale_video+id_audio_codec+id_audio_rate+id_audio_bitrate)
            ##############################################################################################

            infos = "\n############################\n"
            infos += "# Informations %s :\n" % encodeur
            infos += "############################\n"

            debug(infos)
            self.log.append(infos)

            self.ffmpeg2theoraProcess.setVideoLen(self.dureeTotaleVideo)

            if encodeur == 'Ffmpeg2theora':
                # mode de canal: on fusionne le canal de sortie normal
                # (stdout) et celui des erreurs (stderr)

                self.ffmpeg2theoraProcess.setCommand(self.valeurNum)
                self.ffmpeg2theoraProcess.start()

                debug(u"Commande lancée")
            self.estLancee = True



    def finEncodage(self, statutDeSortie):
        """choses à faire à la fin de l'encodage de la vidéo"""

        # fermer la fenêtre à la fin de l'encodage
        if not self.laisserOuvert:
            self.close()

        debug("fini!")
        self.labelAttente.hide()
        self.pbar.setValue(100)
        # l'encodage est fini. Il ne peut plus être annulé. La
        # seule action possible devient ainsi la fermeture
        self.bout_annuler.setText(_(u"Fermer"))
        self.bout_preZoneTexte.show()


    def afficherLog(self):
        """afficher les information de la vidéo de départ et de l'encodage"""
        self.zoneTexte.setText(self.ffmpeg2theoraProcess.log)
        self.zoneTexte.show()
        self.resize(500, 300)
Beispiel #53
0
class Form(QDialog):

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


        self.ql = QLabel("URL:")
        self.le = QLineEdit()
        self.le.setObjectName("URL")

        self.ql1 = QLabel("Name of Anime:")
        self.le1 = QLineEdit()
        self.le1.setObjectName("Name")

        self.ql2 = QLabel("Episodes(From):")
        self.le2 = QLineEdit()
        self.le2.setObjectName("Episodes")

        self.ql6 = QLabel("Episodes(Till):")
        self.le6 = QLineEdit()
        self.le6.setObjectName("Episodes")

        self.ql3 = QLabel("Season:")
        self.le3 = QLineEdit()
        self.le3.setObjectName("Season")

        self.ql4 = QLabel("Quality( 1:-360p  2:-480p  3:-720p  4:-1080p ):")
        self.le4 = QLineEdit()

        self.le4.setObjectName("Quality")

        self.ql5 = QLabel("Category:")
        self.le5 = QLineEdit()
        self.le5.setObjectName("Category")

        self.ql7 = QLabel("--::It requires RapidVideo Server to be available for downloading::--")
        self.ql9 = QLabel("--::This project is in development phase, giving absurd values will lead to errors::--")
        self.ql10 = QLabel("--::To exit program completely please exit uGet as well as the application window::--")
        self.ql11 = QLabel("--::For any issues raise the issue on GitHub (link in README.md)::--")
        self.ql8 = QLabel("\n")

        self.pb = QPushButton()
        self.pb.setObjectName("Download")
        self.pb.setText("Download")

        layout = QFormLayout()

        layout.addWidget(self.ql1)
        layout.addWidget(self.le1)

        layout.addWidget(self.ql)
        layout.addWidget(self.le)

        layout.addWidget(self.ql3)
        layout.addWidget(self.le3)
        layout.addWidget(self.ql2)
        layout.addWidget(self.le2)

        layout.addWidget(self.ql6)
        layout.addWidget(self.le6)

        layout.addWidget(self.ql4)
        layout.addWidget(self.le4)

        layout.addWidget(self.ql5)
        layout.addWidget(self.le5)

        layout.addWidget(self.ql7)
        layout.addWidget(self.ql9)
        layout.addWidget(self.ql10)
        layout.addWidget(self.ql11)
        layout.addWidget(self.ql8)

        layout.addWidget(self.pb)

        self.setLayout(layout)
        self.connect(self.pb, SIGNAL("clicked()"),self.button_click)


        self.setWindowTitle("Anime Downloader")

    def button_click(self):

        url = self.le.text()
        anime = self.le1.text()
        episodes1 = self.le2.text()
        episodes2 = self.le6.text()
        season = self.le3.text()
        quality = self.le4.text()
        category = self.le5.text()

        self.le.hide()
        self.le1.hide()
        self.le2.hide()
        self.le3.hide()
        self.le4.hide()
        self.le5.hide()
        self.ql1.hide()
        self.ql2.hide()
        self.ql3.hide()
        self.ql4.hide()
        self.ql5.hide()
        self.ql6.hide()
        self.ql7.hide()
        self.ql8.hide()
        self.ql9.hide()
        self.ql10.hide()
        self.ql11.hide()
        self.ql.hide()
        self.pb.hide()
        self.le6.hide()

        filepath = os.path.realpath(__file__)
        filepath = filepath.replace('/src/anime_downloader.py','/res/')
        image_path=filepath
        fo = open(filepath + 'config.cfg','w')
        fo.write(category + '\n')
        fo.close()
        fo1 = open(filepath + 'links.txt','w')
        fo1.write(anime + '\n' + season + '\n' + episodes1 +'\n')
        fo1.close()
        fo2 = open(filepath + 'data.txt','w')
        fo2.write(url + '\n' + quality + '\n' + episodes1 + '\n' + episodes2 + '\n')
        fo2.close()
        filepath1 = filepath.replace('/res/','/src/')
        subprocess.call(['python','populate_links.py'])
        subprocess.call(['python','download_script.py'])
        self.setStyleSheet("border-image: url("+image_path+"bg_img.jpg); background-repeat: no-repeat;")
Beispiel #54
0
class RunDialog(QDialog):

    def __init__(self, run_model):
        QDialog.__init__(self)
        self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint)
        self.setWindowFlags(self.windowFlags() & ~Qt.WindowCloseButtonHint)
        self.setModal(True)
        self.setWindowTitle("Simulations")

        assert isinstance(run_model, RunModelMixin)
        self.__run_model = run_model

        layout = QVBoxLayout()
        layout.setSizeConstraint(QLayout.SetFixedSize)

        self.simulations_tracker = SimulationsTracker()
        states = self.simulations_tracker.getList()

        self.total_progress = SimpleProgress()
        layout.addWidget(self.total_progress)


        status_layout = QHBoxLayout()
        status_layout.addStretch()
        self.__status_label = QLabel()
        status_layout.addWidget(self.__status_label)
        status_layout.addStretch()
        layout.addLayout(status_layout)

        self.progress = Progress()
        self.progress.setIndeterminateColor(self.total_progress.color)
        for state in states:
            self.progress.addState(state.state, QColor(*state.color), 100.0 * state.count / state.total_count)

        layout.addWidget(self.progress)

        legend_layout = QHBoxLayout()
        self.legends = {}
        for state in states:
            self.legends[state] = Legend("%s (%d/%d)", QColor(*state.color))
            self.legends[state].updateLegend(state.name, 0, 0)
            legend_layout.addWidget(self.legends[state])

        layout.addLayout(legend_layout)

        self.running_time = QLabel("")

        self.plot_tool = PlotTool()
        self.plot_tool.setParent(self)
        self.plot_button = QPushButton(self.plot_tool.getName())
        self.plot_button.clicked.connect(self.plot_tool.trigger)

        self.kill_button = QPushButton("Kill simulations")
        self.done_button = QPushButton("Done")
        self.done_button.setHidden(True)

        button_layout = QHBoxLayout()

        size = 20
        spin_movie = util.resourceMovie("ide/loading.gif")
        spin_movie.setSpeed(60)
        spin_movie.setScaledSize(QSize(size, size))
        spin_movie.start()

        self.processing_animation = QLabel()
        self.processing_animation.setMaximumSize(QSize(size, size))
        self.processing_animation.setMinimumSize(QSize(size, size))
        self.processing_animation.setMovie(spin_movie)

        button_layout.addWidget(self.processing_animation)
        button_layout.addWidget(self.running_time)
        button_layout.addStretch()
        button_layout.addWidget(self.plot_button)
        button_layout.addWidget(self.kill_button)
        button_layout.addWidget(self.done_button)

        layout.addStretch()
        layout.addLayout(button_layout)

        self.setLayout(layout)

        self.kill_button.clicked.connect(self.killJobs)
        self.done_button.clicked.connect(self.accept)

        self.__updating = False
        self.__update_queued = False
        self.__simulation_started = False

        self.__update_timer = QTimer(self)
        self.__update_timer.setInterval(500)
        self.__update_timer.timeout.connect(self.updateRunStatus)


    def startSimulation(self):
        simulation_thread = Thread(name="ert_gui_simulation_thread")
        simulation_thread.setDaemon(True)
        simulation_thread.run = self.__run_model.startSimulations
        simulation_thread.start()

        self.__update_timer.start()


    def checkIfRunFinished(self):
        if self.__run_model.isFinished():
            self.hideKillAndShowDone()

            if self.__run_model.hasRunFailed():
                error = self.__run_model.getFailMessage()
                QMessageBox.critical(self, "Simulations failed!", "The simulation failed with the following error:\n\n%s" % error)
                self.reject()


    def updateRunStatus(self):
        self.checkIfRunFinished()

        self.total_progress.setProgress(self.__run_model.getProgress())

        self.__status_label.setText(self.__run_model.getPhaseName())

        states = self.simulations_tracker.getList()

        if self.__run_model.isIndeterminate():
            self.progress.setIndeterminate(True)

            for state in states:
                self.legends[state].updateLegend(state.name, 0, 0)

        else:
            self.progress.setIndeterminate(False)
            total_count = self.__run_model.getQueueSize()
            queue_status = self.__run_model.getQueueStatus()

            for state in states:
                state.count = 0
                state.total_count = total_count

            for state in states:
                for queue_state in queue_status:
                    if queue_state in state.state:
                        state.count += queue_status[queue_state]

                self.progress.updateState(state.state, 100.0 * state.count / state.total_count)
                self.legends[state].updateLegend(state.name, state.count, state.total_count)

        self.setRunningTime()


    def setRunningTime(self):
        days = 0
        hours = 0
        minutes = 0
        seconds = self.__run_model.getRunningTime()

        if seconds >= 60:
            minutes, seconds = divmod(seconds, 60)

        if minutes >= 60:
            hours, minutes = divmod(minutes, 60)

        if hours >= 24:
            days, hours = divmod(hours, 24)

        if days > 0:
            self.running_time.setText("Running time: %d days %d hours %d minutes %d seconds" % (days, hours, minutes, seconds))
        elif hours > 0:
            self.running_time.setText("Running time: %d hours %d minutes %d seconds" % (hours, minutes, seconds))
        elif minutes > 0:
            self.running_time.setText("Running time: %d minutes %d seconds" % (minutes, seconds))
        else:
            self.running_time.setText("Running time: %d seconds" % seconds)


    def killJobs(self):
        kill_job = QMessageBox.question(self, "Kill simulations?", "Are you sure you want to kill the currently running simulations?", QMessageBox.Yes | QMessageBox.No )

        if kill_job == QMessageBox.Yes:
            self.__run_model.killAllSimulations()
            self.reject()


    def hideKillAndShowDone(self):
        self.__update_timer.stop()
        self.processing_animation.hide()
        self.kill_button.setHidden(True)
        self.done_button.setHidden(False)
Beispiel #55
0
class WSystem(QWidget, Logger.ClassLogger):
    """
    System widget
    """
    # action, description, misc, parameters
    AddStep = pyqtSignal(str, str, str, dict)
    UpdateStep = pyqtSignal(str, str, str, dict)
    CancelEdit = pyqtSignal()

    def __init__(self, parent):
        """
        Constructor
        """
        QWidget.__init__(self)

        self.createActions()
        self.createWidgets()
        self.createToolbar()
        self.createConnections()

    def createActions(self):
        """
        Create qt actions
        """
        self.addAction = QPushButton(QIcon(":/add_black.png"), '&Add Action',
                                     self)
        self.addAction.setMinimumHeight(40)
        self.addAction.setMaximumWidth(150)
        self.cancelAction = QtHelper.createAction(self,
                                                  "&Cancel",
                                                  self.cancelStep,
                                                  icon=QIcon(":/undo.png"),
                                                  tip='Cancel update')
        self.cancelAction.setEnabled(False)

        self.optionsAction = QtHelper.createAction(
            self,
            "&",
            self.openOptions,
            icon=QIcon(":/system-small.png"),
            tip='System options')

    def openOptions(self):
        """
        Open options dialog
        """
        if self.optionsDialog.exec_() == QDialog.Accepted:
            pass

    def createWidgets(self):
        """
        Create qt widgets
        """
        self.optionsDialog = OptionsDialog(self)

        self.validatorUpper = ValidatorUpper(self)
        self.validatorAll = ValidatorAll(self)
        self.validatorInt = QIntValidator(self)

        self.actionsComboBox = QComboBox(self)
        self.actionsComboBox.setMinimumHeight(40)
        for i in xrange(len(GuiSteps.ACTION_SYSTEM_DESCR)):
            if not len(GuiSteps.ACTION_SYSTEM_DESCR[i]):
                self.actionsComboBox.insertSeparator(i + 1)
            else:
                el = GuiSteps.ACTION_SYSTEM_DESCR[i].keys()
                self.actionsComboBox.addItem(list(el)[0])

        self.labelActionDescr = QLabel(self)
        self.labelActionDescr.hide()
        self.descriptionLine = QLineEdit(self)
        self.descriptionLine.setPlaceholderText("Step purpose description")
        self.descriptionLine.hide()

        actionsLayout = QHBoxLayout()
        actionsLayout.addWidget(self.actionsComboBox)

        actionLayout1 = QGridLayout()
        actionLayout1.addLayout(actionsLayout, 0, 1)

        self.createWidgetSession()
        self.createWidgetText()
        self.createWidgetShortcut()
        self.createWidgetScreen()

        actionLayout2 = QGridLayout()
        actionLayout2.addWidget(self.sessionGroup, 1, 0)
        actionLayout2.addWidget(self.textGroup, 1, 0)
        actionLayout2.addWidget(self.shortcutGroup, 1, 0)
        actionLayout2.addWidget(self.screenGroup, 1, 0)

        font = QFont()
        font.setBold(True)

        labelAct = QLabel(self.tr("Action: "))
        labelAct.setFont(font)

        self.arrowLabel = QLabel("")
        self.arrowLabel.setPixmap(
            QPixmap(":/arrow-right.png").scaledToWidth(32))

        self.arrowLabel2 = QLabel("")
        self.arrowLabel2.setPixmap(
            QPixmap(":/arrow-right.png").scaledToWidth(32))

        layoutFinal = QHBoxLayout()
        layoutFinal.addWidget(labelAct)
        layoutFinal.addLayout(actionLayout1)
        layoutFinal.addWidget(self.arrowLabel)
        layoutFinal.addLayout(actionLayout2)
        layoutFinal.addWidget(self.arrowLabel2)
        layoutFinal.addWidget(self.addAction)

        layoutFinal.addStretch(1)
        self.setLayout(layoutFinal)

    def createToolbar(self):
        """
        Create toolbar
        """
        pass

    def createWidgetScreen(self):
        """
        Create screen widget
        """
        self.screenGroup = QGroupBox(self.tr(""))

        # text
        self.checkComboBox = QComboBox(self)
        self.checkComboBox.addItems([
            GuiSteps.OP_ANY, GuiSteps.OP_CONTAINS, GuiSteps.OP_NOTCONTAINS,
            GuiSteps.OP_REGEXP, GuiSteps.OP_NOTREGEXP, GuiSteps.OP_STARTSWITH,
            GuiSteps.OP_NOTSTARTSWITH, GuiSteps.OP_ENDSWITH,
            GuiSteps.OP_NOTENDSWITH
        ])

        self.screenLine = QLineEdit(self)
        self.screenLine.setMinimumWidth(300)
        self.screenLine.setEnabled(False)
        self.screenLine.hide()
        self.screenArea = QTextEdit(self)
        self.screenArea.setMinimumWidth(300)
        self.screenArea.setEnabled(False)

        self.screenCombo = QComboBox(self)
        self.screenCombo.addItems(LIST_TYPES)
        self.screenCombo.setEnabled(False)

        self.screenSaveCombo = QComboBox(self)
        self.screenSaveCombo.addItems(["VARIABLE", "CACHE"])
        self.screenSaveLine = QLineEdit(self)
        self.screenSaveLine.setMinimumWidth(300)
        self.screenSaveLine.setEnabled(False)

        mainTextlayout = QGridLayout()
        mainTextlayout.addWidget(QLabel(self.tr("Checking if the screen: ")),
                                 0, 0)
        mainTextlayout.addWidget(self.checkComboBox, 0, 1)
        mainTextlayout.addWidget(QLabel(self.tr("The value:")), 1, 0)
        mainTextlayout.addWidget(self.screenCombo, 1, 1)
        mainTextlayout.addWidget(self.screenLine, 2, 1)
        mainTextlayout.addWidget(self.screenArea, 2, 1)
        mainTextlayout.addWidget(QLabel(self.tr("And save the screen in:")), 0,
                                 2)
        mainTextlayout.addWidget(self.screenSaveCombo, 1, 2)
        mainTextlayout.addWidget(self.screenSaveLine, 2, 2)

        self.screenGroup.setLayout(mainTextlayout)
        self.screenGroup.hide()

    def createWidgetText(self):
        """
        Create text widget
        """
        self.textGroup = QGroupBox(self.tr(""))

        # text
        self.textLine = QLineEdit(self)
        self.textLine.setMinimumWidth(300)
        self.textCombo = QComboBox(self)
        self.textCombo.addItems(LIST_TYPES)

        mainTextlayout = QGridLayout()
        mainTextlayout.addWidget(QLabel(self.tr("Send the value:")), 0, 0)
        mainTextlayout.addWidget(self.textCombo, 0, 1)
        mainTextlayout.addWidget(self.textLine, 0, 2)

        self.textGroup.setLayout(mainTextlayout)
        self.textGroup.hide()

    def createWidgetShortcut(self):
        """
        Create shortcut widget
        """
        self.shortcutGroup = QGroupBox(self.tr(""))

        # text
        self.shortcutComboBox = QComboBox()
        self.shortcutComboBox.addItems([KEY_CTRLC, KEY_ENTER])
        self.shortcutComboBox.setMinimumWidth(300)

        mainTextlayout = QGridLayout()
        mainTextlayout.addWidget(QLabel(self.tr("Shortcut:")), 0, 0)
        mainTextlayout.addWidget(self.shortcutComboBox, 0, 1)

        self.shortcutGroup.setLayout(mainTextlayout)
        self.shortcutGroup.hide()

    def createWidgetSession(self):
        """
        Create session widget
        """
        self.sessionGroup = QGroupBox(self.tr(""))

        # login
        self.loginLine = QLineEdit(self)
        self.loginLine.setMinimumWidth(300)
        self.loginCombo = QComboBox(self)
        self.loginCombo.addItems(LIST_TYPES)

        # password
        self.pwdLine = QLineEdit(self)
        self.pwdLine.setMinimumWidth(300)
        self.pwdCombo = QComboBox(self)
        self.pwdCombo.addItems(LIST_TYPES)

        # ip
        self.ipLine = QLineEdit(self)
        self.ipLine.setMinimumWidth(300)
        self.ipCombo = QComboBox(self)
        self.ipCombo.addItems(LIST_TYPES)

        # port
        self.portLine = QLineEdit(self)
        self.portLine.setMinimumWidth(300)
        self.portLine.setText("22")
        self.portLine.setValidator(self.validatorInt)
        self.portCombo = QComboBox(self)
        self.portCombo.addItems(LIST_TYPES)

        # agent support
        self.useAgent = QCheckBox("Use with agent mode")

        mainTextlayout = QGridLayout()
        mainTextlayout.addWidget(QLabel(self.tr("Host:")), 0, 0)
        mainTextlayout.addWidget(self.ipCombo, 0, 1)
        mainTextlayout.addWidget(self.ipLine, 0, 2)
        mainTextlayout.addWidget(QLabel(self.tr("Port (optional):")), 1, 0)
        mainTextlayout.addWidget(self.portCombo, 1, 1)
        mainTextlayout.addWidget(self.portLine, 1, 2)
        mainTextlayout.addWidget(QLabel(self.tr("Login:"******"Password:"******"""
        Create qt connections
        """
        self.actionsComboBox.currentIndexChanged.connect(self.onActionChanged)
        self.addAction.clicked.connect(self.addStep)

        self.ipCombo.currentIndexChanged.connect(self.onIpTypeChanged)
        self.portCombo.currentIndexChanged.connect(self.onPortTypeChanged)
        self.loginCombo.currentIndexChanged.connect(self.onLoginTypeChanged)
        self.pwdCombo.currentIndexChanged.connect(self.onPwdTypeChanged)

        self.textCombo.currentIndexChanged.connect(self.onTextTypeChanged)
        self.screenCombo.currentIndexChanged.connect(self.onScreenTypeChanged)
        self.checkComboBox.currentIndexChanged.connect(
            self.onScreenOperatorChanged)
        self.screenSaveCombo.currentIndexChanged.connect(
            self.onScreenSaveChanged)

    def pluginDataAccessor(self):
        """
        Return data to plugin
        """
        return {"data": ""}

    def onPluginImport(self, dataJson):
        """
        Received data from plugins
        """
        if "steps" not in dataJson:
            QMessageBox.warning(self, "Assistant Automation", "bad import")
            return

        if not isinstance(dataJson['steps'], list):
            QMessageBox.warning(self, "Assistant Automation", "bad import")
            return

        if not ('ip' in dataJson and 'login' in dataJson
                and 'password' in dataJson):
            QMessageBox.warning(self, "Assistant Automation", "bad import")
            return

        # emit open session
        parameters = {
            'dest-ip': dataJson['ip'],
            'dest-port': 22,
            'login': dataJson['login'],
            'password': dataJson['password'],
            'from-cache-ip': False,
            'from-alias-ip': False,
            'from-cache-port': False,
            'from-alias-port': False,
            'from-cache-login': False,
            'from-alias-login': False,
            'from-cache-pwd': False,
            'from-alias-pwd': False,
            'agent-support': False
        }
        self.AddStep.emit(GuiSteps.SYSTEM_SESSION, EMPTY_VALUE, EMPTY_VALUE,
                          parameters)

        for stp in dataJson['steps']:
            if isinstance(stp, dict):

                # new in v16
                fromCache = False
                fromAlias = False
                if "type-value" in stp:
                    if stp["type-value"].lower() == "cache": fromCache = True
                    if stp["type-value"].lower() == "alias": fromAlias = True
                # end of new

                if stp["action-name"] == "SEND":
                    parameters = {
                        'text': stp["action-value"],
                        'from-cache': fromCache,
                        'from-alias': fromAlias
                    }
                    self.AddStep.emit(GuiSteps.SYSTEM_TEXT, EMPTY_VALUE,
                                      EMPTY_VALUE, parameters)
                elif stp["action-name"] == "EXPECT":
                    op = "Contains"
                    if stp["action-type"] == "REGEX":
                        op = "RegEx"
                    parameters = {
                        'value': stp["action-value"],
                        'from-cache': fromCache,
                        'from-alias': fromAlias,
                        'operator': op,
                        'to-cache': False,
                        'cache-key': ''
                    }
                    self.AddStep.emit(GuiSteps.SYSTEM_CHECK_SCREEN,
                                      EMPTY_VALUE, EMPTY_VALUE, parameters)
                else:
                    QMessageBox.warning(
                        self, "Assistant Automation",
                        "action not yet supported: %s" % stp["action-name"])

        # close
        self.AddStep.emit(GuiSteps.SYSTEM_CLOSE, EMPTY_VALUE, EMPTY_VALUE, {})

    def onScreenOperatorChanged(self):
        """
        On screen operator changed
        """
        if self.checkComboBox.currentText() == GuiSteps.OP_ANY:
            self.screenLine.setEnabled(False)
            self.screenArea.setEnabled(False)
            self.screenCombo.setEnabled(False)
        else:
            self.screenLine.setEnabled(True)
            self.screenArea.setEnabled(True)
            self.screenCombo.setEnabled(True)

    def onScreenSaveChanged(self):
        """
        On screen save changed
        """
        if self.screenSaveCombo.currentText() == "VARIABLE":
            self.screenSaveLine.setEnabled(False)
        else:
            self.screenSaveLine.setEnabled(True)

    def onScreenTypeChanged(self):
        """
        On screen type changed
        """
        if self.screenCombo.currentText() in ["TEXT"]:
            self.screenArea.show()
            self.screenLine.hide()
        else:
            self.screenLine.show()
            self.screenArea.hide()
            if self.screenCombo.currentText() in ["CACHE"]:
                self.screenLine.setValidator(self.validatorAll)

            if self.screenCombo.currentText() == "ALIAS":
                self.screenLine.setText(self.screenLine.text().upper())
                self.screenLine.setValidator(self.validatorUpper)

    def onTextTypeChanged(self):
        """
        On text type changed
        """
        if self.textCombo.currentText() in ["TEXT", "CACHE"]:
            self.textLine.setValidator(self.validatorAll)

        if self.textCombo.currentText() == "ALIAS":
            self.textLine.setText(self.textLine.text().upper())
            self.textLine.setValidator(self.validatorUpper)

    def onLoginTypeChanged(self):
        """
        On login type changed
        """
        if self.loginCombo.currentText() in ["TEXT", "CACHE"]:
            self.loginLine.setValidator(self.validatorAll)

        if self.loginCombo.currentText() == "ALIAS":
            self.loginLine.setText(self.loginLine.text().upper())
            self.loginLine.setValidator(self.validatorUpper)

    def onPwdTypeChanged(self):
        """
        On password type changed
        """
        if self.pwdCombo.currentText() in ["TEXT", "CACHE"]:
            self.pwdLine.setValidator(self.validatorAll)

        if self.pwdCombo.currentText() == "ALIAS":
            self.pwdLine.setText(self.pwdLine.text().upper())
            self.pwdLine.setValidator(self.validatorUpper)

    def onIpTypeChanged(self):
        """
        On ip type changed
        """
        if self.ipCombo.currentText() in ["TEXT", "CACHE"]:
            self.ipLine.setValidator(self.validatorAll)

        if self.ipCombo.currentText() == "ALIAS":
            self.ipLine.setText(self.ipLine.text().upper())
            self.ipLine.setValidator(self.validatorUpper)

    def onPortTypeChanged(self):
        """
        On port type changed
        """
        if self.portCombo.currentText() in ["TEXT"]:
            self.portLine.setText("22")
            self.portLine.setValidator(self.validatorInt)

        if self.portCombo.currentText() in ["CACHE"]:
            self.portLine.setValidator(self.validatorAll)

        if self.portCombo.currentText() == "ALIAS":
            self.portLine.setText(self.portLine.text().upper())
            self.portLine.setValidator(self.validatorUpper)

    def onActionChanged(self):
        """
        On action changed
        """
        descr = 'No description available!'
        i = 0
        for el in GuiSteps.ACTION_SYSTEM_DESCR:
            if isinstance(el, dict):
                if self.actionsComboBox.currentText() in el:
                    descr = GuiSteps.ACTION_SYSTEM_DESCR[i][
                        self.actionsComboBox.currentText()]
                    break
            i += 1
        self.labelActionDescr.setText("%s\n" % descr)

        if self.actionsComboBox.currentText() in [GuiSteps.SYSTEM_SESSION]:
            self.sessionGroup.show()
            self.textGroup.hide()
            self.shortcutGroup.hide()
            self.screenGroup.hide()

            self.arrowLabel.show()
            self.arrowLabel2.show()

        elif self.actionsComboBox.currentText() in [GuiSteps.SYSTEM_CLOSE]:
            self.sessionGroup.hide()
            self.textGroup.hide()
            self.shortcutGroup.hide()
            self.screenGroup.hide()

            self.arrowLabel.hide()
            self.arrowLabel2.show()

        elif self.actionsComboBox.currentText() in [
                GuiSteps.SYSTEM_CLEAR_SCREEN
        ]:
            self.sessionGroup.hide()
            self.textGroup.hide()
            self.shortcutGroup.hide()
            self.screenGroup.hide()

            self.arrowLabel.hide()
            self.arrowLabel2.show()

        elif self.actionsComboBox.currentText() in [GuiSteps.SYSTEM_TEXT]:
            self.sessionGroup.hide()
            self.textGroup.show()
            self.shortcutGroup.hide()
            self.screenGroup.hide()

            self.arrowLabel.show()
            self.arrowLabel2.show()

        elif self.actionsComboBox.currentText() in [GuiSteps.SYSTEM_SHORTCUT]:
            self.sessionGroup.hide()
            self.textGroup.hide()
            self.shortcutGroup.show()
            self.screenGroup.hide()

            self.arrowLabel.show()
            self.arrowLabel2.show()

        elif self.actionsComboBox.currentText() in [
                GuiSteps.SYSTEM_CHECK_SCREEN
        ]:
            self.sessionGroup.hide()
            self.textGroup.hide()
            self.shortcutGroup.hide()
            self.screenGroup.show()

            self.arrowLabel.show()
            self.arrowLabel2.show()

        else:
            self.sessionGroup.hide()
            self.textGroup.hide()
            self.shortcutGroup.hide()
            self.screenGroup.hide()

            self.arrowLabel.hide()
            self.arrowLabel2.hide()

    def addStep(self):
        """
        Add step
        """
        action = self.actionsComboBox.currentText()
        descr = self.descriptionLine.text()
        descr = unicode(descr).replace('"', '')

        signal = self.AddStep
        if self.cancelAction.isEnabled():
            signal = self.UpdateStep

        if action in [GuiSteps.SYSTEM_SESSION]:
            fromCacheIp = False
            if self.ipCombo.currentText() == "CACHE": fromCacheIp = True
            fromAliasIp = False
            if self.ipCombo.currentText() == "ALIAS": fromAliasIp = True

            fromCachePort = False
            if self.portCombo.currentText() == "CACHE": fromCachePort = True
            fromAliasPort = False
            if self.portCombo.currentText() == "ALIAS": fromAliasPort = True

            fromCacheLogin = False
            if self.loginCombo.currentText() == "CACHE": fromCacheLogin = True
            fromAliasLogin = False
            if self.loginCombo.currentText() == "ALIAS": fromAliasLogin = True

            fromCachePwd = False
            if self.pwdCombo.currentText() == "CACHE": fromCachePwd = True
            fromAliasPwd = False
            if self.pwdCombo.currentText() == "ALIAS": fromAliasPwd = True

            newIp = self.ipLine.text()
            if not len(newIp):
                QMessageBox.warning(self, "Assistant",
                                    "Please to provide a ip!")
                return

            newPort = self.portLine.text()
            if not len(newPort):
                QMessageBox.warning(self, "Assistant",
                                    "Please to provide a port!")
                return

            newLogin = self.loginLine.text()
            if not len(newLogin):
                QMessageBox.warning(self, "Assistant",
                                    "Please to provide a login!")
                return

            newPwd = self.pwdLine.text()
            agentSupport = "False"
            if self.useAgent.isChecked(): agentSupport = "True"

            parameters = {
                'dest-ip': newIp,
                'dest-port': newPort,
                'login': newLogin,
                'password': newPwd,
                'from-cache-ip': fromCacheIp,
                'from-alias-ip': fromAliasIp,
                'from-cache-port': fromCachePort,
                'from-alias-port': fromAliasPort,
                'from-cache-login': fromCacheLogin,
                'from-alias-login': fromAliasLogin,
                'from-cache-pwd': fromCachePwd,
                'from-alias-pwd': fromAliasPwd,
                'agent-support': agentSupport
            }
            signal.emit(str(action), unicode(descr), EMPTY_VALUE, parameters)

        elif action in [GuiSteps.SYSTEM_CLOSE]:
            signal.emit(str(action), unicode(descr), EMPTY_VALUE, {})

        elif action in [GuiSteps.SYSTEM_CLEAR_SCREEN]:
            signal.emit(str(action), unicode(descr), EMPTY_VALUE, {})

        elif action in [GuiSteps.SYSTEM_TEXT]:
            fromCache = False
            if self.textCombo.currentText() == "CACHE": fromCache = True
            fromAlias = False
            if self.textCombo.currentText() == "ALIAS": fromAlias = True

            newText = self.textLine.text()
            if not len(newText):
                QMessageBox.warning(self, "Assistant",
                                    "Please to provide text!")
                return
            parameters = {
                'text': newText,
                'from-cache': fromCache,
                'from-alias': fromAlias
            }
            signal.emit(str(action), unicode(descr), EMPTY_VALUE, parameters)

        elif action in [GuiSteps.SYSTEM_SHORTCUT]:

            newShortcut = self.shortcutComboBox.currentText()
            parameters = {'shortcut': newShortcut}
            signal.emit(str(action), unicode(descr), EMPTY_VALUE, parameters)

        elif action in [GuiSteps.SYSTEM_CHECK_SCREEN]:
            op = self.checkComboBox.currentText()
            fromCache = False
            if self.screenCombo.currentText() == "CACHE": fromCache = True
            fromAlias = False
            if self.screenCombo.currentText() == "ALIAS": fromAlias = True

            toCache = False
            if self.screenSaveCombo.currentText() == "CACHE": toCache = True
            keyCache = self.screenSaveLine.text()

            newText = ""
            if op != GuiSteps.OP_ANY:
                if fromCache or fromAlias:
                    newText = self.screenLine.text()
                else:
                    newText = self.screenArea.toPlainText()
                if not len(newText):
                    QMessageBox.warning(self, "Assistant",
                                        "Please to provide value to search!")
                    return

            parameters = {
                'value': newText,
                'from-cache': fromCache,
                'from-alias': fromAlias,
                'operator': op,
                'to-cache': toCache,
                'cache-key': keyCache
            }
            signal.emit(str(action), unicode(descr), EMPTY_VALUE, parameters)

        else:
            signal.emit(str(action), unicode(descr), EMPTY_VALUE, {})

    def cancelStep(self):
        """
        Cancel step
        """
        self.addAction.setText("&Add")

        buttonFont = QFont()
        buttonFont.setBold(False)
        self.addAction.setFont(buttonFont)
        self.cancelAction.setEnabled(False)

        self.CancelEdit.emit()

    def finalizeUpdate(self):
        """
        Finalize the update of the step
        """
        self.addAction.setText("&Add Action")

        buttonFont = QFont()
        buttonFont.setBold(False)
        self.addAction.setFont(buttonFont)
        self.cancelAction.setEnabled(False)

    def editStep(self, stepData):
        """
        Edit step
        """
        self.addAction.setText("&Update")
        buttonFont = QFont()
        buttonFont.setBold(True)
        self.addAction.setFont(buttonFont)

        self.cancelAction.setEnabled(True)

        # set the current value for actions combo
        for i in xrange(self.actionsComboBox.count()):
            item_text = self.actionsComboBox.itemText(i)
            if unicode(stepData["action"]) == unicode(item_text):
                self.actionsComboBox.setCurrentIndex(i)
                break

        # and then refresh options
        self.onActionChanged()

        # finally fill all fields
        self.descriptionLine.setText(stepData["description"])

        if self.actionsComboBox.currentText() in [GuiSteps.SYSTEM_SESSION]:
            self.ipLine.setText(stepData["parameters"]["dest-ip"])
            self.portLine.setText("%s" % stepData["parameters"]["dest-port"])
            self.loginLine.setText(stepData["parameters"]["login"])
            self.pwdLine.setText(stepData["parameters"]["password"])

            if stepData["parameters"]["from-cache-ip"]:
                self.ipLine.setValidator(self.validatorAll)
                self.ipCombo.setCurrentIndex(INDEX_CACHE)
            elif stepData["parameters"]["from-alias-ip"]:
                self.ipLine.setValidator(self.validatorUpper)
                self.ipCombo.setCurrentIndex(INDEX_ALIAS)
            else:
                self.ipLine.setValidator(self.validatorAll)
                self.ipCombo.setCurrentIndex(INDEX_TEXT)

            if stepData["parameters"]["from-cache-port"]:
                self.portLine.setValidator(self.validatorAll)
                self.portCombo.setCurrentIndex(INDEX_CACHE)
            elif stepData["parameters"]["from-alias-port"]:
                self.portLine.setValidator(self.validatorUpper)
                self.portCombo.setCurrentIndex(INDEX_ALIAS)
            else:
                self.portLine.setValidator(self.validatorInt)
                self.portCombo.setCurrentIndex(INDEX_TEXT)

            if stepData["parameters"]["from-cache-login"]:
                self.loginLine.setValidator(self.validatorAll)
                self.loginCombo.setCurrentIndex(INDEX_CACHE)
            elif stepData["parameters"]["from-alias-login"]:
                self.loginLine.setValidator(self.validatorUpper)
                self.loginCombo.setCurrentIndex(INDEX_ALIAS)
            else:
                self.loginLine.setValidator(self.validatorAll)
                self.loginCombo.setCurrentIndex(INDEX_TEXT)

            if stepData["parameters"]["from-cache-pwd"]:
                self.pwdLine.setValidator(self.validatorAll)
                self.pwdCombo.setCurrentIndex(INDEX_CACHE)
            elif stepData["parameters"]["from-alias-pwd"]:
                self.pwdLine.setValidator(self.validatorUpper)
                self.pwdCombo.setCurrentIndex(INDEX_ALIAS)
            else:
                self.pwdLine.setValidator(self.validatorAll)
                self.pwdCombo.setCurrentIndex(INDEX_TEXT)

        if self.actionsComboBox.currentText() in [GuiSteps.SYSTEM_CLOSE]:
            pass

        if self.actionsComboBox.currentText() in [
                GuiSteps.SYSTEM_CLEAR_SCREEN
        ]:
            pass

        if self.actionsComboBox.currentText() in [GuiSteps.SYSTEM_TEXT]:

            if stepData["parameters"]["from-cache"]:
                self.textLine.setValidator(self.validatorAll)
                self.textCombo.setCurrentIndex(INDEX_CACHE)
            elif stepData["parameters"]["from-alias"]:
                self.textLine.setValidator(self.validatorUpper)
                self.textCombo.setCurrentIndex(INDEX_ALIAS)
            else:
                self.textLine.setValidator(self.validatorAll)
                self.textCombo.setCurrentIndex(INDEX_TEXT)

            self.textLine.setText(stepData["parameters"]["text"])

        if self.actionsComboBox.currentText() in [GuiSteps.SYSTEM_SHORTCUT]:

            for i in xrange(self.shortcutComboBox.count()):
                item_text = self.shortcutComboBox.itemText(i)
                if unicode(stepData["parameters"]["shortcut"]) == unicode(
                        item_text):
                    self.shortcutComboBox.setCurrentIndex(i)
                    break

        if self.actionsComboBox.currentText() in [
                GuiSteps.SYSTEM_CHECK_SCREEN
        ]:

            if stepData["parameters"]["from-cache"]:
                self.screenLine.setValidator(self.validatorAll)
                self.screenCombo.setCurrentIndex(INDEX_CACHE)
                self.screenLine.setText(stepData["parameters"]["value"])
            elif stepData["parameters"]["from-alias"]:
                self.screenLine.setValidator(self.validatorUpper)
                self.screenCombo.setCurrentIndex(INDEX_ALIAS)
                self.screenLine.setText(stepData["parameters"]["value"])
            else:
                self.screenCombo.setCurrentIndex(INDEX_TEXT)
                self.screenArea.setPlainText(stepData["parameters"]["value"])

            for i in xrange(self.checkComboBox.count()):
                item_text = self.checkComboBox.itemText(i)
                if unicode(stepData["parameters"]["operator"]) == unicode(
                        item_text):
                    self.checkComboBox.setCurrentIndex(i)
                    break

            if stepData["parameters"]["to-cache"]:
                self.screenSaveCombo.setCurrentIndex(1)
                self.screenSaveLine.setText(
                    stepData["parameters"]["cache-key"])
            else:
                self.screenSaveCombo.setCurrentIndex(0)

    def getTimeout(self):
        """
        Return timeout value
        """
        return self.optionsDialog.timeoutLine.text()

    def setTimeout(self, timeout):
        """
        Set the timeout
        """
        return self.optionsDialog.timeoutLine.setText(timeout)

    def getAgentName(self):
        """
        Return the agent name
        """
        return self.optionsDialog.agentNameLine.text()

    def getAgentList(self):
        """
        Return the agent list
        """
        return self.optionsDialog.agentsList
class WAndroid(QWidget, Logger.ClassLogger):
    """
    Android widget
    """
    # action, description, misc, parameters
    AddStep = pyqtSignal(str, str, str, dict)
    UpdateStep = pyqtSignal(str, str, str, dict)    
    CancelEdit = pyqtSignal()
    def __init__(self, parent):
        """
        Constructor
        """
        QWidget.__init__(self)

        self.createActions()
        self.createWidgets()
        self.createToolbar()
        self.createConnections()
    
    def createActions(self):
        """
        Create qt actions
        """
        self.addAndroidAction = QPushButton(QIcon(":/add_black.png"), '&Add Action', self)
        self.addAndroidAction.setMinimumHeight(40)         
        self.addAndroidAction.setMaximumWidth(150)
        
        self.cancelAndroidAction = QtHelper.createAction(self, "&Cancel", self.cancelStep, 
                                            icon=None, tip = 'Cancel update')
        self.cancelAndroidAction.setEnabled(False)
        
        self.optionsAction = QtHelper.createAction(self, "&", self.openOptions, 
                                            icon=QIcon(":/recorder-mobile-small.png"), tip = 'Android options')
                                            
    def createWidgets(self):
        """
        Create qt widgets
        """
        self.optionsDialog  = OptionsDialog(self)
        
        self.validatorUpper = ValidatorUpper(self)
        self.validatorAll = ValidatorAll(self)
        self.validatorInt = QIntValidator(self)

        ###################### android action #########################

        self.actionsAndroidComboBox = QComboBox(self)
        self.actionsAndroidComboBox.setMinimumHeight(40)
        for i in xrange(len(GuiSteps.ACTION_ANDROID_DESCR)):
            if not len( GuiSteps.ACTION_ANDROID_DESCR[i] ):
                self.actionsAndroidComboBox.insertSeparator(i+1)
            else:
                el = GuiSteps.ACTION_ANDROID_DESCR[i].keys()
                self.actionsAndroidComboBox.addItem( list(el)[0] )
            
        self.descriptionAndroidLine = QLineEdit(self)
        self.descriptionAndroidLine.setPlaceholderText("Step purpose description")
        self.descriptionAndroidLine.hide()

        self.labelActionAndroidDescr = QLabel( )
        self.labelActionAndroidDescr.hide()
        self.labelActionAndroidDescr.setText( "%s\n" % GuiSteps.ACTION_ANDROID_DESCR[0][GuiSteps.ANDROID_WAKEUP_UNLOCK])
        self.labelActionAndroidDescr.setWordWrap(True)
        
        actionsLayout = QHBoxLayout()
        actionsLayout.addWidget(self.actionsAndroidComboBox)
        
        actionLayoutAndroid = QGridLayout()
        actionLayoutAndroid.addLayout(actionsLayout, 0, 1)

        self.createWidgetShortcut()
        self.createWidgetCode()
        self.createWidgetStart()
        self.createWidgetXY()
        self.createWidgetEndXY()
        self.createWidgetElement()
        self.createWidgetTextTo()
        self.createWidgetLine()
        self.createWidgetLine2()
        
        actionLayoutAndroid2 = QGridLayout()
        actionLayoutAndroid2.addWidget( self.shortcutAndroidGroup , 0, 0)
        actionLayoutAndroid2.addWidget( self.codeAndroidGroup , 0, 0)
        actionLayoutAndroid2.addWidget( self.elemenAndroidGroup , 0, 0)
        actionLayoutAndroid2.addWidget( self.xyAndroidGroup , 0, 0)
        actionLayoutAndroid2.addWidget( self.startAndroidGroup , 0, 0)
        actionLayoutAndroid2.addWidget( self.lineAndroidGroup , 1, 0)
        actionLayoutAndroid2.addWidget( self.line2AndroidGroup , 0, 1)
        actionLayoutAndroid2.addWidget( self.textToGlobalGroup , 0, 1)
        actionLayoutAndroid2.addWidget( self.endXyAndroidGroup, 0, 1)
        
        font = QFont()
        font.setBold(True)
        
        labelAct = QLabel( self.tr("Action: ") )
        labelAct.setFont( font) 
        
        self.arrowLabel = QLabel("")
        self.arrowLabel.setPixmap(QPixmap(":/arrow-right.png").scaledToWidth(32))
        self.arrowLabel.hide()
        
        self.arrowLabel2 = QLabel("")
        self.arrowLabel2.setPixmap(QPixmap(":/arrow-right.png").scaledToWidth(32))

        layoutAndroid = QHBoxLayout()
        layoutAndroid.addWidget( labelAct )
        layoutAndroid.addLayout( actionLayoutAndroid )
        layoutAndroid.addWidget( self.arrowLabel )
        layoutAndroid.addLayout( actionLayoutAndroid2 )
        layoutAndroid.addWidget( self.arrowLabel2 )
        layoutAndroid.addWidget(self.addAndroidAction)

        layoutAndroid.addStretch(1)
        self.setLayout(layoutAndroid)
        
    def createToolbar(self):
        """
        Create qt toolbar
        """
        pass
        
    def openOptions(self):
        """
        Open options
        """
        if self.optionsDialog.exec_() == QDialog.Accepted:
            pass
            
    def createWidgetLine2(self):
        """
        Create line widget
        """
        self.valueAndroidLine2 = QLineEdit(self)
        self.valueAndroidLine2.setMinimumWidth(150)
        self.valueAndroidCombo2 = QComboBox(self)
        self.valueAndroidCombo2.addItems( LIST_TYPES )

        self.line2AndroidGroup = QGroupBox(self.tr(""))
        
        line2Androidlayout = QGridLayout()
        line2Androidlayout.addWidget( QLabel( self.tr("Text to type:") ), 0, 0  ) 
        line2Androidlayout.addWidget( self.valueAndroidCombo2, 0, 1 )
        line2Androidlayout.addWidget( self.valueAndroidLine2, 0, 2 )

        self.line2AndroidGroup.setLayout(line2Androidlayout)
        self.line2AndroidGroup.hide()
        
    def createWidgetLine(self):
        """
        Create line widget
        """
        self.lineAndroidGroup = QGroupBox(self.tr(""))
        lineAndroidlayout = QGridLayout()
        self.valueAndroidLine = QLineEdit(self)
        self.valueAndroidLine.setMinimumWidth(300)
        lineAndroidlayout.addWidget( QLabel( self.tr("Value:") ) , 0,1)
        lineAndroidlayout.addWidget( self.valueAndroidLine , 0, 2)
        self.lineAndroidGroup.setLayout(lineAndroidlayout)
        self.lineAndroidGroup.hide()
        
    def createWidgetTextTo(self):
        """
        Create text widget
        """
        self.valueTextCacheGlobalLine = QLineEdit(self)
        self.valueTextCacheGlobalLine.setMinimumWidth(150)
        self.valueTextCacheGlobalCombo = QComboBox(self)
        self.valueTextCacheGlobalCombo.addItems( ["CACHE"] )
        
        self.textToGlobalGroup = QGroupBox(self.tr(""))
        textToGloballayout = QGridLayout()
        textToGloballayout.addWidget( QLabel( self.tr("Save text in:") ) , 0, 0)
        textToGloballayout.addWidget( self.valueTextCacheGlobalCombo , 0, 1)
        textToGloballayout.addWidget( self.valueTextCacheGlobalLine , 0, 2)
        self.textToGlobalGroup.setLayout(textToGloballayout)
        self.textToGlobalGroup.hide()
        
    def createWidgetElement(self):
        """
        Create text widget
        """
        self.elemenAndroidGroup = QGroupBox(self.tr(""))
        
        self.elementTextAndroidLine = QLineEdit(self)
        self.elementTextAndroidLine.setMinimumWidth(300)
        self.elementTextCombo = QComboBox(self)
        self.elementTextCombo.addItems( LIST_TYPES )
        
        self.elementDescriptionAndroidLine = QLineEdit(self)
        self.elementDescriptionAndroidLine.setMinimumWidth(300)
        self.elementClassAndroidLine = QLineEdit(self)
        self.elementClassAndroidLine.setMinimumWidth(300)
        self.elementRessourceIdAndroidLine = QLineEdit(self)
        self.elementRessourceIdAndroidLine.setMinimumWidth(300)
        self.elementPackageAndroidLine = QLineEdit(self)
        self.elementPackageAndroidLine.setMinimumWidth(300)

        # get  text end
        elementAndroidlayout = QGridLayout()
        elementAndroidlayout.addWidget( QLabel( self.tr("Text Element:") ) , 0,1)
        elementAndroidlayout.addWidget( self.elementTextCombo , 0, 2)
        elementAndroidlayout.addWidget( self.elementTextAndroidLine , 0, 3)
        elementAndroidlayout.addWidget( QLabel( self.tr("Description Element:") ) , 1,1)
        elementAndroidlayout.addWidget( self.elementDescriptionAndroidLine , 1, 3)
        elementAndroidlayout.addWidget( QLabel( self.tr("Class Name:") ) , 2,1)
        elementAndroidlayout.addWidget( self.elementClassAndroidLine , 2, 3)
        elementAndroidlayout.addWidget( QLabel( self.tr("Resource ID:") ) , 3,1)
        elementAndroidlayout.addWidget( self.elementRessourceIdAndroidLine , 3, 3)
        elementAndroidlayout.addWidget( QLabel( self.tr("Package Name:") ) , 4,1)
        elementAndroidlayout.addWidget( self.elementPackageAndroidLine , 4, 3)
        self.elemenAndroidGroup.setLayout(elementAndroidlayout)
        self.elemenAndroidGroup.hide()
        
    def createWidgetEndXY(self):
        """
        Create widget 
        """
        self.endXyAndroidGroup = QGroupBox(self.tr(""))
        endXyAndroidlayout = QGridLayout()
        
        self.endxAndroidLine = QLineEdit(self)
        validatorEndXAndroid = QIntValidator (self)
        self.endxAndroidLine.setValidator(validatorEndXAndroid)
        self.endxAndroidLine.installEventFilter(self)
        
        self.endyAndroidLine = QLineEdit(self)
        validatorEndYAndroid = QIntValidator (self)
        self.endyAndroidLine.setValidator(validatorEndYAndroid)
        self.endyAndroidLine.installEventFilter(self)
        
        endXyAndroidlayout.addWidget( QLabel( self.tr("Destination Coordinate X:") ) , 0, 0)
        endXyAndroidlayout.addWidget( self.endxAndroidLine , 0, 1)
        endXyAndroidlayout.addWidget( QLabel( self.tr("Destination Coordinate Y:") ) , 1,0)
        endXyAndroidlayout.addWidget( self.endyAndroidLine , 1, 1)
        
        self.endXyAndroidGroup.setLayout(endXyAndroidlayout)
        self.endXyAndroidGroup.hide()
        
    def createWidgetXY(self):
        """
        Create text widget
        """
        self.xyAndroidGroup = QGroupBox(self.tr(""))
        xyAndroidlayout = QGridLayout()
        
        self.xAndroidLine = QLineEdit(self)
        validatorXAndroid = QIntValidator (self)
        self.xAndroidLine.setValidator(validatorXAndroid)
        self.xAndroidLine.installEventFilter(self)
        
        self.yAndroidLine = QLineEdit(self)
        validatorYAndroid = QIntValidator (self)
        self.yAndroidLine.setValidator(validatorYAndroid)
        self.yAndroidLine.installEventFilter(self)
        
        xyAndroidlayout.addWidget( QLabel( self.tr("Coordinate X:") ) , 0,0)
        xyAndroidlayout.addWidget( self.xAndroidLine , 0, 1)
        xyAndroidlayout.addWidget( QLabel( self.tr("Coordinate Y:") ) , 1,0)
        xyAndroidlayout.addWidget( self.yAndroidLine , 1, 1)
        
        self.xyAndroidGroup.setLayout(xyAndroidlayout)
        self.xyAndroidGroup.hide()
        
    def createWidgetStart(self):
        """
        Create text widget
        """
        self.startAndroidGroup = QGroupBox(self.tr(""))
        startAndroidlayout = QGridLayout()
        
        self.startXAndroidLine = QLineEdit(self)
        validatorStartXAndroid = QIntValidator (self)
        self.startXAndroidLine.setValidator(validatorStartXAndroid)
        self.startXAndroidLine.installEventFilter(self)
        
        self.startYAndroidLine = QLineEdit(self)
        validatorStartYAndroid = QIntValidator (self)
        self.startYAndroidLine.setValidator(validatorStartYAndroid)
        self.startYAndroidLine.installEventFilter(self)
        
        self.stopXAndroidLine = QLineEdit(self)
        validatorStopXAndroid = QIntValidator (self)
        self.stopXAndroidLine.setValidator(validatorStopXAndroid)
        self.stopXAndroidLine.installEventFilter(self)
        
        self.stopYAndroidLine = QLineEdit(self)
        validatorStopYAndroid = QIntValidator (self)
        self.stopYAndroidLine.setValidator(validatorStopYAndroid)
        self.stopYAndroidLine.installEventFilter(self)
        
        startAndroidlayout.addWidget( QLabel( self.tr("From X:") ) , 0,1)
        startAndroidlayout.addWidget( self.startXAndroidLine , 0, 2)
        startAndroidlayout.addWidget( QLabel( self.tr("From Y:") ) , 0,3)
        startAndroidlayout.addWidget( self.startYAndroidLine , 0, 4)
        startAndroidlayout.addWidget( QLabel( self.tr("To X:") ) ,1,1)
        startAndroidlayout.addWidget( self.stopXAndroidLine , 1, 2)
        startAndroidlayout.addWidget( QLabel( self.tr("To Y:") ) , 1,3)
        startAndroidlayout.addWidget( self.stopYAndroidLine , 1 , 4)
        self.startAndroidGroup.setLayout(startAndroidlayout)
        self.startAndroidGroup.hide()
        
    def createWidgetShortcut(self):
        """
        Create shortcut widget
        """
        self.shortcutAndroidGroup = QGroupBox(self.tr(""))
        shortcutAndroidlayout = QGridLayout()

        self.shortcutAndroidComboBox = QComboBox(self)
        for i in xrange(len(KEYS_SHORTCUT_ANDROID)):
            if len(KEYS_SHORTCUT_ANDROID[i]) == 0:
                self.shortcutAndroidComboBox.insertSeparator(i + 2)
            else:
                self.shortcutAndroidComboBox.addItem (KEYS_SHORTCUT_ANDROID[i])

        shortcutAndroidlayout.addWidget( QLabel( self.tr("Button:") ) , 0,1)
        shortcutAndroidlayout.addWidget(self.shortcutAndroidComboBox, 0, 2)
        
        self.shortcutAndroidGroup.setLayout(shortcutAndroidlayout)
        self.shortcutAndroidGroup.hide()

    def createWidgetCode(self):
        """
        Create code widget
        """
        self.codeAndroidGroup = QGroupBox(self.tr(""))
        self.codeAndroidLine = QLineEdit(self)
        validatorCodeAndroid = QIntValidator (self)
        self.codeAndroidLine.setValidator(validatorCodeAndroid)
        self.codeAndroidLine.installEventFilter(self)
        
        codeAndroidlayout = QGridLayout()
        codeAndroidlayout.addWidget( QLabel( self.tr("Code:") ) , 0,1)
        codeAndroidlayout.addWidget( self.codeAndroidLine , 0, 2)
        self.codeAndroidGroup.setLayout(codeAndroidlayout)
        self.codeAndroidGroup.hide()
        
    def pluginDataAccessor(self):
        """
        Return data for plugin
        """
        return { "data": "" } 
        
    def onPluginImport(self, dataJson):
        """
        Received data from plugin
        """
        pass

    def createConnections(self):
        """
        Create qt connections
        """
        self.actionsAndroidComboBox.currentIndexChanged.connect(self.onActionAndroidChanged)
        self.addAndroidAction.clicked.connect(self.addStep)
        self.valueAndroidCombo2.currentIndexChanged.connect(self.onValueAndroid2TypeChanged)
        self.elementTextCombo.currentIndexChanged.connect(self.onElementTextTypeChanged)
        
    def onElementTextTypeChanged(self):
        """
        On element text changed
        """
        if self.elementTextCombo.currentText() in [ "TEXT", "CACHE" ]:
            self.elementTextAndroidLine.setValidator(self.validatorAll)
            
        if self.elementTextCombo.currentText() == "ALIAS":
            self.elementTextAndroidLine.setText( self.elementTextAndroidLine.text().upper() )
            self.elementTextAndroidLine.setValidator(self.validatorUpper)
            
    def onValueAndroid2TypeChanged(self):
        """
        On value changed
        """
        if self.valueAndroidCombo2.currentText() in [ "TEXT", "CACHE" ]:
            self.valueAndroidLine2.setValidator(self.validatorAll)
            
        if self.valueAndroidCombo2.currentText() == "ALIAS":
            self.valueAndroidLine2.setText( self.valueAndroidLine2.text().upper() )
            self.valueAndroidLine2.setValidator(self.validatorUpper)

    def addStep(self):
        """
        Add step
        """
        action = self.actionsAndroidComboBox.currentText()
        descr = self.descriptionAndroidLine.text()
        descr = unicode(descr).replace('"', '')
        
        signal = self.AddStep
        if self.cancelAndroidAction.isEnabled():
            signal = self.UpdateStep
            
        if self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_WAKUP, GuiSteps.ANDROID_UNLOCK, GuiSteps.ANDROID_REBOOT, 
                                                        GuiSteps.ANDROID_SLEEP, GuiSteps.ANDROID_FREEZE_ROTATION, GuiSteps.ANDROID_UNFREEZE_ROTATION, 
                                                        GuiSteps.ANDROID_BOOTLOADER, GuiSteps.ANDROID_RECOVERY, GuiSteps.ANDROID_NOTIFICATION, 
                                                        GuiSteps.ANDROID_SETTINGS, GuiSteps.ANDROID_DEVICEINFO, GuiSteps.ANDROID_GET_LOGS, 
                                                        GuiSteps.ANDROID_CLEAR_LOGS , GuiSteps.ANDROID_WAKEUP_UNLOCK, GuiSteps.ANDROID_LOCK,
                                                        GuiSteps.ANDROID_SLEEP_LOCK ]:
            signal.emit( str(action), unicode(descr), EMPTY_VALUE, {} )
            
        elif self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_TYPE_SHORTCUT]:
            shorcut = self.shortcutAndroidComboBox.currentText()
            signal.emit( str(action), unicode(descr), shorcut, {} )
            
        elif self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_TYPE_KEYCODE ]:
            code = self.codeAndroidLine.text()
            if not len(code):
                QMessageBox.warning(self, "Recording for Gui" , "Please to set a value!")
            else:
                signal.emit( str(action), unicode(descr), code, {} )
                
        elif self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_CLEAR_ELEMENT, GuiSteps.ANDROID_CLICK_ELEMENT, GuiSteps.ANDROID_LONG_CLICK_ELEMENT,
                                                            GuiSteps.ANDROID_EXIST_ELEMENT, GuiSteps.ANDROID_WAIT_ELEMENT, GuiSteps.ANDROID_TYPE_TEXT_ELEMENT,
                                                            GuiSteps.ANDROID_GET_TEXT_ELEMENT, GuiSteps.ANDROID_DRAG_ELEMENT, GuiSteps.ANDROID_WAIT_CLICK_ELEMENT ]:
            textAndroid = self.elementTextAndroidLine.text()
            descrAndroid = self.elementDescriptionAndroidLine.text()
            classAndroid = self.elementClassAndroidLine.text()
            ressourceAndroid = self.elementRessourceIdAndroidLine.text()
            packageAndroid = self.elementPackageAndroidLine.text()
            if not len(textAndroid) and not len(classAndroid) and not len(ressourceAndroid) and not len(packageAndroid) and not len(descrAndroid):
                QMessageBox.warning(self, "Recording for Gui" , "Please to set one value!")
            else:
                # read text from cache or not ?
                fromElCache = False
                if self.elementTextCombo.currentText() == "CACHE": fromElCache = True
                fromElAlias = False
                if self.elementTextCombo.currentText() == "ALIAS": fromElAlias = True
                        
                if self.actionsAndroidComboBox.currentText() == GuiSteps.ANDROID_TYPE_TEXT_ELEMENT:
                    newTextAndroid = self.valueAndroidLine2.text()
                    if not len(newTextAndroid):
                        QMessageBox.warning(self, "Recording for Gui" , "Please to set a text value!")
                    else:
                        # read text from cache or not ?
                        fromCache = False
                        if self.valueAndroidCombo2.currentText() == "CACHE": fromCache = True
                        fromAlias = False
                        if self.valueAndroidCombo2.currentText() == "ALIAS": fromAlias = True
                        
                        parameters = {'text': textAndroid, 'class': classAndroid, 'ressource': ressourceAndroid, 
                                        'package': packageAndroid, 'description': descrAndroid, 'new-text': newTextAndroid,
                                        'from-cache': fromCache, 'from-alias': fromAlias,
                                        'from-el-cache': fromElCache, 'from-el-alias': fromElAlias }
                        signal.emit( str(action), unicode(descr), EMPTY_VALUE, parameters )
                
                elif self.actionsAndroidComboBox.currentText() == GuiSteps.ANDROID_GET_TEXT_ELEMENT:       
                    # read text from cache or not ?
                    cacheKey = ''
                    toCache = True
                    cacheKey = self.valueTextCacheGlobalLine.text()
                        
                    parameters = {'text': textAndroid, 'class': classAndroid, 'ressource': ressourceAndroid, 
                                    'package': packageAndroid, 'description': descrAndroid, 'cache-key': cacheKey,
                                    'to-cache': toCache, 'from-el-cache': fromElCache, 'from-el-alias': fromElAlias }
                    signal.emit( str(action), unicode(descr), EMPTY_VALUE, parameters )
                    
                elif self.actionsAndroidComboBox.currentText() == GuiSteps.ANDROID_DRAG_ELEMENT:       
                    xAndroid = self.endxAndroidLine.text()
                    yAndroid = self.endyAndroidLine.text()
                    if not len(xAndroid) and not len(yAndroid):
                        QMessageBox.warning(self, "Recording for Gui" , "Please to set values!")
                    else:
                        parameters = {'text': textAndroid, 'class': classAndroid, 'ressource': ressourceAndroid, 
                                    'package': packageAndroid, 'description': descrAndroid,
                                    'from-el-cache': fromElCache, 'from-el-alias': fromElAlias,
                                    'x': xAndroid, 'y': yAndroid }
                        signal.emit( str(action), unicode(descr), EMPTY_VALUE, parameters )
                    
                else:

                    parameters = {'text': textAndroid, 'class': classAndroid, 'ressource': ressourceAndroid, 
                                    'package': packageAndroid, 'description': descrAndroid,
                                    'from-el-cache': fromElCache, 'from-el-alias': fromElAlias }
                    signal.emit( str(action), unicode(descr), EMPTY_VALUE, parameters )
                    
        elif self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_CLICK_POSITION ]:
            xAndroid = self.xAndroidLine.text()
            yAndroid = self.yAndroidLine.text()
            if not len(xAndroid) and not len(yAndroid):
                QMessageBox.warning(self, "Recording for Gui" , "Please to set values!")
            else:
                parameters = { 'x': xAndroid, 'y': yAndroid }
                signal.emit( str(action), unicode(descr), EMPTY_VALUE, parameters )
                
        elif self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_DRAG_ELEMENT, GuiSteps.ANDROID_DRAG_POSITION, 
                                                            GuiSteps.ANDROID_SWIPE_POSITION]:
            startXAndroid = self.startXAndroidLine.text()
            startYAndroid = self.startYAndroidLine.text()
            stopXAndroid = self.stopXAndroidLine.text()
            stopYAndroid = self.stopYAndroidLine.text()
            if not len(startXAndroid) and not len(startYAndroid) and not len(stopXAndroid) and not len(stopYAndroid):
                QMessageBox.warning(self, "Recording for Gui" , "Please to set values!")
            else:
                parameters = { 'start-x': startXAndroid, 'start-y': startYAndroid, 'stop-x': stopXAndroid, 'stop-y': stopYAndroid }
                signal.emit( str(action), unicode(descr), EMPTY_VALUE, parameters )

        elif self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_COMMAND, GuiSteps.ANDROID_SHELL, GuiSteps.ANDROID_RESET_APP,
                                                            GuiSteps.ANDROID_STOP_APP]:
            miscStr = self.valueAndroidLine.text()
            if not len(miscStr):
                QMessageBox.warning(self, "Recording for Gui" , "Please to set a value!")
            else:
                if self.actionsAndroidComboBox.currentText() == GuiSteps.ANDROID_COMMAND:
                    parameters = { 'cmd': miscStr }
                elif self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_RESET_APP, GuiSteps.ANDROID_STOP_APP ]:
                    parameters = { 'pkg': miscStr }
                else:
                    parameters = { 'sh': miscStr }
                signal.emit( str(action), unicode(descr), EMPTY_VALUE, parameters )
                
        else:
            signal.emit( str(action), unicode(descr), EMPTY_VALUE, {} )
        
    def cancelStep(self):
        """
        Cancel step
        """
        self.addAndroidAction.setText( "&Add" )
        buttonFont = QFont()
        buttonFont.setBold(False)
        self.addAndroidAction.setFont(buttonFont)
        
        self.cancelAndroidAction.setEnabled(False)
        
        self.CancelEdit.emit()
    
    def finalizeUpdate(self):
        """
        Finalize the update of a step
        """
        self.addAndroidAction.setText( "&Add Action" )
        
        buttonFont = QFont()
        buttonFont.setBold(False)
        self.addAndroidAction.setFont(buttonFont)
        self.cancelAndroidAction.setEnabled(False)
        
    def onActionAndroidChanged(self):
        """
        On action changed
        """
        descr = 'No description available!'
        i = 0
        for el in GuiSteps.ACTION_ANDROID_DESCR:
            if isinstance(el, dict):
                if self.actionsAndroidComboBox.currentText() in el:
                    descr = GuiSteps.ACTION_ANDROID_DESCR[i][self.actionsAndroidComboBox.currentText()]
                    break
            i += 1
        self.labelActionAndroidDescr.setText( "%s\n" % descr )

            
        if self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_TYPE_SHORTCUT ]:
            self.shortcutAndroidGroup.show()   
            self.codeAndroidGroup.hide()  
            self.elemenAndroidGroup.hide()
            self.startAndroidGroup.hide()
            self.xyAndroidGroup.hide()
            self.lineAndroidGroup.hide()
            self.line2AndroidGroup.hide()
            self.textToGlobalGroup.hide()
            self.endXyAndroidGroup.hide()
            
            self.arrowLabel.show()
            self.arrowLabel2.show()
            
        elif self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_TYPE_KEYCODE ]:
            self.codeAndroidGroup.show()   
            self.shortcutAndroidGroup.hide()    
            self.elemenAndroidGroup.hide()
            self.startAndroidGroup.hide()
            self.xyAndroidGroup.hide()
            self.lineAndroidGroup.hide()
            self.line2AndroidGroup.hide()
            self.textToGlobalGroup.hide()
            self.endXyAndroidGroup.hide()
            
            self.arrowLabel.show()
            self.arrowLabel2.show()
            
        elif self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_CLEAR_ELEMENT, GuiSteps.ANDROID_CLICK_ELEMENT, GuiSteps.ANDROID_LONG_CLICK_ELEMENT,
                                                            GuiSteps.ANDROID_EXIST_ELEMENT, GuiSteps.ANDROID_WAIT_ELEMENT, GuiSteps.ANDROID_WAIT_CLICK_ELEMENT ]:
            self.shortcutAndroidGroup.hide()   
            self.codeAndroidGroup.hide()       
            self.elemenAndroidGroup.show()
            self.startAndroidGroup.hide()
            self.xyAndroidGroup.hide()
            self.lineAndroidGroup.hide()
            self.line2AndroidGroup.hide()
            self.textToGlobalGroup.hide()
            self.endXyAndroidGroup.hide()
            
            self.arrowLabel.show()
            self.arrowLabel2.show()
            
        elif self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_DRAG_ELEMENT ]:
            self.shortcutAndroidGroup.hide()   
            self.codeAndroidGroup.hide()       
            self.elemenAndroidGroup.show()
            self.startAndroidGroup.hide()
            self.xyAndroidGroup.hide()
            self.lineAndroidGroup.hide()
            self.line2AndroidGroup.hide()
            self.textToGlobalGroup.hide()
            self.endXyAndroidGroup.show()
            
            self.arrowLabel.show()
            self.arrowLabel2.show()
            
        elif self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_GET_TEXT_ELEMENT ]:
            self.shortcutAndroidGroup.hide()   
            self.codeAndroidGroup.hide()       
            self.elemenAndroidGroup.show()
            self.startAndroidGroup.hide()
            self.xyAndroidGroup.hide()
            self.lineAndroidGroup.hide()
            self.line2AndroidGroup.hide()
            self.textToGlobalGroup.show()
            self.endXyAndroidGroup.hide()
            
            self.arrowLabel.show()
            self.arrowLabel2.show()
            
        elif self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_CLICK_POSITION ]:
            self.shortcutAndroidGroup.hide()   
            self.codeAndroidGroup.hide()       
            self.elemenAndroidGroup.hide()
            self.startAndroidGroup.hide()
            self.xyAndroidGroup.show()
            self.lineAndroidGroup.hide()
            self.line2AndroidGroup.hide()
            self.textToGlobalGroup.hide()
            self.endXyAndroidGroup.hide()
            
            self.arrowLabel.show()
            self.arrowLabel2.show()
            
        elif self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_DRAG_POSITION, GuiSteps.ANDROID_SWIPE_POSITION ]:
            self.shortcutAndroidGroup.hide()   
            self.codeAndroidGroup.hide()       
            self.elemenAndroidGroup.hide()
            self.startAndroidGroup.show()
            self.xyAndroidGroup.hide()
            self.lineAndroidGroup.hide()
            self.line2AndroidGroup.hide()
            self.textToGlobalGroup.hide()
            self.endXyAndroidGroup.hide()
            
            self.arrowLabel.show()
            self.arrowLabel2.show()
            
        elif self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_COMMAND, GuiSteps.ANDROID_SHELL, GuiSteps.ANDROID_RESET_APP, 
                                                            GuiSteps.ANDROID_STOP_APP  ]:
            self.shortcutAndroidGroup.hide()   
            self.codeAndroidGroup.hide()       
            self.elemenAndroidGroup.hide()
            self.startAndroidGroup.hide()
            self.xyAndroidGroup.hide()
            self.lineAndroidGroup.show()
            self.line2AndroidGroup.hide()
            self.textToGlobalGroup.hide()
            self.endXyAndroidGroup.hide()
             
            self.arrowLabel.show()
            self.arrowLabel2.show()
            
        elif self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_TYPE_TEXT_ELEMENT ]:
            self.shortcutAndroidGroup.hide()   
            self.codeAndroidGroup.hide()       
            self.elemenAndroidGroup.show()
            self.startAndroidGroup.hide()
            self.xyAndroidGroup.hide()
            self.lineAndroidGroup.hide()
            self.line2AndroidGroup.show()
            self.textToGlobalGroup.hide()
            self.endXyAndroidGroup.hide()
            
            self.arrowLabel.show()
            self.arrowLabel2.show()
            
        else:
            self.shortcutAndroidGroup.hide()   
            self.codeAndroidGroup.hide()       
            self.elemenAndroidGroup.hide()
            self.startAndroidGroup.hide()
            self.xyAndroidGroup.hide()
            self.lineAndroidGroup.hide()
            self.line2AndroidGroup.hide()
            self.textToGlobalGroup.hide()
            self.endXyAndroidGroup.hide()
            
            self.arrowLabel.hide()
            self.arrowLabel2.show()
            
    def setTimeout(self, timeout):
        """
        Set the timeout
        """
        self.optionsDialog.timeoutAndroidLine.setText(timeout)
        
    def getTimeout(self):
        """
        Return the timeout
        """
        return self.optionsDialog.timeoutAndroidLine.text()
        
    def getAgentName(self):
        """
        Get the agent name
        """
        return self.optionsDialog.agentNameLineAndroid.text()
        
    def getAgentList(self):
        """
        Return the agent list
        """
        return self.optionsDialog.agentsAndroidList
     
    def editStep(self, stepData):
        """
        Edit a step
        """
        self.addAndroidAction.setText( "&Update" )
        buttonFont = QFont()
        buttonFont.setBold(True)
        self.addAndroidAction.setFont(buttonFont)
        
        self.cancelAndroidAction.setEnabled(True)
            
        # set the current value for actions combo
        for i in xrange(self.actionsAndroidComboBox.count()):
            item_text = self.actionsAndroidComboBox.itemText(i)
            if unicode(stepData["action"]) == unicode(item_text):
                self.actionsAndroidComboBox.setCurrentIndex(i)
                break
        # and then refresh options
        self.onActionAndroidChanged()
        
        # finally fill all fields
        self.descriptionAndroidLine.setText( stepData["description"] )

        if self.actionsAndroidComboBox.currentText() == GuiSteps.ANDROID_COMMAND:
            self.valueAndroidLine.setText( stepData["parameters"]["cmd"] )
            
        if self.actionsAndroidComboBox.currentText() == GuiSteps.ANDROID_SHELL:
            self.valueAndroidLine.setText( stepData["parameters"]["sh"] )
            
        if self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_RESET_APP, GuiSteps.ANDROID_STOP_APP ]:
            self.valueAndroidLine.setText( stepData["parameters"]["pkg"] )
            
        if self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_CLEAR_ELEMENT, GuiSteps.ANDROID_TYPE_TEXT_ELEMENT, 
                                                          GuiSteps.ANDROID_CLICK_ELEMENT, GuiSteps.ANDROID_LONG_CLICK_ELEMENT,
                                                          GuiSteps.ANDROID_EXIST_ELEMENT, GuiSteps.ANDROID_WAIT_ELEMENT,
                                                          GuiSteps.ANDROID_GET_TEXT_ELEMENT, GuiSteps.ANDROID_DRAG_ELEMENT,
                                                          GuiSteps.ANDROID_WAIT_CLICK_ELEMENT ]:
                                                          
            self.elementTextAndroidLine.setText( "" )
            self.elementDescriptionAndroidLine.setText( "" )
            self.elementClassAndroidLine.setText( "" )
            self.elementRessourceIdAndroidLine.setText( "" )
            self.elementPackageAndroidLine.setText( "" )
            self.valueAndroidLine2.setText( "" )
            
            if "text" in stepData["parameters"]:
                if stepData["parameters"]["from-el-cache"]:
                    self.elementTextCombo.setCurrentIndex(INDEX_CACHE)
                    self.elementTextAndroidLine.setValidator(self.validatorAll)
                elif stepData["parameters"]["from-el-alias"]:
                    self.elementTextCombo.setCurrentIndex(INDEX_ALIAS)
                    self.elementTextAndroidLine.setValidator(self.validatorUpper) 
                else:
                    self.elementTextCombo.setCurrentIndex(INDEX_TEXT)
                    self.elementTextAndroidLine.setValidator(self.validatorAll)
                
                self.elementTextAndroidLine.setText ( stepData["parameters"]["text"] )

            if "description" in stepData["parameters"]:
                self.elementDescriptionAndroidLine.setText( stepData["parameters"]["description"] )
            if "class" in stepData["parameters"]:
                self.elementClassAndroidLine.setText( stepData["parameters"]["class"] )
            if "ressource" in stepData["parameters"]:
                self.elementRessourceIdAndroidLine.setText( stepData["parameters"]["ressource"] )
            if "package" in stepData["parameters"]:
                self.elementPackageAndroidLine.setText( stepData["parameters"]["package"] )
            if "new-text" in stepData["parameters"]:
                self.valueAndroidLine2.setText( stepData["parameters"]["new-text"] )

            if self.actionsAndroidComboBox.currentText() == GuiSteps.ANDROID_DRAG_ELEMENT:
                if "x" in stepData["parameters"]:
                    self.endxAndroidLine.setText( stepData["parameters"]["x"] )
                if "y" in stepData["parameters"]:
                    self.endyAndroidLine.setText( stepData["parameters"]["y"] )
                
            if self.actionsAndroidComboBox.currentText() == GuiSteps.ANDROID_TYPE_TEXT_ELEMENT:
                if stepData["parameters"]["from-cache"]:
                    self.valueAndroidCombo2.setCurrentIndex(INDEX_CACHE)
                    self.valueAndroidLine2.setValidator(self.validatorAll)
                elif stepData["parameters"]["from-alias"]:
                    self.valueAndroidCombo2.setCurrentIndex(INDEX_ALIAS)
                    self.valueAndroidLine2.setValidator(self.validatorUpper) 
                else:
                    self.valueAndroidCombo2.setCurrentIndex(INDEX_TEXT)
                    self.valueAndroidLine2.setValidator(self.validatorAll)
                
            if self.actionsAndroidComboBox.currentText() == GuiSteps.ANDROID_GET_TEXT_ELEMENT:
                self.valueTextCacheGlobalLine.setText ( stepData["parameters"]["cache-key"] )

        if self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_CLICK_POSITION]:
            if "x" in stepData["parameters"]:
                self.xAndroidLine.setText( stepData["parameters"]["x"] )
            if "y" in stepData["parameters"]:
                self.yAndroidLine.setText( stepData["parameters"]["y"] )
                
        if self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_DRAG_POSITION, GuiSteps.ANDROID_SWIPE_POSITION]:
            if "start-x" in stepData["parameters"]:
                self.startXAndroidLine.setText( stepData["parameters"]["start-x"] )
            if "start-y" in stepData["parameters"]:
                self.startYAndroidLine.setText( stepData["parameters"]["start-y"] )
            if "stop-x" in stepData["parameters"]:
                self.stopXAndroidLine.setText( stepData["parameters"]["stop-x"] )
            if "stop-y" in stepData["parameters"]:
                self.stopYAndroidLine.setText( stepData["parameters"]["stop-y"] )

        if self.actionsAndroidComboBox.currentText() == GuiSteps.ANDROID_TYPE_KEYCODE:
            self.codeAndroidLine.setText( stepData["misc"] )
            
        if self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_TYPE_SHORTCUT ]:
            # set default
            for i in xrange(self.shortcutAndroidComboBox.count()):
                item_text = self.shortcutAndroidComboBox.itemText(i)
                if unicode(stepData["misc"]) == unicode(item_text):
                    self.shortcutAndroidComboBox.setCurrentIndex(i)
                    break
Beispiel #57
0
class PymetricsViewer(QWidget):
    " Pymetrics tab widget "

    # Limits to colorize the McCabe score
    LittleRiskLimit = 10
    ModerateRiskLimit = 20
    HighRiskLimit = 50

    # Options of providing a report
    SingleFile = 0
    DirectoryFiles = 1
    ProjectFiles = 2
    SingleBuffer = 3

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

        self.__reportUUID = ""
        self.__reportFileName = ""
        self.__reportOption = -1
        self.__reportShown = False
        self.__report = None

        # Prepare members for reuse
        self.__noneLabel = QLabel("\nNo results available")

        self.__noneLabel.setFrameShape(QFrame.StyledPanel)
        self.__noneLabel.setAlignment(Qt.AlignHCenter)
        self.__headerFont = self.__noneLabel.font()
        self.__headerFont.setPointSize(self.__headerFont.pointSize() + 4)
        self.__noneLabel.setFont(self.__headerFont)
        self.__noneLabel.setAutoFillBackground(True)
        noneLabelPalette = self.__noneLabel.palette()
        noneLabelPalette.setColor(QPalette.Background,
                                  GlobalData().skin.nolexerPaper)
        self.__noneLabel.setPalette(noneLabelPalette)

        self.__createLayout(parent)

        self.__updateButtonsStatus()
        return

    def __createLayout(self, parent):
        " Creates the toolbar and layout "

        # Buttons
        self.__mcCabeButton = QAction(PixmapCache().getIcon('tableview.png'),
                                      'Switch to McCabe only table view', self)
        self.__mcCabeButton.setCheckable(True)
        self.connect(self.__mcCabeButton, SIGNAL('toggled(bool)'),
                     self.__onMcCabe)

        self.printButton = QAction(PixmapCache().getIcon('printer.png'),
                                   'Print', self)
        #printButton.setShortcut( 'Ctrl+' )
        self.connect(self.printButton, SIGNAL('triggered()'), self.__onPrint)
        self.printButton.setVisible(False)

        self.printPreviewButton = QAction(
            PixmapCache().getIcon('printpreview.png'), 'Print preview', self)
        #printPreviewButton.setShortcut( 'Ctrl+' )
        self.connect(self.printPreviewButton, SIGNAL('triggered()'),
                     self.__onPrintPreview)
        self.printPreviewButton.setVisible(False)

        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        self.clearButton = QAction(PixmapCache().getIcon('trash.png'), 'Clear',
                                   self)
        self.connect(self.clearButton, SIGNAL('triggered()'), self.__clear)

        # The toolbar
        self.toolbar = QToolBar(self)
        self.toolbar.setOrientation(Qt.Vertical)
        self.toolbar.setMovable(False)
        self.toolbar.setAllowedAreas(Qt.RightToolBarArea)
        self.toolbar.setIconSize(QSize(16, 16))
        self.toolbar.setFixedWidth(28)
        self.toolbar.setContentsMargins(0, 0, 0, 0)

        self.toolbar.addAction(self.__mcCabeButton)
        self.toolbar.addAction(self.printPreviewButton)
        self.toolbar.addAction(self.printButton)
        self.toolbar.addWidget(spacer)
        self.toolbar.addAction(self.clearButton)

        self.__totalResultsTree = QTreeWidget()
        self.__totalResultsTree.setAlternatingRowColors(True)
        self.__totalResultsTree.setRootIsDecorated(True)
        self.__totalResultsTree.setItemsExpandable(True)
        self.__totalResultsTree.setUniformRowHeights(True)
        self.__totalResultsTree.setItemDelegate(NoOutlineHeightDelegate(4))
        headerLabels = ["Path / name", "Value", ""]
        self.__totalResultsTree.setHeaderLabels(headerLabels)
        self.connect(self.__totalResultsTree,
                     SIGNAL("itemActivated(QTreeWidgetItem *, int)"),
                     self.__allItemActivated)
        self.connect(self.__totalResultsTree,
                     SIGNAL("itemExpanded(QTreeWidgetItem *)"),
                     self.__onResultsExpanded)
        self.__totalResultsTree.setColumnHidden(2, True)
        self.__totalResultsTree.hide()

        self.__mcCabeTable = QTreeWidget()
        self.__mcCabeTable.setAlternatingRowColors(True)
        self.__mcCabeTable.setRootIsDecorated(False)
        self.__mcCabeTable.setItemsExpandable(False)
        self.__mcCabeTable.setSortingEnabled(True)
        self.__mcCabeTable.setItemDelegate(NoOutlineHeightDelegate(4))
        self.__mcCabeTable.setUniformRowHeights(True)
        headerLabels = ["", "File name", "Object", "McCabe Complexity"]
        self.__mcCabeTable.setHeaderLabels(headerLabels)
        self.connect(self.__mcCabeTable,
                     SIGNAL("itemActivated(QTreeWidgetItem *, int)"),
                     self.__mcCabeActivated)
        self.__mcCabeTable.hide()

        self.__hLayout = QHBoxLayout()
        self.__hLayout.setContentsMargins(0, 0, 0, 0)
        self.__hLayout.setSpacing(0)
        self.__hLayout.addWidget(self.toolbar)
        self.__hLayout.addWidget(self.__noneLabel)
        self.__hLayout.addWidget(self.__totalResultsTree)
        self.__hLayout.addWidget(self.__mcCabeTable)

        self.setLayout(self.__hLayout)
        return

    def getTotalResultsWidget(self):
        " Provides a reference to the total results widget "
        return self.__totalResultsTree

    def getMcCabeResultsWidget(self):
        " Provides a reference to the McCabe results widget "
        return self.__mcCabeTable

    def __updateButtonsStatus(self):
        " Updates the buttons status "
        self.__mcCabeButton.setEnabled(self.__reportShown)
        self.printButton.setEnabled(self.__reportShown)
        self.printPreviewButton.setEnabled(self.__reportShown)
        self.clearButton.setEnabled(self.__reportShown)
        return

    def __onResultsExpanded(self, item):
        " An item has been expanded, so the column width should be adjusted "
        self.__totalResultsTree.header().resizeSections(
            QHeaderView.ResizeToContents)
        return

    def __onPrint(self):
        " Triggered when the print button is pressed "
        pass

    def __onPrintPreview(self):
        " triggered when the print preview button is pressed "
        pass

    def __onMcCabe(self, state):
        " Triggered when the metrics view is switched "

        if not self.__reportShown:
            return

        if state:
            self.__totalResultsTree.hide()
            self.__mcCabeTable.show()
            self.__mcCabeButton.setIcon(PixmapCache().getIcon('treeview.png'))
            self.__mcCabeButton.setToolTip("Switch to complete "
                                           "results tree view")
        else:
            self.__mcCabeTable.hide()
            self.__totalResultsTree.show()
            self.__mcCabeButton.setIcon(PixmapCache().getIcon('tableview.png'))
            self.__mcCabeButton.setToolTip("Switch to McCabe only table view")
        return

    def setFocus(self):
        " Overridden setFocus "
        self.__hLayout.setFocus()
        return

    def __clear(self):
        " Clears the content of the vertical layout "
        if not self.__reportShown:
            return

        self.__totalResultsTree.clear()
        self.__totalResultsTree.hide()
        self.__mcCabeTable.clear()
        self.__mcCabeTable.hide()
        self.__noneLabel.show()

        self.__report = None
        self.__reportShown = False
        self.__updateButtonsStatus()
        #        self.resizeEvent()
        self.__mcCabeButton.setIcon(PixmapCache().getIcon('tableview.png'))
        self.__mcCabeButton.setToolTip("Switch to McCabe only table view")
        self.__mcCabeButton.setChecked(False)

        self.__updateTooltip()
        return

    def __updateTooltip(self):
        " Generates a signal with appropriate string message "
        if not self.__reportShown:
            tooltip = "No metrics available"
        elif self.__reportOption == self.DirectoryFiles:
            tooltip = "Metrics generated for directory: " + \
                      self.__reportFileName
        elif self.__reportOption == self.ProjectFiles:
            tooltip = "Metrics generated for the whole project"
        elif self.__reportOption == self.SingleFile:
            tooltip = "Metrics generated for file: " + self.__reportFileName
        elif self.__reportOption == self.SingleBuffer:
            tooltip = "Metrics generated for unsaved file: " + \
                      self.__reportFileName
        else:
            tooltip = ""
        self.emit(SIGNAL('updatePymetricsTooltip'), tooltip)
        return

    @staticmethod
    def __shouldShowFileName(table, column):
        " Checks if the file name is the same "

        size = table.topLevelItemCount()
        if size == 0:
            return False

        index = size - 1
        firstName = table.topLevelItem(index).text(column)
        index -= 1
        while index >= 0:
            if table.topLevelItem(index).text(column) != firstName:
                return True
            index -= 1
        return False

    def showReport(self, metrics, reportOption, fileName, uuid):
        " Shows the pymetrics results "
        self.__clear()
        self.__noneLabel.hide()

        self.__report = metrics
        self.__reportUUID = uuid
        self.__reportFileName = fileName
        self.__reportOption = reportOption

        if len(metrics.report) > 1:
            accumulatedBasic = self.__accumulateBasicMetrics()
            accItem = QTreeWidgetItem(["Cumulative basic metrics"])
            self.__totalResultsTree.addTopLevelItem(accItem)
            for key in accumulatedBasic:
                bmItem = [
                    BasicMetrics.metricsOfInterest[key],
                    splitThousands(str(accumulatedBasic[key]))
                ]
                basicMetric = QTreeWidgetItem(bmItem)
                accItem.addChild(basicMetric)

        # Add the complete information
        for fileName in metrics.report:
            if reportOption == self.SingleBuffer:
                fileItem = QTreeWidgetItem(["Editor buffer"])
            else:
                fileItem = QTreeWidgetItem([fileName])
                info = GlobalData().briefModinfoCache.get(fileName)
                if info.docstring is not None:
                    fileItem.setToolTip(0, info.docstring.text)
                else:
                    fileItem.setToolTip(0, "")
            self.__totalResultsTree.addTopLevelItem(fileItem)

            # Messages part
            messages = metrics.report[fileName].messages
            if len(messages) > 0:
                messagesItem = QTreeWidgetItem(["Messages"])
                fileItem.addChild(messagesItem)
                for message in messages:
                    mItem = [message, "", "E"]
                    messagesItem.addChild(QTreeWidgetItem(mItem))

            # Basic metrics part
            basicItem = QTreeWidgetItem(["Basic metrics"])
            fileItem.addChild(basicItem)
            basic = metrics.report[fileName].basicMetrics
            for key in basic.metrics:
                bmItem = [
                    BasicMetrics.metricsOfInterest[key],
                    str(basic.metrics[key])
                ]
                basicMetric = QTreeWidgetItem(bmItem)
                basicItem.addChild(basicMetric)

            # McCabe part
            mccabeItem = QTreeWidgetItem(["McCabe metrics"])
            fileItem.addChild(mccabeItem)
            mccabe = metrics.report[fileName].mcCabeMetrics.metrics
            for objName in mccabe:
                objItem = [objName, str(mccabe[objName]), "M"]
                mccabeMetric = QTreeWidgetItem(objItem)
                mccabeItem.addChild(mccabeMetric)

            # COCOMO 2 part
            cocomo = [
                "COCOMO 2",
                str(metrics.report[fileName].cocomo2Metrics.value)
            ]
            cocomoItem = QTreeWidgetItem(cocomo)
            fileItem.addChild(cocomoItem)

        # Resizing the table
        self.__totalResultsTree.header().resizeSections(
            QHeaderView.ResizeToContents)

        # Add McCabe complexity information
        for fileName in metrics.report:
            mccabe = metrics.report[fileName].mcCabeMetrics.metrics
            for objName in mccabe:
                values = ["", fileName, objName, str(mccabe[objName])]
                self.__mcCabeTable.addTopLevelItem(McCabeTableItem(values))

        if not self.__shouldShowFileName(self.__mcCabeTable, 1):
            self.__mcCabeTable.setColumnHidden(1, True)

        # Resizing and sorting the table
        self.__mcCabeTable.header().setSortIndicator(3, Qt.DescendingOrder)
        self.__mcCabeTable.sortItems(
            3,
            self.__mcCabeTable.header().sortIndicatorOrder())
        self.__mcCabeTable.header().resizeSections(
            QHeaderView.ResizeToContents)

        # Show the complete information
        self.__mcCabeTable.hide()
        self.__totalResultsTree.show()

        self.__reportShown = True
        self.__updateButtonsStatus()
        self.__updateTooltip()

        # It helps, but why do I have flickering?
        QApplication.processEvents()
        return

    def __accumulateBasicMetrics(self):
        " Accumulates basic metrics for all the processed files "
        basic = {}
        for fileName in self.__report.report:
            singleBasic = self.__report.report[fileName].basicMetrics.metrics
            for key in singleBasic:
                if not key.startswith('num'):
                    continue
                if key in basic:
                    basic[key] += int(singleBasic[key])
                else:
                    basic[key] = int(singleBasic[key])
        return basic

    def __mcCabeActivated(self, item, column):
        " Handles the double click (or Enter) on the mccabe table item "

        objName = str(item.text(2))
        if self.__reportOption == self.SingleBuffer:
            if os.path.isabs(self.__reportFileName):
                fileName = self.__reportFileName
            else:
                fileName = ""
        else:
            fileName = str(item.text(1))
        self.__onMcCabeObject(objName, fileName)
        return

    def __allItemActivated(self, item, column):
        " Handles the double click (or Enter) in the total results tree "

        # We process only the error messages and McCabe items
        hiddenColumnText = str(item.text(2))
        if not hiddenColumnText in ["M", "E"]:
            return

        fileName = self.__getTreeItemFileName(item)
        lineNumber = 0
        if hiddenColumnText == "M":
            # This is McCabe item
            objName = str(item.text(0))
            self.__onMcCabeObject(objName, fileName)
            return
        elif hiddenColumnText == "E":
            # This is an error message
            message = str(item.text(0))
            pos = message.find("at line")
            if pos == -1:
                logging.error("Unknown format of the message. "
                              "Please inform the developers.")
                return
            parts = message[pos:].split()
            try:
                lineNumber = int(parts[2].replace(',', ''))
            except:
                logging.error("Unknown format of the message. "
                              "Please inform the developers.")
                return

            if fileName == "":
                # This is an unsaved buffer, try to find the editor by UUID
                mainWindow = GlobalData().mainWindow
                widget = mainWindow.getWidgetByUUID(self.__reportUUID)
                if widget is None:
                    logging.error("The unsaved buffer has been closed")
                    return
                # The widget was found, so jump to the required
                editor = widget.getEditor()
                editor.gotoLine(lineNumber)
                editor.setFocus()
                return

        GlobalData().mainWindow.openFile(fileName, lineNumber)
        return

    def __getTreeItemFileName(self, item):
        " Identifies the tree view item file name "
        if self.__reportOption == self.SingleBuffer:
            if os.path.isabs(self.__reportFileName):
                return self.__reportFileName
            return ""

        # The file name is always two levels up
        fileItem = item.parent().parent()
        return str(fileItem.text(0))

    def __onMcCabeObject(self, objName, fileName):
        " Called when the user activated McCabe item "

        info = None

        mainWindow = GlobalData().mainWindow
        widget = mainWindow.getWidgetByUUID(self.__reportUUID)
        if widget is None:
            if fileName == "":
                logging.error("The unsaved buffer has been closed")
                return
            # No widget, but we know the file name
            info = getBriefModuleInfoFromFile(fileName)
        else:
            # The widget was found
            editor = widget.getEditor()
            # The editor content has been modified, so re-parse the buffer
            info = getBriefModuleInfoFromMemory(editor.text())

        parts = objName.split('.')
        currentIndex = 0
        functionsContainer = info.functions
        classesContainer = info.classes
        line = -1

        if objName == "__main__" and len(parts) == 1:
            # Special case - global file scope
            line = 1
            currentIndex = 1

        while currentIndex < len(parts):
            found = False
            for func in functionsContainer:
                if func.name == parts[currentIndex]:
                    if currentIndex == len(parts) - 1:
                        # Found, jump to the line
                        line = func.line
                        break
                    functionsContainer = func.functions
                    classesContainer = func.classes
                    found = True
                    break
            if line != -1:
                break
            if found:
                currentIndex += 1
                continue
            for klass in classesContainer:
                if klass.name == parts[currentIndex]:
                    if currentIndex == len(parts) - 1:
                        # Found, jump to the line
                        line = klass.line
                        break
                    functionsContainer = klass.functions
                    classesContainer = klass.classes
                    found = True
            if line != -1:
                break
            if found:
                currentIndex += 1
                continue

            # Not found
            logging.error("Cannot find the " + objName)
            return

        # Here we have the line number
        if widget is None:
            GlobalData().mainWindow.openFile(fileName, line)
        else:
            editor = widget.getEditor()
            editor.gotoLine(line)
            editor.setFocus()
        return

    def onFileUpdated(self, fileName, uuid):
        " Called when a buffer is saved or saved as "

        if not self.__reportShown:
            return
        if self.__reportUUID != uuid:
            return

        # Currently shown report is for the saved buffer
        # File name is expected being absolute
        self.__reportFileName = fileName
        self.emit(SIGNAL('updatePymetricsTooltip'),
                  "Metrics generated for buffer saved as " + fileName)
        return
Beispiel #58
0
class ActionBar(QFrame):
    """
    SIGNALS:
    @changeCurrent(PyQt_PyObject)
    @runFile(QString)
    @reopenTab(QString)
    @recentTabsModified()
    """

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        menu.exec_(QCursor.pos())

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    def _close_all_files_except_this(self):
        """Close all the files except the current one."""
        neditable = self.combo.itemData(self.combo.currentIndex())
        for i in reversed(list(range(self.combo.count()))):
            ne = self.combo.itemData(i)
            if ne is not neditable:
                self.about_to_close_file(i)
Beispiel #59
0
 def create_rows(self, layout):
     u"""Build one row of the dialog box"""
     play_button_group = QButtonGroup(self)
     old_play_button_group = QButtonGroup(self)
     for num, (source, dest, text, dl_fname, dl_hash, extras, icon)\
             in enumerate(self.list, 3):
         tt_text = self.build_text_help_label(text, source, extras)
         ico_label = QLabel('', self)
         ico_label.setToolTip(tt_text)
         if icon:
             ico_label.setPixmap(QPixmap.fromImage(icon))
         layout.addWidget(ico_label, num, 0)
         tt_label = QLabel(text, self)
         tt_label.setToolTip(tt_text)
         layout.addWidget(tt_label, num, 1)
         if self.hide_text:
             tt_label.hide()
         # Play button.
         t_play_button = QPushButton(self)
         play_button_group.addButton(t_play_button, num - 3)
         t_play_button.setToolTip(self.play_help)
         t_play_button.setIcon(QIcon(os.path.join(icons_dir, 'play.png')))
         layout.addWidget(t_play_button, num, self.play_column)
         if self.note[dest]:
             t_play_old_button = QPushButton(self)
             old_play_button_group.addButton(t_play_old_button, num - 3)
             t_play_old_button.setIcon(
                 QIcon(os.path.join(icons_dir, 'play.png')))
             if not self.hide_text:
                 t_play_old_button.setToolTip(self.note[dest])
             else:
                 t_play_old_button.setToolTip(self.play_old_help_short)
             layout.addWidget(t_play_old_button, num, self.play_old_column)
         else:
             dummy_label = QLabel('', self)
             dummy_label.setToolTip(self.play_old_empty_line_help)
             layout.addWidget(dummy_label, num, self.play_old_column)
         # The group where we later look what to do:
         t_button_group = QButtonGroup(self)
         t_button_group.setExclusive(True)
         # Now the four buttons
         t_add_button = QPushButton(self)
         t_add_button.setCheckable(True)
         t_add_button.setChecked(True)
         t_add_button.setFlat(True)
         t_add_button.setToolTip(self.add_help_text_short)
         t_add_button.setIcon(QIcon(os.path.join(icons_dir, 'add.png')))
         layout.addWidget(t_add_button, num, self.add_column)
         t_button_group.addButton(t_add_button, action['add'])
         t_keep_button = QPushButton(self)
         t_keep_button.setCheckable(True)
         t_keep_button.setFlat(True)
         t_keep_button.setToolTip(self.keep_help_text_short)
         t_keep_button.setIcon(QIcon(os.path.join(icons_dir, 'keep.png')))
         layout.addWidget(t_keep_button, num, self.keep_column)
         t_button_group.addButton(t_keep_button, action['keep'])
         t_delete_button = QPushButton(self)
         t_delete_button.setCheckable(True)
         t_delete_button.setFlat(True)
         t_delete_button.setToolTip(self.delete_help_text_short)
         t_delete_button.setIcon(
             QIcon(os.path.join(icons_dir, 'delete.png')))
         layout.addWidget(t_delete_button, num, self.delete_column)
         t_button_group.addButton(t_delete_button, action['delete'])
         t_blacklist_button = QPushButton(self)
         t_blacklist_button.setCheckable(True)
         t_blacklist_button.setFlat(True)
         t_blacklist_button.setToolTip(self.blacklist_help_text_short)
         t_blacklist_button.setIcon(
             QIcon(os.path.join(icons_dir, 'blacklist.png')))
         if self.show_skull_and_bones:
             layout.addWidget(t_blacklist_button, num,
                              self.blacklist_column)
         else:
             t_blacklist_button.hide()
         t_button_group.addButton(t_blacklist_button, action['blacklist'])
         self.buttons_groups.append(t_button_group)
     play_button_group.buttonClicked.connect(
         lambda button: play(self.list[play_button_group.id(button)][3]))
     old_play_button_group.buttonClicked.connect(
         lambda button: playFromText(self.note[self.list[
             old_play_button_group.id(button)][1]]))