示例#1
0
class UpdateDialog(QDialog):
    """The dialog for update."""
    def __init__(self):
        super(UpdateDialog, self).__init__()
        vbox = QVBoxLayout(self)
        self.closed = False
        self.setModal(True)
        self.resize(500, 250)

        vbox.addWidget(QLabel(u"Actualización de la lista de episodios:"))
        self.text = QPlainTextEdit()
        self.text.setReadOnly(True)
        vbox.addWidget(self.text)

        bbox = QDialogButtonBox(QDialogButtonBox.Cancel)
        bbox.rejected.connect(self.reject)
        vbox.addWidget(bbox)

    def append(self, text):
        """Append some text in the dialog."""
        self.text.appendPlainText(text.strip())

    def closeEvent(self, event):
        """It was closed."""
        self.closed = True
示例#2
0
class DependenciesHelpDialog(QDialog):
    def __init__(self, requirements_dict):
        super(DependenciesHelpDialog, self).__init__()
        self.setWindowTitle(self.tr("Plugin requirements"))
        self.resize(525, 400)
        vbox = QVBoxLayout(self)
        label = QLabel(
            self.tr("""It seems that some plugins needs some
            dependencies to be solved to work properly, you should install them
            as follows using a Terminal"""))
        vbox.addWidget(label)
        self._editor = QPlainTextEdit()
        self._editor.setReadOnly(True)
        vbox.addWidget(self._editor)
        hbox = QHBoxLayout()
        btnAccept = QPushButton(self.tr("Accept"))
        btnAccept.setMaximumWidth(100)
        hbox.addWidget(btnAccept)
        vbox.addLayout(hbox)
        #signals
        self.connect(btnAccept, SIGNAL("clicked()"), self.close)

        command_tmpl = "<%s>:\n%s\n"
        for name, description in list(requirements_dict.items()):
            self._editor.insertPlainText(command_tmpl % (name, description))
示例#3
0
class UpdateDialog(QDialog):
    """The dialog for update."""
    def __init__(self):
        super(UpdateDialog, self).__init__()
        vbox = QVBoxLayout(self)
        self.closed = False
        self.setModal(True)
        self.resize(500, 250)

        vbox.addWidget(QLabel(u"Actualización de la lista de episodios:"))
        self.text = QPlainTextEdit()
        self.text.setReadOnly(True)
        vbox.addWidget(self.text)

        bbox = QDialogButtonBox(QDialogButtonBox.Cancel)
        bbox.rejected.connect(self.reject)
        vbox.addWidget(bbox)

    def append(self, text):
        """Append some text in the dialog."""
        self.text.appendPlainText(text.strip())

    def closeEvent(self, event):
        """It was closed."""
        self.closed = True
示例#4
0
class ErrorReportDialog(QDialog):
    def __init__(self, parent, github_url, error):
        flags = Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowSystemMenuHint
        QDialog.__init__(self, parent, flags)
        self._setupUi()
        name = QCoreApplication.applicationName()
        version = QCoreApplication.applicationVersion()
        errorText = "Application Name: {0}\nVersion: {1}\n\n{2}".format(
            name, version, error)
        # Under windows, we end up with an error report without linesep if we don't mangle it
        errorText = errorText.replace('\n', os.linesep)
        self.errorTextEdit.setPlainText(errorText)
        self.github_url = github_url

        self.sendButton.clicked.connect(self.goToGithub)
        self.dontSendButton.clicked.connect(self.reject)

    def _setupUi(self):
        self.setWindowTitle(tr("Error Report"))
        self.resize(553, 349)
        self.verticalLayout = QVBoxLayout(self)
        self.label = QLabel(self)
        self.label.setText(
            tr("Something went wrong. How about reporting the error?"))
        self.label.setWordWrap(True)
        self.verticalLayout.addWidget(self.label)
        self.errorTextEdit = QPlainTextEdit(self)
        self.errorTextEdit.setReadOnly(True)
        self.verticalLayout.addWidget(self.errorTextEdit)
        msg = tr(
            "Error reports should be reported as Github issues. You can copy the error traceback "
            "above and paste it in a new issue (bonus point if you run a search to make sure the "
            "issue doesn't already exist). What usually really helps is if you add a description "
            "of how you got the error. Thanks!"
            "\n\n"
            "Although the application should continue to run after this error, it may be in an "
            "unstable state, so it is recommended that you restart the application."
        )
        self.label2 = QLabel(msg)
        self.label2.setWordWrap(True)
        self.verticalLayout.addWidget(self.label2)
        self.horizontalLayout = QHBoxLayout()
        self.horizontalLayout.addItem(horizontalSpacer())
        self.dontSendButton = QPushButton(self)
        self.dontSendButton.setText(tr("Close"))
        self.dontSendButton.setMinimumSize(QSize(110, 0))
        self.horizontalLayout.addWidget(self.dontSendButton)
        self.sendButton = QPushButton(self)
        self.sendButton.setText(tr("Go to Github"))
        self.sendButton.setMinimumSize(QSize(110, 0))
        self.sendButton.setDefault(True)
        self.horizontalLayout.addWidget(self.sendButton)
        self.verticalLayout.addLayout(self.horizontalLayout)

    def goToGithub(self):
        open_url(self.github_url)
示例#5
0
class ErrorReportDialog(QDialog):
    def __init__(self, parent, error):
        flags = Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowSystemMenuHint
        QDialog.__init__(self, parent, flags)
        self._setupUi()
        name = QCoreApplication.applicationName()
        version = QCoreApplication.applicationVersion()
        errorText = "Application Name: {0}\nVersion: {1}\n\n{2}".format(
            name, version, error)
        # Under windows, we end up with an error report without linesep if we don't mangle it
        errorText = errorText.replace('\n', os.linesep)
        self.errorTextEdit.setPlainText(errorText)

        self.sendButton.clicked.connect(self.accept)
        self.dontSendButton.clicked.connect(self.reject)

    def _setupUi(self):
        self.setWindowTitle(tr("Error Report"))
        self.resize(553, 349)
        self.verticalLayout = QVBoxLayout(self)
        self.label = QLabel(self)
        self.label.setText(
            tr("Something went wrong. Would you like to send the error report to Hardcoded Software?"
               ))
        self.label.setWordWrap(True)
        self.verticalLayout.addWidget(self.label)
        self.errorTextEdit = QPlainTextEdit(self)
        self.errorTextEdit.setReadOnly(True)
        self.verticalLayout.addWidget(self.errorTextEdit)
        msg = tr(
            "Although the application should continue to run after this error, it may be in an "
            "instable state, so it is recommended that you restart the application."
        )
        self.label2 = QLabel(msg)
        self.label2.setWordWrap(True)
        self.verticalLayout.addWidget(self.label2)
        self.horizontalLayout = QHBoxLayout()
        self.horizontalLayout.addItem(horizontalSpacer())
        self.dontSendButton = QPushButton(self)
        self.dontSendButton.setText(tr("Don\'t Send"))
        self.dontSendButton.setMinimumSize(QSize(110, 0))
        self.horizontalLayout.addWidget(self.dontSendButton)
        self.sendButton = QPushButton(self)
        self.sendButton.setText(tr("Send"))
        self.sendButton.setMinimumSize(QSize(110, 0))
        self.sendButton.setDefault(True)
        self.horizontalLayout.addWidget(self.sendButton)
        self.verticalLayout.addLayout(self.horizontalLayout)

    def accept(self):
        text = self.errorTextEdit.toPlainText()
        url = QUrl(
            "mailto:[email protected]?SUBJECT=Error Report&BODY=%s" % text)
        QDesktopServices.openUrl(url)
        QDialog.accept(self)
class ErrorReportDialog(QDialog):
    def __init__(self, parent, github_url, error):
        flags = Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowSystemMenuHint
        QDialog.__init__(self, parent, flags)
        self._setupUi()
        name = QCoreApplication.applicationName()
        version = QCoreApplication.applicationVersion()
        errorText = "Application Name: {0}\nVersion: {1}\n\n{2}".format(name, version, error)
        # Under windows, we end up with an error report without linesep if we don't mangle it
        errorText = errorText.replace('\n', os.linesep)
        self.errorTextEdit.setPlainText(errorText)
        self.github_url = github_url

        self.sendButton.clicked.connect(self.goToGithub)
        self.dontSendButton.clicked.connect(self.reject)

    def _setupUi(self):
        self.setWindowTitle(tr("Error Report"))
        self.resize(553, 349)
        self.verticalLayout = QVBoxLayout(self)
        self.label = QLabel(self)
        self.label.setText(tr("Something went wrong. How about reporting the error?"))
        self.label.setWordWrap(True)
        self.verticalLayout.addWidget(self.label)
        self.errorTextEdit = QPlainTextEdit(self)
        self.errorTextEdit.setReadOnly(True)
        self.verticalLayout.addWidget(self.errorTextEdit)
        msg = tr(
            "Error reports should be reported as Github issues. You can copy the error traceback "
            "above and paste it in a new issue (bonus point if you run a search to make sure the "
            "issue doesn't already exist). What usually really helps is if you add a description "
            "of how you got the error. Thanks!"
            "\n\n"
            "Although the application should continue to run after this error, it may be in an "
            "unstable state, so it is recommended that you restart the application."
        )
        self.label2 = QLabel(msg)
        self.label2.setWordWrap(True)
        self.verticalLayout.addWidget(self.label2)
        self.horizontalLayout = QHBoxLayout()
        self.horizontalLayout.addItem(horizontalSpacer())
        self.dontSendButton = QPushButton(self)
        self.dontSendButton.setText(tr("Close"))
        self.dontSendButton.setMinimumSize(QSize(110, 0))
        self.horizontalLayout.addWidget(self.dontSendButton)
        self.sendButton = QPushButton(self)
        self.sendButton.setText(tr("Go to Github"))
        self.sendButton.setMinimumSize(QSize(110, 0))
        self.sendButton.setDefault(True)
        self.horizontalLayout.addWidget(self.sendButton)
        self.verticalLayout.addLayout(self.horizontalLayout)

    def goToGithub(self):
        open_url(self.github_url)
示例#7
0
class TracebackWidget(QWidget):
    """
    Represents a python traceback
    """
    def __init__(self, traceback_msg):
        QWidget.__init__(self)
        vbox = QVBoxLayout(self)
        self._editor = QPlainTextEdit()
        vbox.addWidget(QLabel(self.tr('Traceback')))
        vbox.addWidget(self._editor)
        self._editor.setReadOnly(True)
        self._editor.insertPlainText(traceback_msg)
示例#8
0
class TracebackWidget(QWidget):
    """
    Represents a python traceback
    """

    def __init__(self, traceback_msg):
        QWidget.__init__(self)
        vbox = QVBoxLayout(self)
        self._editor = QPlainTextEdit()
        vbox.addWidget(QLabel(self.tr("Traceback")))
        vbox.addWidget(self._editor)
        self._editor.setReadOnly(True)
        self._editor.insertPlainText(traceback_msg)
示例#9
0
class TracebackWidget(QWidget):
    """
    Represents a python traceback
    """
    def __init__(self, traceback_msg):
        QWidget.__init__(self)
        vbox = QVBoxLayout(self)
        self._editor = QPlainTextEdit()
        vbox.addWidget(QLabel(translations.TR_TRACEBACK))
        vbox.addWidget(self._editor)
        self._editor.setReadOnly(True)
        self._editor.setLineWrapMode(0)
        self._editor.insertPlainText(traceback_msg)
        self._editor.selectAll()
示例#10
0
class ErrorReportDialog(QDialog):
    def __init__(self, parent, error):
        flags = Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowSystemMenuHint
        QDialog.__init__(self, parent, flags)
        self._setupUi()
        name = QCoreApplication.applicationName()
        version = QCoreApplication.applicationVersion()
        errorText = "Application Name: {0}\nVersion: {1}\n\n{2}".format(name, version, error)
        # Under windows, we end up with an error report without linesep if we don't mangle it
        errorText = errorText.replace('\n', os.linesep)
        self.errorTextEdit.setPlainText(errorText)
        
        self.sendButton.clicked.connect(self.accept)
        self.dontSendButton.clicked.connect(self.reject)
    
    def _setupUi(self):
        self.setWindowTitle(tr("Error Report"))
        self.resize(553, 349)
        self.verticalLayout = QVBoxLayout(self)
        self.label = QLabel(self)
        self.label.setText(tr("Something went wrong. Would you like to send the error report to Hardcoded Software?"))
        self.label.setWordWrap(True)
        self.verticalLayout.addWidget(self.label)
        self.errorTextEdit = QPlainTextEdit(self)
        self.errorTextEdit.setReadOnly(True)
        self.verticalLayout.addWidget(self.errorTextEdit)
        msg = tr("Although the application should continue to run after this error, it may be in an "
            "instable state, so it is recommended that you restart the application.")
        self.label2 = QLabel(msg)
        self.label2.setWordWrap(True)
        self.verticalLayout.addWidget(self.label2)
        self.horizontalLayout = QHBoxLayout()
        self.horizontalLayout.addItem(horizontalSpacer())
        self.dontSendButton = QPushButton(self)
        self.dontSendButton.setText(tr("Don\'t Send"))
        self.dontSendButton.setMinimumSize(QSize(110, 0))
        self.horizontalLayout.addWidget(self.dontSendButton)
        self.sendButton = QPushButton(self)
        self.sendButton.setText(tr("Send"))
        self.sendButton.setMinimumSize(QSize(110, 0))
        self.sendButton.setDefault(True)
        self.horizontalLayout.addWidget(self.sendButton)
        self.verticalLayout.addLayout(self.horizontalLayout)
    
    def accept(self):
        text = self.errorTextEdit.toPlainText()
        url = QUrl("mailto:[email protected]?SUBJECT=Error Report&BODY=%s" % text)
        QDesktopServices.openUrl(url)
        QDialog.accept(self)
示例#11
0
class TracebackWidget(QWidget):
    """
    Represents a python traceback
    """

    def __init__(self, traceback_msg):
        QWidget.__init__(self)
        vbox = QVBoxLayout(self)
        self._editor = QPlainTextEdit()
        vbox.addWidget(QLabel(translations.TR_TRACEBACK))
        vbox.addWidget(self._editor)
        self._editor.setReadOnly(True)
        self._editor.setLineWrapMode(0)
        self._editor.insertPlainText(traceback_msg)
        self._editor.selectAll()
示例#12
0
class TextLogger(logging.Handler):
    ''' A logger to record the users actions and write them to a QPlainTextEdit widget.
    '''
    def __init__(self, parent):
        super(TextLogger, self).__init__()

        self.widget = QPlainTextEdit(parent)
        self.widget.setReadOnly(True)

    def emit(self, record):
        ''' Log a message.
        Args:
            record (str) : the message to log.
        '''
        message = self.format(record)
        self.widget.appendPlainText(message)
示例#13
0
class GdalParametersPanel(ParametersPanel):

    def __init__(self, parent, alg):
        ParametersPanel.__init__(self, parent, alg)

        w = QWidget()
        layout = QVBoxLayout()
        layout.setMargin(0)
        layout.setSpacing(6)
        label = QLabel()
        label.setText(self.tr("GDAL/OGR console call"))
        layout.addWidget(label)
        self.text = QPlainTextEdit()
        self.text.setReadOnly(True)
        layout.addWidget(self.text)
        w.setLayout(layout)
        self.layoutMain.addWidget(w)

        self.connectParameterSignals()
        self.parametersHaveChanged()

    def connectParameterSignals(self):
        for w in self.widgets.values():
            if isinstance(w, QLineEdit):
                w.textChanged.connect(self.parametersHaveChanged)
            elif isinstance(w, QComboBox):
                w.currentIndexChanged.connect(self.parametersHaveChanged)
            elif isinstance(w, QCheckBox):
                w.stateChanged.connect(self.parametersHaveChanged)
            elif isinstance(w, MultipleInputPanel):
                w.selectionChanged.connect(self.parametersHaveChanged)
            elif isinstance(w, NumberInputPanel):
                w.hasChanged.connect(self.parametersHaveChanged)

    def parametersHaveChanged(self):
        try:
            self.parent.setParamValues()
            for output in self.alg.outputs:
                if output.value is None:
                    output.value = self.tr("[temporary file]")
            commands = self.alg.getConsoleCommands()
            commands = [c for c in commands if c not in ['cmd.exe', '/C ']]
            self.text.setPlainText(" ".join(commands))
        except AlgorithmDialogBase.InvalidParameterValue as e:
            self.text.setPlainText(self.tr("Invalid value for parameter '%s'") % e.parameter.description)
        except:
            self.text.setPlainText("")
示例#14
0
    def print_result(self, result, history):
        """
            Print processing result
        """
        self.result = result
        self.history = history

        message = "Filter " + self.history['process'] + "    params: "
        for param in self.history['params'].keys():
            message += " " + param + " : " + str(
                self.history['params'][param]) + " |"

        self.historyBox.appendPlainText(message)

        if result['type'] == "sensor":
            self.draw_chart(self.result['data'])

        elif result['type'] == "sensor list":
            self.draw_multiple_chart(self.result['data'])

        elif result['type'] == "dict list":
            field = QPlainTextEdit()
            field.setReadOnly(True)
            for elem in self.result['data']:
                tmp = ""
                for key in elem.keys():
                    tmp += key + " : " + str(elem[key]) + " "
                field.appendPlainText(tmp)

            self.clear_layout(self.resultFrame.layout())
            self.resultFrame.layout().addWidget(field)

        elif result['type'] == "dict":
            field = QPlainTextEdit()
            field.setReadOnly(True)
            data = self.result['data']
            for key in data.keys():
                field.appendPlainText(key + " : " + str(data[key]))

            self.clear_layout(self.resultFrame.layout())
            self.resultFrame.layout().addWidget(field)
        else:
            print "undefined result"

        self.base_thread.quit()
示例#15
0
    def __init__(self, authors, translators, parent=None):
        super(CreditsDialog, self).__init__(parent)
        self.parent = parent

        authorsLabel = QPlainTextEdit(authors)
        authorsLabel.setReadOnly(True)
        translatorsLabel = QPlainTextEdit(translators)
        translatorsLabel.setReadOnly(True)
        TabWidget = QTabWidget()
        TabWidget.addTab(authorsLabel, self.tr('Written by'))
        TabWidget.addTab(translatorsLabel, self.tr('Translated by'))
        closeQPB = QPushButton(self.tr('&Close'))

        hlayout = utils.add_to_layout('h', None, closeQPB)
        vlayout = utils.add_to_layout('v', TabWidget, hlayout)

        self.setLayout(vlayout)
        closeQPB.clicked.connect(self.close)

        self.setMinimumSize(QSize(335, 370))
        self.setMaximumSize(QSize(335, 370))
        self.setWindowTitle(self.tr('Credits'))
示例#16
0
    def __init__(self, authors, translators, parent=None):
        super(CreditsDialog, self).__init__(parent)
        self.parent = parent

        authorsLabel = QPlainTextEdit(authors)
        authorsLabel.setReadOnly(True)
        translatorsLabel = QPlainTextEdit(translators)
        translatorsLabel.setReadOnly(True)
        TabWidget = QTabWidget()
        TabWidget.addTab(authorsLabel, self.tr('Written by'))
        TabWidget.addTab(translatorsLabel, self.tr('Translated by'))
        closeQPB = QPushButton(self.tr('&Close'))

        hlayout = utils.add_to_layout('h', None, closeQPB)
        vlayout = utils.add_to_layout('v', TabWidget, hlayout)

        self.setLayout(vlayout)
        closeQPB.clicked.connect(self.close)

        self.setMinimumSize(QSize(335, 370))
        self.setMaximumSize(QSize(335, 370))
        self.setWindowTitle(self.tr('Credits'))
class SystemLog(object):
    def __init__(self, display_name, source_name):
        self.display_name = display_name
        self.source_name = source_name  # FIXME: need to handle rotated logs
        self.last_filename = os.path.join(get_home_path(), display_name)
        self.content = ''
        self.edit = QPlainTextEdit()
        self.normal_font = self.edit.font()
        self.monospace_font = QFont('monospace')

        self.edit.setUndoRedoEnabled(False)
        self.edit.setReadOnly(True)
        self.edit.setWordWrapMode(QTextOption.NoWrap)
        self.edit.setPlainText(
            'Click "Refresh" to download {0}.'.format(display_name))

        self.monospace_font.setStyleHint(QFont.TypeWriter)

    def log(self, message, bold=False, pre=False):
        if bold:
            self.edit.appendHtml(u'<b>{0}</b>'.format(Qt.escape(message)))
        elif pre:
            self.edit.appendHtml(u'<pre>{0}</pre>'.format(message))
        else:
            self.edit.appendPlainText(message)

    def reset(self):
        self.content = None

        self.edit.setPlainText('')
        self.edit.setFont(self.normal_font)

    def set_content(self, content):
        self.content = content

        self.edit.setPlainText('')
        self.edit.setFont(self.monospace_font)
        self.edit.setPlainText(content)
示例#18
0
class DependenciesHelpDialog(QDialog):
    """Help on Plugin Dependencies widget"""
    def __init__(self, requirements_dict):
        super(DependenciesHelpDialog, self).__init__()
        self.setWindowTitle(translations.TR_REQUIREMENTS)
        self.resize(525, 400)
        vbox = QVBoxLayout(self)
        label = QLabel(translations.TR_SOME_PLUGINS_NEED_DEPENDENCIES)
        vbox.addWidget(label)
        self._editor = QPlainTextEdit()
        self._editor.setReadOnly(True)
        vbox.addWidget(self._editor)
        hbox = QHBoxLayout()
        btnAccept = QPushButton(translations.TR_ACCEPT)
        btnAccept.setMaximumWidth(100)
        hbox.addWidget(btnAccept)
        vbox.addLayout(hbox)
        # signals
        self.connect(btnAccept, SIGNAL("clicked()"), self.close)

        command_tmpl = "<%s>:\n%s\n"
        for name, description in list(requirements_dict.items()):
            self._editor.insertPlainText(command_tmpl % (name, description))
class SystemLog(object):
    def __init__(self, display_name, source_name):
        self.display_name   = display_name
        self.source_name    = source_name # FIXME: need to handle rotated logs
        self.last_filename  = os.path.join(get_home_path(), display_name)
        self.content        = ''
        self.edit           = QPlainTextEdit()
        self.normal_font    = self.edit.font()
        self.monospace_font = QFont('monospace')

        self.edit.setUndoRedoEnabled(False)
        self.edit.setReadOnly(True)
        self.edit.setWordWrapMode(QTextOption.NoWrap)
        self.edit.setPlainText('Click "Refresh" to download {0}.'.format(display_name))

        self.monospace_font.setStyleHint(QFont.TypeWriter)

    def log(self, message, bold=False, pre=False):
        if bold:
            self.edit.appendHtml(u'<b>{0}</b>'.format(Qt.escape(message)))
        elif pre:
            self.edit.appendHtml(u'<pre>{0}</pre>'.format(message))
        else:
            self.edit.appendPlainText(message)

    def reset(self):
        self.content = None

        self.edit.setPlainText('')
        self.edit.setFont(self.normal_font)

    def set_content(self, content):
        self.content = content

        self.edit.setPlainText('')
        self.edit.setFont(self.monospace_font)
        self.edit.setPlainText(content)
示例#20
0
class DependenciesHelpDialog(QDialog):
    """Help on Plugin Dependencies widget"""

    def __init__(self, requirements_dict):
        super(DependenciesHelpDialog, self).__init__()
        self.setWindowTitle(translations.TR_REQUIREMENTS)
        self.resize(525, 400)
        vbox = QVBoxLayout(self)
        label = QLabel(translations.TR_SOME_PLUGINS_NEED_DEPENDENCIES)
        vbox.addWidget(label)
        self._editor = QPlainTextEdit()
        self._editor.setReadOnly(True)
        vbox.addWidget(self._editor)
        hbox = QHBoxLayout()
        btnAccept = QPushButton(translations.TR_ACCEPT)
        btnAccept.setMaximumWidth(100)
        hbox.addWidget(btnAccept)
        vbox.addLayout(hbox)
        #signals
        self.connect(btnAccept, SIGNAL("clicked()"), self.close)

        command_tmpl = "<%s>:\n%s\n"
        for name, description in list(requirements_dict.items()):
            self._editor.insertPlainText(command_tmpl % (name, description))
示例#21
0
class DebugLogWidget(QWidget):
    def __init__(self, parent):
        QWidget.__init__(self, parent)
        self.canMonitor = parent

    def addToWidget(self, vbox):
        self.text = QPlainTextEdit(self.canMonitor)
        self.text.setReadOnly(True)
        vbox.addWidget(self.text)

        hbox = QHBoxLayout()
        hbox.setAlignment(Qt.AlignRight | Qt.AlignBottom)
        self.clearButton = QPushButton("Clear", self.canMonitor)
        self.clearButton.clicked.connect(self._clearText)
        hbox.addWidget(self.clearButton)

        vbox.addLayout(hbox)

    @pyqtSlot()
    def _clearText(self):
        self.text.clear()

    def addLineToLog(self, line):
        self.text.appendPlainText(line)
示例#22
0
class DependenciesHelpDialog(QDialog):
    def __init__(self, requirements_dict):
        super(DependenciesHelpDialog, self).__init__()
        self.setWindowTitle(self.tr("Plugin requirements"))
        self.resize(525, 400)
        vbox = QVBoxLayout(self)
        label = QLabel(self.tr("""It seems that some plugins needs some
            dependencies to be solved to work properly, you should install them
            as follows using a Terminal"""))
        vbox.addWidget(label)
        self._editor = QPlainTextEdit()
        self._editor.setReadOnly(True)
        vbox.addWidget(self._editor)
        hbox = QHBoxLayout()
        btnAccept = QPushButton(self.tr("Accept"))
        btnAccept.setMaximumWidth(100)
        hbox.addWidget(btnAccept)
        vbox.addLayout(hbox)
        #signals
        self.connect(btnAccept, SIGNAL("clicked()"), self.close)

        command_tmpl = "<%s>:\n%s\n"
        for name, description in list(requirements_dict.items()):
            self._editor.insertPlainText(command_tmpl % (name, description))
示例#23
0
class OWBioMart(widget.OWWidget):
    name = "BioMart"
    description = "Query BioMart service"
    icon = "../widgets/icons/BioMart.svg"
    priority = 2010

    inputs = [("Input ids", Orange.data.Table, "setData")]
    outputs = [("Data", Orange.data.Table)]

    SHOW_FILTERS = True

    selectedDataset = settings.Setting(0)

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

        self.selectedDatabase = 0

        self.idAttr = 0
        self.useAttrNames = False
        self.uniqueRows = True

        gui.button(
            gui.widgetBox(self.controlArea, "Cache", addSpace=True),
            self,
            "Clear cache",
            tooltip="Clear saved query results",
            callback=self.clearCache,
        )

        self.martsCombo = gui.comboBox(
            self.controlArea, self, "selectedDatabase", "Database", callback=self.setSelectedMart, addSpace=True
        )
        self.martsCombo.setMaximumWidth(250)

        self.datasetsCombo = gui.comboBox(
            self.controlArea, self, "selectedDataset", "Dataset", callback=self.setSelectedDataset, addSpace=True
        )

        self.datasetsCombo.setMaximumWidth(250)

        box = gui.widgetBox(self.controlArea, "Input Ids")

        cb = gui.checkBox(
            box,
            self,
            "useAttrNames",
            "Use attribute names",
            tooltip="Use attribute names for ids",
            callback=self.updateInputIds,
        )

        self.idAttrCB = gui.comboBox(
            box, self, "idAttr", tooltip="Use attribute values from ...", callback=self.updateInputIds
        )

        cb.disables = [(-1, self.idAttrCB)]
        cb.makeConsistent()

        self.idText = QPlainTextEdit()
        self.idText.setReadOnly(True)

        box.layout().addWidget(self.idText)

        gui.rubber(self.controlArea)

        box = gui.widgetBox(self.controlArea, "Results")
        gui.checkBox(box, self, "uniqueRows", "Unique results only", tooltip="Return unique results only.")

        self.commitButton = gui.button(
            box,
            self,
            "Get Results",
            callback=self.commit,
            tooltip="Query the BioMart server and output the results",
            autoDefault=True,
        )

        self.commitButton.setEnabled(False)

        self.mainWidget = gui.widgetBox(self.mainArea, orientation=QStackedLayout())

        self.mainTab = QTabWidget()

        self.mainWidget.layout().addWidget(self.mainTab)

        self.attributesConfigurationBox = gui.createTabPage(self.mainTab, "Attributes")

        if self.SHOW_FILTERS:  # ??
            self.filtersConfigurationBox = gui.createTabPage(self.mainTab, "Filters")

        self.error(0)
        self.setEnabled(False)
        self._executor = concurrent.ThreadExecutor(threadPool=QThreadPool(maxThreadCount=2))
        self._task = task = concurrent.Task(function=self._get_registry)
        task.resultReady.connect(self.setBioMartRegistry)
        task.exceptionReady.connect(self._handleException)
        self._executor.submit(task)

        self.candidateIdAttrs = []
        self._afterInitQueue = []
        self.data = None

        try:
            from Bio import SeqIO

            self.hasBiopython = True
        except ImportError:
            self.warning(
                100, "Biopython package not found.\nTo retrieve FASTA sequence data from BioMart install Biopython."
            )
            self.hasBiopython = False

    def sizeHint(self):
        return QSize(800, 600)

    @staticmethod
    def _get_registry(url=None, precache=True):
        con = biomart.BioMartConnection(url)
        reg = biomart.BioMartRegistry(con)
        if precache:
            _ = reg.marts()
        return reg

    @Slot(Exception)
    def _handleException(self, exception):
        assert QThread.currentThread() is self.thread()
        print("Task failed with:", exception, file=sys.stderr)
        self.error(0, str(exception))
        self.setEnabled(True)

    @Slot(object)
    def setBioMartRegistry(self, registry):
        assert QThread.currentThread() is self.thread()
        self.setEnabled(True)
        self.registry = registry
        self.marts = [mart for mart in self.registry.marts() if getattr(mart, "visible", "0") != "0"]

        for mart in self.marts:
            self.martsCombo.addItem(mart.displayName)

    def setSelectedMart(self):
        self.mart = self.marts[self.selectedDatabase]

        self.error(0)
        self.setEnabled(False)

        self._task = task = concurrent.Task(function=self.mart.datasets)
        task.resultReady.connect(self.setBioMartDatasets)
        task.exceptionReady.connect(self._handleException)
        self._executor.submit(task)

    @Slot(object)
    def setBioMartDatasets(self, datasets):
        assert QThread.currentThread() is self.thread()
        self.setEnabled(True)
        self.datasets = [data for data in datasets if getattr(data, "visible", "0") != "0"]
        self.datasetsCombo.clear()
        self.datasetsCombo.addItems([data.displayName for data in self.datasets])

    def setSelectedDataset(self):
        self.dataset = self.datasets[self.selectedDataset]
        self.error(0)
        self.setEnabled(False)

        def get_configuration(dataset):
            connection = dataset.connection
            stream = connection.configuration(dataset=dataset.internalName, virtualSchema=dataset.virtualSchema)
            response = stream.read()
            return response

        self._task = task = concurrent.Task(function=partial(get_configuration, self.dataset))

        task.resultReady.connect(self.setBioMartConfiguration)
        task.exceptionReady.connect(self._handleException)

        self._executor.submit(task)

    @Slot(object)
    def setBioMartConfiguration(self, configuration):
        assert QThread.currentThread() is self.thread()
        self.setEnabled(True)
        # parse the xml in the main thread (a long time ago this step was
        # done in a thread but would frequently cause `expat` to segfault.
        doc = biomart.parseXML(io.BytesIO(configuration))
        config = list(doc.elements("DatasetConfig"))[0]
        configuration = biomart.DatasetConfig(self.registry, config.tag, config.attributes, config.children)

        self.clearConfiguration()

        self.configuration = configuration

        def hidden(tree):
            return getattr(tree, "hidden", "false") != "false" or getattr(tree, "hideDisplay", "false") != "false"

        self.attributePagesTabWidget = tabs = gui.tabWidget(self.attributesConfigurationBox)

        for page in configuration.elements("AttributePage"):
            if not hidden(page):
                page_widget = PageWidget(page, self.dataset, self)
                gui.createTabPage(tabs, getattr(page, "displayName", ""), widgetToAdd=page_widget, canScroll=True)

        if self.SHOW_FILTERS:
            self.filterPagesTabWidget = tabs = gui.tabWidget(self.filtersConfigurationBox)
            for page in configuration.elements("FilterPage"):
                if not hidden(page):
                    page_widget = PageWidget(page, self.dataset, self)
                    gui.createTabPage(tabs, getattr(page, "displayName", ""), widgetToAdd=page_widget, canScroll=True)

        self.afterInit()

        self.commitButton.setEnabled(True)

    def clearConfiguration(self):
        self.mainTab.deleteLater()

        self.mainTab = QTabWidget()
        self.mainWidget.layout().addWidget(self.mainTab)
        self.mainWidget.layout().setCurrentWidget(self.mainTab)

        self.attributesConfigurationBox = gui.createTabPage(self.mainTab, "Attributes")
        if self.SHOW_FILTERS:
            self.filtersConfigurationBox = gui.createTabPage(self.mainTab, "Filters")

    def commit(self):
        pageconf = self.attributePagesTabWidget.currentWidget().widget()
        format = pageconf.outFormats

        self.error(100)
        if not self.hasBiopython and format.lower() == "fasta":
            self.error(100, "Cannot parse FASTA format")
            return

        query = pageconf.query()
        bydatasets = defaultdict(lambda: ([], []))

        for conftype, tree, val in query:
            dataset = self.dataset

            if conftype == "Attribute":
                bydatasets[dataset][0].append(tree.internalName)
            elif conftype == "Filter":
                bydatasets[dataset][1].append((tree.internalName, val))

        if self.SHOW_FILTERS:
            pageconf = self.filterPagesTabWidget.currentWidget().widget()
            query = pageconf.query()

            for conftype, tree, val in query:
                dataset = self.dataset

                if conftype == "Attribute":
                    bydatasets[dataset][0].append(tree.internalName)
                elif conftype == "Filter":
                    bydatasets[dataset][1].append((tree.internalName, val))

        query = self.registry.query(
            format="TSV" if "tsv" in format.lower() else format.upper(), uniqueRows=self.uniqueRows
        )

        for dataset, (attributes, filters) in bydatasets.items():
            query.set_dataset(dataset if dataset else self.dataset)
            for attr in attributes:
                query.add_attribute(attr)
            for filter, value in filters:
                query.add_filter(filter, value)

        self.error(0)
        self.setEnabled(False)
        self._task = task = concurrent.Task(function=query.get_table)
        task.resultReady.connect(self.dataReady)
        task.exceptionReady.connect(self._handleException)
        self._executor.submit(task)

    def dataReady(self, data):
        self.setEnabled(True)
        self.send("Data", data)

    def pushAction(self, action):
        ref = action.ref
        ref_widget = self.findChild(QWidget, ref)
        if hasattr(ref_widget, "setOptions"):
            ref_widget.setOptions(action.subelements_top("Option"))

    def registerDelayedCall(self, call):
        self._afterInitQueue.append(call)

    def afterInit(self):
        while self._afterInitQueue:
            call = self._afterInitQueue.pop(0)
            call()

    def setData(self, data=None):
        self.candidateIdAttrs = []
        self.data = data
        self.idAttrCB.clear()
        if data is not None:
            attrs = data.domain.variables + data.domain.metas
            attrs = [attr for attr in attrs if isinstance(attr, Orange.data.StringVariable)]
            self.candidateIdAttrs = attrs
            self.idAttrCB.addItems([attr.name for attr in attrs])
            self.idAttr = min(self.idAttr, len(self.candidateIdAttrs) - 1)

        self.updateInputIds()

    def updateInputIds(self):
        if self.data is not None:
            if self.useAttrNames:
                names = [attr.name for attr in self.data.domain.attributes]
            elif self.candidateIdAttrs:
                attr = self.candidateIdAttrs[self.idAttr]
                names = [str(ex[attr]) for ex in self.data if not numpy.isnan(ex[attr])]
            else:
                names = []
        else:
            names = []

        self.idText.setPlainText("\n".join(names))

    def clearCache(self):
        self.registry.connection.clear_cache()
示例#24
0
class SkinsTab(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        vbox = QVBoxLayout(self)

        #Top Bar
        hbox = QHBoxLayout()
        self.radioDefault = QRadioButton("Default Skin")
        self.radioCustom = QRadioButton("Custom")
        self.comboSkins = QComboBox()
        self.skins = loader.load_gui_skins()
        for item in self.skins:
            self.comboSkins.addItem(item)
        hbox.addWidget(self.radioDefault)
        hbox.addWidget(self.radioCustom)
        hbox.addWidget(self.comboSkins)
        #Text Area
        self.txtStyle = QPlainTextEdit()
        self.txtStyle.setReadOnly(True)

        #Settings
        settings = QSettings()
        settings.beginGroup('preferences')
        settings.beginGroup('skins')
        if settings.value('default', True).toBool():
            self.radioDefault.setChecked(True)
            self.comboSkins.setEnabled(False)
        else:
            self.radioCustom.setChecked(True)
            index = self.comboSkins.findText(
                settings.value('selectedSkin', '').toString())
            self.comboSkins.setCurrentIndex(index)
            content = self.skins[str(self.comboSkins.currentText())]
            self.txtStyle.setPlainText(content)
        settings.endGroup()
        settings.endGroup()

        vbox.addLayout(hbox)
        vbox.addWidget(self.txtStyle)
        vbox.addWidget(QLabel('Requires restart the IDE'))

        #Signals
        self.connect(self.radioDefault, SIGNAL("clicked()"),
                     self._default_clicked)
        self.connect(self.radioCustom, SIGNAL("clicked()"),
                     self._custom_clicked)

    def _default_clicked(self):
        self.comboSkins.setEnabled(False)
        self.txtStyle.setPlainText('')

    def _custom_clicked(self):
        self.comboSkins.setEnabled(True)
        content = self.skins[str(self.comboSkins.currentText())]
        self.txtStyle.setPlainText(content)

    def save(self):
        settings = QSettings()
        settings.beginGroup('preferences')
        settings.beginGroup('skins')
        settings.setValue('default', self.radioDefault.isChecked())
        settings.setValue('selectedSkin', self.comboSkins.currentText())
        settings.endGroup()
        settings.endGroup()
示例#25
0
class MigrationWidget(QWidget):

    def __init__(self):
        super(MigrationWidget, self).__init__()
        self._migration = {}
        vbox = QVBoxLayout(self)
        lbl_title = QLabel(self.tr("Current code:"))
        self.current_list = QListWidget()
        lbl_suggestion = QLabel(self.tr("Suggested changes:"))
        self.suggestion = QPlainTextEdit()
        self.suggestion.setReadOnly(True)

        self.btn_apply = QPushButton(self.tr("Apply change!"))
        hbox = QHBoxLayout()
        hbox.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding))
        hbox.addWidget(self.btn_apply)

        vbox.addWidget(lbl_title)
        vbox.addWidget(self.current_list)
        vbox.addWidget(lbl_suggestion)
        vbox.addWidget(self.suggestion)
        vbox.addLayout(hbox)

        self.connect(self.current_list,
            SIGNAL("itemClicked(QListWidgetItem*)"), self.load_suggestion)
        self.connect(self.btn_apply, SIGNAL("clicked()"), self.apply_changes)

    def apply_changes(self):
        lineno = int(self.current_list.currentItem().data(Qt.UserRole))
        lines = self._migration.migration_data[lineno][0].split('\n')
        remove = -1
        code = ''
        for line in lines:
            if line.startswith('-'):
                remove += 1
            elif line.startswith('+'):
                code += '%s\n' % line[1:]

        main_container = IDE.get_service('main_container')
        if main_container:
            editorWidget = main_container.get_actual_editor()
            block_start = editorWidget.document().findBlockByLineNumber(lineno)
            block_end = editorWidget.document().findBlockByLineNumber(
                lineno + remove)
            cursor = editorWidget.textCursor()
            cursor.setPosition(block_start.position())
            cursor.setPosition(block_end.position(), QTextCursor.KeepAnchor)
            cursor.movePosition(QTextCursor.EndOfLine, QTextCursor.KeepAnchor)
            cursor.insertText(code[:-1])

    def load_suggestion(self, item):
        lineno = int(item.data(Qt.UserRole))
        lines = self._migration.migration_data[lineno][0].split('\n')
        code = ''
        for line in lines:
            if line.startswith('+'):
                code += '%s\n' % line[1:]
        self.suggestion.setPlainText(code)
        main_container = IDE.get_service('main_container')
        if main_container:
            editorWidget = main_container.get_actual_editor()
            if editorWidget:
                editorWidget.jump_to_line(lineno)
                editorWidget.setFocus()

    def refresh_lists(self, migration):
        self._migration = migration
        self.current_list.clear()
        base_lineno = -1
        for lineno in sorted(migration.migration_data.keys()):
            linenostr = 'L%s\n' % str(lineno + 1)
            data = migration.migration_data[lineno]
            lines = data[0].split('\n')
            if base_lineno == data[1]:
                continue
            base_lineno = data[1]
            message = ''
            for line in lines:
                if line.startswith('-'):
                    message += '%s\n' % line
            item = QListWidgetItem(linenostr + message)
            item.setToolTip(linenostr + message)
            item.setData(Qt.UserRole, lineno)
            self.current_list.addItem(item)

    def clear(self):
        """
        Clear the widget
        """
        self.current_list.clear()
        self.suggestion.clear()
示例#26
0
class MigrationWidget(QWidget):
    def __init__(self):
        super(MigrationWidget, self).__init__()
        self._migration = {}
        vbox = QVBoxLayout(self)
        lbl_title = QLabel(self.tr("Current code:"))
        self.current_list = QListWidget()
        lbl_suggestion = QLabel(self.tr("Suggested changes:"))
        self.suggestion = QPlainTextEdit()
        self.suggestion.setReadOnly(True)

        self.btn_apply = QPushButton(self.tr("Apply change!"))
        hbox = QHBoxLayout()
        hbox.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding))
        hbox.addWidget(self.btn_apply)

        vbox.addWidget(lbl_title)
        vbox.addWidget(self.current_list)
        vbox.addWidget(lbl_suggestion)
        vbox.addWidget(self.suggestion)
        vbox.addLayout(hbox)

        self.connect(self.current_list,
                     SIGNAL("itemClicked(QListWidgetItem*)"),
                     self.load_suggestion)
        self.connect(self.btn_apply, SIGNAL("clicked()"), self.apply_changes)

    def apply_changes(self):
        lineno = int(self.current_list.currentItem().data(Qt.UserRole))
        lines = self._migration.migration_data[lineno][0].split('\n')
        remove = -1
        code = ''
        for line in lines:
            if line.startswith('-'):
                remove += 1
            elif line.startswith('+'):
                code += '%s\n' % line[1:]

        editorWidget = main_container.MainContainer().get_actual_editor()
        block_start = editorWidget.document().findBlockByLineNumber(lineno)
        block_end = editorWidget.document().findBlockByLineNumber(lineno +
                                                                  remove)
        cursor = editorWidget.textCursor()
        cursor.setPosition(block_start.position())
        cursor.setPosition(block_end.position(), QTextCursor.KeepAnchor)
        cursor.movePosition(QTextCursor.EndOfLine, QTextCursor.KeepAnchor)
        cursor.insertText(code[:-1])

    def load_suggestion(self, item):
        lineno = int(item.data(Qt.UserRole))
        lines = self._migration.migration_data[lineno][0].split('\n')
        code = ''
        for line in lines:
            if line.startswith('+'):
                code += '%s\n' % line[1:]
        self.suggestion.setPlainText(code)
        editorWidget = main_container.MainContainer().get_actual_editor()
        if editorWidget:
            editorWidget.jump_to_line(lineno)
            editorWidget.setFocus()

    def refresh_lists(self, migration):
        self._migration = migration
        self.current_list.clear()
        base_lineno = -1
        for lineno in sorted(migration.migration_data.keys()):
            linenostr = 'L%s\n' % str(lineno + 1)
            data = migration.migration_data[lineno]
            lines = data[0].split('\n')
            if base_lineno == data[1]:
                continue
            base_lineno = data[1]
            message = ''
            for line in lines:
                if line.startswith('-'):
                    message += '%s\n' % line
            item = QListWidgetItem(linenostr + message)
            item.setToolTip(linenostr + message)
            item.setData(Qt.UserRole, lineno)
            self.current_list.addItem(item)

    def clear(self):
        """
        Clear the widget
        """
        self.current_list.clear()
        self.suggestion.clear()
示例#27
0
class Ui_MainWindow(object):
	def setupUi(self, MainWindow):
		MainWindow.setObjectName(_fromUtf8("MainWindow"))
		MainWindow.resize(300, 270)
		self.centralwidget = QWidget(MainWindow)
		self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
		self.buttonSave = QPushButton(self.centralwidget)
		self.buttonSave.setGeometry(QRect(120, 235, 71, 32))
		self.buttonSave.setObjectName(_fromUtf8("buttonSave"))
		self.inputFolder = QLineEdit(self.centralwidget)
		self.inputFolder.setGeometry(QRect(130, 10, 131, 23))
		self.inputFolder.setObjectName(_fromUtf8("inputFolder"))
		self.buttonSelectFolder = QToolButton(self.centralwidget)
		self.buttonSelectFolder.setGeometry(QRect(263, 10, 27, 23))
		self.buttonSelectFolder.setToolButtonStyle(Qt.ToolButtonIconOnly)
		self.buttonSelectFolder.setAutoRaise(False)
		self.buttonSelectFolder.setArrowType(Qt.NoArrow)
		self.buttonSelectFolder.setObjectName(_fromUtf8("buttonSelectFolder"))
		self.labelFolder = QLabel(self.centralwidget)
		self.labelFolder.setGeometry(QRect(10, 13, 101, 16))
		self.labelFolder.setObjectName(_fromUtf8("labelFolder"))
		self.inputLogin = QLineEdit(self.centralwidget)
		self.inputLogin.setGeometry(QRect(130, 40, 161, 23))
		self.inputLogin.setObjectName(_fromUtf8("inputLogin"))
		self.inputPassword = QLineEdit(self.centralwidget)
		self.inputPassword.setGeometry(QRect(130, 70, 161, 23))
		self.inputPassword.setObjectName(_fromUtf8("inputPassword"))
		self.labelLogin = QLabel(self.centralwidget)
		self.labelLogin.setGeometry(QRect(10, 42, 62, 16))
		self.labelLogin.setObjectName(_fromUtf8("labelLogin"))
		self.labelPassword = QLabel(self.centralwidget)
		self.labelPassword.setGeometry(QRect(10, 72, 62, 16))
		self.labelPassword.setObjectName(_fromUtf8("labelPassword"))
		self.output = QPlainTextEdit(self.centralwidget)
		self.output.setEnabled(True)
		self.output.setGeometry(QRect(10, 100, 281, 131))
		self.output.viewport().setProperty("cursor", QCursor(Qt.IBeamCursor))
		self.output.setReadOnly(True)
		self.output.setObjectName(_fromUtf8("output"))
		font = QApplication.font()
		font.setPointSize(11)
		self.output.setFont(font)
		MainWindow.setCentralWidget(self.centralwidget)

		self.retranslateUi(MainWindow)
		self.connectSignals()
		QMetaObject.connectSlotsByName(MainWindow)

	def retranslateUi(self, MainWindow):
		MainWindow.setWindowTitle(QApplication.translate("MainWindow", "TDS Dropbox setup", None, QApplication.UnicodeUTF8))
		self.buttonSave.setText(QApplication.translate("MainWindow", "Save", None, QApplication.UnicodeUTF8))
		self.buttonSelectFolder.setText(QApplication.translate("MainWindow", "...", None, QApplication.UnicodeUTF8))
		self.labelFolder.setText(QApplication.translate("MainWindow", "Folder to sync", None, QApplication.UnicodeUTF8))
		self.labelLogin.setText(QApplication.translate("MainWindow", "Login", None, QApplication.UnicodeUTF8))
		self.labelPassword.setText(QApplication.translate("MainWindow", "Password", None, QApplication.UnicodeUTF8))

	def connectSignals(self):
		QObject.connect(self.buttonSelectFolder, SIGNAL("clicked()"), self.selectFolder)
		QObject.connect(self.centralwidget, SIGNAL("folderIsSet(PyQt_PyObject)"), self.setFolder)
		QObject.connect(self.buttonSave, SIGNAL("clicked()"), self.validateData)
		

	def selectFolder(self):
		folder = QFileDialog.getExistingDirectory(self.centralwidget, "Choose folder to sync", os.getenv("HOME"))
		QObject.emit(self.centralwidget, SIGNAL("folderIsSet(PyQt_PyObject)"), folder)

	def setFolder(self, folder):
		self.inputFolder.setText(folder)

	def validateData(self):
		validate = True
		if (len(self.inputFolder.text()) == 0):
			self.error("You haven't choose the dir to sync!")
			validate = False
		if (len(self.inputLogin.text()) == 0):
			self.error("You havent enter the login!")
			validate = False
		if (len(self.inputPassword.text()) == 0):
			self.error("You haven't enter the password!")
			validate = False
		if (validate):
			self.lockGui()
			self.out("setup start")
			self.setupSync({"folder": self.inputFolder.text(), "login": self.inputLogin.text(), "password": self.inputPassword.text()})
			self.unlockGui()

	def lockGui(self):
		self.inputFolder.setReadOnly(True)
		self.inputLogin.setReadOnly(True)
		self.inputPassword.setReadOnly(True)
		self.buttonSave.setDisabled(True)
		self.buttonSelectFolder.setDisabled(True)

	def unlockGui(self):
		self.inputFolder.setReadOnly(False)
		self.inputLogin.setReadOnly(False)
		self.inputPassword.setReadOnly(False)
		self.buttonSave.setDisabled(False)
		self.buttonSelectFolder.setDisabled(False)

	def setupSync(self, data):
		p = Popen(["./letssync.sh", "-u%(login)s" % data, "-p%(password)s" % data, "%(folder)s" % data])
		if (p.wait() != 0):
			self.error("an error occuring during setup!")
		else:
			self.out("setup complete!")

	def error(self, message):
		self.out("ERROR: {}".format(message))

	def out(self, message):
		self.output.appendPlainText("{0} :: {1}".format(datetime.now().strftime("%H:%M"), message))
示例#28
0
class LogViewer(QWidget):
    """ The log (+stdout, +stderr) viewer widget """
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        self.__isEmpty = True
        self.__copyAvailable = False
        self.clearButton = None
        self.messages = None
        self.copyButton = None
        self.selectAllButton = None
        self.__createLayout(parent)

        # create the context menu
        self.__menu = QMenu(self)
        self.__selectAllMenuItem = self.__menu.addAction(
            PixmapCache().getIcon('selectall.png'), 'Select All',
            self.messages.selectAll)
        self.__copyMenuItem = self.__menu.addAction(
            PixmapCache().getIcon('copytoclipboard.png'), 'Copy',
            self.messages.copy)
        self.__menu.addSeparator()
        self.__clearMenuItem = self.__menu.addAction(
            PixmapCache().getIcon('trash.png'), 'Clear', self.__clear)

        self.messages.setContextMenuPolicy(Qt.CustomContextMenu)
        self.messages.customContextMenuRequested.connect(
            self.__handleShowContextMenu)
        self.messages.copyAvailable.connect(self.__onCopyAvailable)

        self.cNormalFormat = self.messages.currentCharFormat()
        self.cErrorFormat = self.messages.currentCharFormat()
        self.cErrorFormat.setForeground(QBrush(QColor(Qt.red)))
        self.__updateToolbarButtons()
        return

    def __createLayout(self, parent):
        " Helper to create the viewer layout "

        # Messages list area
        self.messages = QPlainTextEdit(parent)
        self.messages.setLineWrapMode(QPlainTextEdit.NoWrap)
        self.messages.setFont(QFont(GlobalData().skin.baseMonoFontFace))
        self.messages.setReadOnly(True)
        self.messages.setMaximumBlockCount(MAX_LINES)

        # Default font size is good enough for most of the systems.
        # 12.0 might be good only in case of the XServer on PC (Xming).
        # self.messages.setFontPointSize( 12.0 )

        # Buttons
        self.selectAllButton = QAction(PixmapCache().getIcon('selectall.png'),
                                       'Select all', self)
        self.selectAllButton.triggered.connect(self.messages.selectAll)
        self.copyButton = QAction(PixmapCache().getIcon('copytoclipboard.png'),
                                  'Copy to clipboard', self)
        self.copyButton.triggered.connect(self.messages.copy)
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.clearButton = QAction(PixmapCache().getIcon('trash.png'),
                                   'Clear all', self)
        self.clearButton.triggered.connect(self.__clear)

        # Toolbar
        self.toolbar = QToolBar()
        self.toolbar.setOrientation(Qt.Vertical)
        self.toolbar.setMovable(False)
        self.toolbar.setAllowedAreas(Qt.LeftToolBarArea)
        self.toolbar.setIconSize(QSize(16, 16))
        self.toolbar.setFixedWidth(28)
        self.toolbar.setContentsMargins(0, 0, 0, 0)
        self.toolbar.addAction(self.selectAllButton)
        self.toolbar.addAction(self.copyButton)
        self.toolbar.addWidget(spacer)
        self.toolbar.addAction(self.clearButton)

        # layout
        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)
        layout.addWidget(self.toolbar)
        layout.addWidget(self.messages)

        self.setLayout(layout)
        return

    def __handleShowContextMenu(self, coord):
        """ Show the context menu """

        self.__selectAllMenuItem.setEnabled(not self.__isEmpty)
        self.__copyMenuItem.setEnabled(self.__copyAvailable)
        self.__clearMenuItem.setEnabled(not self.__isEmpty)

        self.__menu.popup(QCursor.pos())
        return

    def __appendText(self, txt, isError):
        " Append the text "

        if len(txt) == 0:
            return

        self.__isEmpty = False
        cursor = self.messages.textCursor()
        cursor.movePosition(QTextCursor.End)
        self.messages.setTextCursor(cursor)
        if isError:
            self.messages.setCurrentCharFormat(self.cErrorFormat)
        else:
            self.messages.setCurrentCharFormat(self.cNormalFormat)
        self.messages.insertPlainText(txt)
        self.messages.insertPlainText('\n')
        self.messages.ensureCursorVisible()
        self.__updateToolbarButtons()
        return

    def appendMessage(self, txt):
        " Append the regular message "

        self.__appendText(txt, False)
        #QApplication.processEvents()
        return

    def appendError(self, txt):
        " Append the error message "

        self.__appendText(txt, True)
        #QApplication.processEvents()
        return

    def append(self, txt):
        " Decides what the message is - error or not - and append it then "

        if txt.startswith( 'CRITICAL' ) or \
           txt.startswith( 'ERROR' ) or \
           txt.startswith( 'WARNING' ):
            self.appendError(txt)
        else:
            self.appendMessage(txt)
        return

    def __updateToolbarButtons(self):
        " Contextually updates toolbar buttons "

        self.selectAllButton.setEnabled(not self.__isEmpty)
        self.copyButton.setEnabled(self.__copyAvailable)
        self.clearButton.setEnabled(not self.__isEmpty)
        return

    def __clear(self):
        " Triggers when the clear function is selected "
        self.__isEmpty = True
        self.__copyAvailable = False
        self.messages.clear()
        self.__updateToolbarButtons()
        return

    def __onCopyAvailable(self, isAvailable):
        " Triggers on the copyAvailable signal "
        self.__copyAvailable = isAvailable
        self.__updateToolbarButtons()
        return

    def getText(self):
        " Provides the content as a plain text "
        return self.messages.toPlainText()
示例#29
0
class MigrationWidget(QDialog):
    def __init__(self, parent=None):
        super(MigrationWidget, self).__init__(parent, Qt.WindowStaysOnTopHint)
        self._migration = {}
        vbox = QVBoxLayout(self)
        lbl_title = QLabel(self.tr("Current code:"))
        self.current_list = QListWidget()
        lbl_suggestion = QLabel(self.tr("Suggested changes:"))
        self.suggestion = QPlainTextEdit()
        self.suggestion.setReadOnly(True)

        self.btn_apply = QPushButton(self.tr("Apply change!"))
        hbox = QHBoxLayout()
        hbox.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding))
        hbox.addWidget(self.btn_apply)

        vbox.addWidget(lbl_title)
        vbox.addWidget(self.current_list)
        vbox.addWidget(lbl_suggestion)
        vbox.addWidget(self.suggestion)
        vbox.addLayout(hbox)

        self.connect(self.current_list,
                     SIGNAL("itemClicked(QListWidgetItem*)"),
                     self.load_suggestion)
        self.connect(self.btn_apply, SIGNAL("clicked()"), self.apply_changes)

        IDE.register_service('tab_migration', self)
        ExplorerContainer.register_tab(translations.TR_TAB_MIGRATION, self)

    def install_tab(self):
        ide = IDE.get_service('ide')
        self.connect(ide, SIGNAL("goingDown()"), self.close)

    def apply_changes(self):
        lineno = int(self.current_list.currentItem().data(Qt.UserRole))
        lines = self._migration[lineno][0].split('\n')
        remove = -1
        code = ''
        for line in lines:
            if line.startswith('-'):
                remove += 1
            elif line.startswith('+'):
                code += '%s\n' % line[1:]

        main_container = IDE.get_service('main_container')
        if main_container:
            editorWidget = main_container.get_current_editor()
            block_start = editorWidget.document().findBlockByLineNumber(lineno)
            block_end = editorWidget.document().findBlockByLineNumber(lineno +
                                                                      remove)
            cursor = editorWidget.textCursor()
            cursor.setPosition(block_start.position())
            cursor.setPosition(block_end.position(), QTextCursor.KeepAnchor)
            cursor.movePosition(QTextCursor.EndOfLine, QTextCursor.KeepAnchor)
            cursor.insertText(code[:-1])

    def load_suggestion(self, item):
        lineno = int(item.data(Qt.UserRole))
        lines = self._migration[lineno][0].split('\n')
        code = ''
        for line in lines:
            if line.startswith('+'):
                code += '%s\n' % line[1:]
        self.suggestion.setPlainText(code)
        main_container = IDE.get_service('main_container')
        if main_container:
            editorWidget = main_container.get_current_editor()
            if editorWidget:
                editorWidget.jump_to_line(lineno)
                editorWidget.setFocus()

    def refresh_lists(self, migration):
        self._migration = migration
        self.current_list.clear()
        base_lineno = -1
        for lineno in sorted(migration.keys()):
            linenostr = 'L%s\n' % str(lineno + 1)
            data = migration[lineno]
            lines = data[0].split('\n')
            if base_lineno == data[1]:
                continue
            base_lineno = data[1]
            message = ''
            for line in lines:
                if line.startswith('-'):
                    message += '%s\n' % line
            item = QListWidgetItem(linenostr + message)
            item.setToolTip(linenostr + message)
            item.setData(Qt.UserRole, lineno)
            self.current_list.addItem(item)

    def clear(self):
        """
        Clear the widget
        """
        self.current_list.clear()
        self.suggestion.clear()

    def reject(self):
        if self.parent() is None:
            self.emit(SIGNAL("dockWidget(PyQt_PyObject)"), self)

    def closeEvent(self, event):
        self.emit(SIGNAL("dockWidget(PyQt_PyObject)"), self)
        event.ignore()
示例#30
0
class SkinsTab(QWidget):

    def __init__(self):
        QWidget.__init__(self)
        vbox = QVBoxLayout(self)

        #Top Bar
        hbox = QHBoxLayout()
        self.radioDefault = QRadioButton("Default Skin")
        self.radioCustom = QRadioButton("Custom")
        self.comboSkins = QComboBox()
        self.skins = loader.load_gui_skins()
        for item in self.skins:
            self.comboSkins.addItem(item)
        hbox.addWidget(self.radioDefault)
        hbox.addWidget(self.radioCustom)
        hbox.addWidget(self.comboSkins)
        #Text Area
        self.txtStyle = QPlainTextEdit()
        self.txtStyle.setReadOnly(True)

        #Settings
        settings = QSettings()
        settings.beginGroup('preferences')
        settings.beginGroup('skins')
        if settings.value('default', True).toBool():
            self.radioDefault.setChecked(True)
            self.comboSkins.setEnabled(False)
        else:
            self.radioCustom.setChecked(True)
            index = self.comboSkins.findText(settings.value('selectedSkin', '').toString())
            self.comboSkins.setCurrentIndex(index)
            content = self.skins[str(self.comboSkins.currentText())]
            self.txtStyle.setPlainText(content)
        settings.endGroup()
        settings.endGroup()

        vbox.addLayout(hbox)
        vbox.addWidget(self.txtStyle)
        vbox.addWidget(QLabel('Requires restart the IDE'))

        #Signals
        self.connect(self.radioDefault, SIGNAL("clicked()"), self._default_clicked)
        self.connect(self.radioCustom, SIGNAL("clicked()"), self._custom_clicked)

    def _default_clicked(self):
        self.comboSkins.setEnabled(False)
        self.txtStyle.setPlainText('')

    def _custom_clicked(self):
        self.comboSkins.setEnabled(True)
        content = self.skins[str(self.comboSkins.currentText())]
        self.txtStyle.setPlainText(content)

    def save(self):
        settings = QSettings()
        settings.beginGroup('preferences')
        settings.beginGroup('skins')
        settings.setValue('default', self.radioDefault.isChecked())
        settings.setValue('selectedSkin', self.comboSkins.currentText())
        settings.endGroup()
        settings.endGroup()
示例#31
0
class LogViewer( QWidget ):
    """ The log (+stdout, +stderr) viewer widget """

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

        self.__isEmpty = True
        self.__copyAvailable = False
        self.clearButton = None
        self.messages = None
        self.copyButton = None
        self.selectAllButton = None
        self.__createLayout( parent )

        # create the context menu
        self.__menu = QMenu( self )
        self.__selectAllMenuItem = self.__menu.addAction(
                            PixmapCache().getIcon( 'selectall.png' ),
                            'Select All', self.messages.selectAll )
        self.__copyMenuItem = self.__menu.addAction(
                            PixmapCache().getIcon( 'copytoclipboard.png' ),
                            'Copy', self.messages.copy )
        self.__menu.addSeparator()
        self.__clearMenuItem = self.__menu.addAction(
                            PixmapCache().getIcon( 'trash.png' ),
                            'Clear', self.__clear )

        self.messages.setContextMenuPolicy( Qt.CustomContextMenu )
        self.messages.customContextMenuRequested.connect(
                                                self.__handleShowContextMenu )
        self.messages.copyAvailable.connect( self.__onCopyAvailable )

        self.cNormalFormat = self.messages.currentCharFormat()
        self.cErrorFormat = self.messages.currentCharFormat()
        self.cErrorFormat.setForeground( QBrush( QColor( Qt.red ) ) )
        self.__updateToolbarButtons()
        return

    def __createLayout( self, parent ):
        " Helper to create the viewer layout "

        # Messages list area
        self.messages = QPlainTextEdit( parent )
        self.messages.setLineWrapMode( QPlainTextEdit.NoWrap )
        self.messages.setFont( QFont( GlobalData().skin.baseMonoFontFace ) )
        self.messages.setReadOnly( True )
        self.messages.setMaximumBlockCount( MAX_LINES )

        # Default font size is good enough for most of the systems.
        # 12.0 might be good only in case of the XServer on PC (Xming).
        # self.messages.setFontPointSize( 12.0 )

        # Buttons
        self.selectAllButton = QAction(
            PixmapCache().getIcon( 'selectall.png' ),
            'Select all', self )
        self.selectAllButton.triggered.connect( self.messages.selectAll )
        self.copyButton = QAction(
            PixmapCache().getIcon( 'copytoclipboard.png' ),
            'Copy to clipboard', self )
        self.copyButton.triggered.connect( self.messages.copy )
        spacer = QWidget()
        spacer.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Expanding )
        self.clearButton = QAction(
            PixmapCache().getIcon( 'trash.png' ),
            'Clear all', self )
        self.clearButton.triggered.connect( self.__clear )

        # Toolbar
        self.toolbar = QToolBar()
        self.toolbar.setOrientation( Qt.Vertical )
        self.toolbar.setMovable( False )
        self.toolbar.setAllowedAreas( Qt.LeftToolBarArea )
        self.toolbar.setIconSize( QSize( 16, 16 ) )
        self.toolbar.setFixedWidth( 28 )
        self.toolbar.setContentsMargins( 0, 0, 0, 0 )
        self.toolbar.addAction( self.selectAllButton )
        self.toolbar.addAction( self.copyButton )
        self.toolbar.addWidget( spacer )
        self.toolbar.addAction( self.clearButton )

        # layout
        layout = QHBoxLayout()
        layout.setContentsMargins( 0, 0, 0, 0 )
        layout.setSpacing( 0 )
        layout.addWidget( self.toolbar )
        layout.addWidget( self.messages )

        self.setLayout( layout )
        return

    def __handleShowContextMenu( self, coord ):
        """ Show the context menu """

        self.__selectAllMenuItem.setEnabled( not self.__isEmpty )
        self.__copyMenuItem.setEnabled( self.__copyAvailable )
        self.__clearMenuItem.setEnabled( not self.__isEmpty )

        self.__menu.popup( QCursor.pos() )
        return

    def __appendText( self, txt, isError ):
        " Append the text "

        if len( txt ) == 0:
            return

        self.__isEmpty = False
        cursor = self.messages.textCursor()
        cursor.movePosition( QTextCursor.End )
        self.messages.setTextCursor( cursor )
        if isError:
            self.messages.setCurrentCharFormat( self.cErrorFormat )
        else:
            self.messages.setCurrentCharFormat( self.cNormalFormat )
        self.messages.insertPlainText( txt )
        self.messages.insertPlainText( '\n' )
        self.messages.ensureCursorVisible()
        self.__updateToolbarButtons()
        return

    def appendMessage( self, txt ):
        " Append the regular message "

        self.__appendText( txt, False )
        #QApplication.processEvents()
        return

    def appendError( self, txt ):
        " Append the error message "

        self.__appendText( txt, True )
        #QApplication.processEvents()
        return

    def append( self, txt ):
        " Decides what the message is - error or not - and append it then "

        if txt.startswith( 'CRITICAL' ) or \
           txt.startswith( 'ERROR' ) or \
           txt.startswith( 'WARNING' ):
            self.appendError( txt )
        else:
            self.appendMessage( txt )
        return

    def __updateToolbarButtons( self ):
        " Contextually updates toolbar buttons "

        self.selectAllButton.setEnabled( not self.__isEmpty )
        self.copyButton.setEnabled( self.__copyAvailable )
        self.clearButton.setEnabled( not self.__isEmpty )
        return

    def __clear( self ):
        " Triggers when the clear function is selected "
        self.__isEmpty = True
        self.__copyAvailable = False
        self.messages.clear()
        self.__updateToolbarButtons()
        return

    def __onCopyAvailable( self, isAvailable ):
        " Triggers on the copyAvailable signal "
        self.__copyAvailable = isAvailable
        self.__updateToolbarButtons()
        return

    def getText( self ):
        " Provides the content as a plain text "
        return self.messages.toPlainText()
示例#32
0
class MigrationWidget(QDialog):

    def __init__(self, parent=None):
        super(MigrationWidget, self).__init__(parent, Qt.WindowStaysOnTopHint)
        self._migration = {}
        vbox = QVBoxLayout(self)
        lbl_title = QLabel(self.tr("Current code:"))
        self.current_list = QListWidget()
        lbl_suggestion = QLabel(self.tr("Suggested changes:"))
        self.suggestion = QPlainTextEdit()
        self.suggestion.setReadOnly(True)

        self.btn_apply = QPushButton(self.tr("Apply change!"))
        hbox = QHBoxLayout()
        hbox.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding))
        hbox.addWidget(self.btn_apply)

        vbox.addWidget(lbl_title)
        vbox.addWidget(self.current_list)
        vbox.addWidget(lbl_suggestion)
        vbox.addWidget(self.suggestion)
        vbox.addLayout(hbox)

        self.connect(self.current_list,
            SIGNAL("itemClicked(QListWidgetItem*)"), self.load_suggestion)
        self.connect(self.btn_apply, SIGNAL("clicked()"), self.apply_changes)

        IDE.register_service('tab_migration', self)
        ExplorerContainer.register_tab(translations.TR_TAB_MIGRATION, self)

    def install_tab(self):
        ide = IDE.get_service('ide')
        self.connect(ide, SIGNAL("goingDown()"), self.close)

    def apply_changes(self):
        lineno = int(self.current_list.currentItem().data(Qt.UserRole))
        lines = self._migration[lineno][0].split('\n')
        remove = -1
        code = ''
        for line in lines:
            if line.startswith('-'):
                remove += 1
            elif line.startswith('+'):
                code += '%s\n' % line[1:]

        main_container = IDE.get_service('main_container')
        if main_container:
            editorWidget = main_container.get_current_editor()
            block_start = editorWidget.document().findBlockByLineNumber(lineno)
            block_end = editorWidget.document().findBlockByLineNumber(
                lineno + remove)
            cursor = editorWidget.textCursor()
            cursor.setPosition(block_start.position())
            cursor.setPosition(block_end.position(), QTextCursor.KeepAnchor)
            cursor.movePosition(QTextCursor.EndOfLine, QTextCursor.KeepAnchor)
            cursor.insertText(code[:-1])

    def load_suggestion(self, item):
        lineno = int(item.data(Qt.UserRole))
        lines = self._migration[lineno][0].split('\n')
        code = ''
        for line in lines:
            if line.startswith('+'):
                code += '%s\n' % line[1:]
        self.suggestion.setPlainText(code)
        main_container = IDE.get_service('main_container')
        if main_container:
            editorWidget = main_container.get_current_editor()
            if editorWidget:
                editorWidget.jump_to_line(lineno)
                editorWidget.setFocus()

    def refresh_lists(self, migration):
        self._migration = migration
        self.current_list.clear()
        base_lineno = -1
        for lineno in sorted(migration.keys()):
            linenostr = 'L%s\n' % str(lineno + 1)
            data = migration[lineno]
            lines = data[0].split('\n')
            if base_lineno == data[1]:
                continue
            base_lineno = data[1]
            message = ''
            for line in lines:
                if line.startswith('-'):
                    message += '%s\n' % line
            item = QListWidgetItem(linenostr + message)
            item.setToolTip(linenostr + message)
            item.setData(Qt.UserRole, lineno)
            self.current_list.addItem(item)

    def clear(self):
        """
        Clear the widget
        """
        self.current_list.clear()
        self.suggestion.clear()

    def reject(self):
        if self.parent() is None:
            self.emit(SIGNAL("dockWidget(PyQt_PyObject)"), self)

    def closeEvent(self, event):
        self.emit(SIGNAL("dockWidget(PyQt_PyObject)"), self)
        event.ignore()
示例#33
0
class MainWindow(pMainWindow):
    def __init__(self, parentWidget=None):
        pMainWindow.__init__(self, parentWidget)
        self.createGui()

    def saveState(self):
        pMainWindow.saveState(self)
        
        self.settings().setValue( "MainWindow/Style",
                                  self.agStyles.currentStyle() )
        
        evm = pEnvironmentVariablesManager()
        evm.setVariables( self.eveVariables.variables() )
        evm.save()
        
        self.settings().setValue("UpdateChecker/Last Updated" ,
                                  self.ucMkS.lastUpdated())
        self.settings().setValue("UpdateChecker/Last Checked" ,
                                  self.ucMkS.lastChecked())

    def restoreState(self):
        pMainWindow.restoreState(self)
        
        self.agStyles.setCurrentStyle(
                        self.settings().value( "MainWindow/Style" ).toString() )
        
        variables = []
        evm = pEnvironmentVariablesManager()
        evm.load()
        variables = evm.variables()
        evm.mergeNewVariables( variables )
        
        self.eveVariables.setVariables( variables, True )
        
        self.ucMkS.setLastUpdated( 
            self.settings().value( "UpdateChecker/Last Updated" ).toDateTime() )
        self.ucMkS.setLastChecked( 
            self.settings().value( "UpdateChecker/Last Checked" ).toDateTime() )

    def createGui(self):
        pNetworkAccessManager.instance().setCacheDirectory(
            qApp.applicationDirPath().append( "/tmp" ) )
        
        self.twPages = QTabWidget( self )
        self.setCentralWidget( self.twPages )
        
        # initialize gui
        self.createMenuBar()
        self.createPlainTextEdit()
        self.createActionsTreeView()
        self.createConsole()
        self.createVersionsTests()
        self.createListEditors()
        self.createEnvironmentVariablesEditor()
        self.createCustomWidgets()
        self.createUpdateChecker()
        
        QTimer.singleShot( 3000, self.ucMkS.silentCheck )
        
        # create fake dock widget for testing
        '''for ( i = 0; i < 10; i++ )        dw = QDockWidget( self )
            dw.setObjectName( QString( "Dock%1" ).arg( i ) )
            dw.toggleViewAction().setObjectName( 
                        QString( "DockViewAction%1" ).arg( i ) )
            self.dockToolBar( Qt.LeftToolBarArea ).addDockWidget( 
                    dw, QString( "Dock %1" ).arg( i ), 
        QIcon( scaledPixmap( 
            ":/fresh/country-flags/ad.png", QSize( 96, 96 ) ) ) )
        }'''
        
        # list dock widgets in the menu
        for dockWidget in self.findChildren(QDockWidget):
            #dockWidget.setAttribute( Qt.WA_DeleteOnClose )
            action = dockWidget.toggleViewAction()
            self.mActionsModel.addAction( "mView/mDockWidgets/%s" % \
                        action.objectName() , action )
            self.mActionsModel.setDefaultShortcut(action, 
                QKeySequence( "Ctrl+%s" % chr( max( 32, qrand() % 127 ) ) ) )

    def createMenuBar(self):
        # set menu bar model
        self.mActionsModel = pActionsModel( self )
        self.menuBar().setModel( self.mActionsModel )
        
        # create menus and sub menus
        self.mActionsModel.addMenu( "mFile", self.tr( "&File" ) )
        self.mActionsModel.addMenu( "mEdit", self.tr( "&Edit" ) )
        self.mActionsModel.addMenu( "mView", self.tr( "&View" ) )
        self.mActionsModel.addMenu( "mView/mStyle", self.tr( "&Style" ) )
        self.mActionsModel.addMenu( "mView/mMode", self.tr( "&Mode" ) )
        self.mActionsModel.addMenu( "mView/mDockToolBarManager", self.tr( "&Dock ToolBar Manager" ) )
        self.mActionsModel.addMenu( "mView/mDockWidgets", self.tr( "Dock &Widgets" ) )
        
        # create actions
        aQuit = self.mActionsModel.addAction( "mFile/aQuit", self.tr( "&Quit" ) )
        
        aClassic = self.mActionsModel.addAction(
                        "mView/mMode/aShowClassic", self.tr( "Classic" ) )
        aClassic.setCheckable( True )
        
        aModern = self.mActionsModel.addAction(
                        "mView/mMode/aShowModern", self.tr( "Modern" ) )
        aModern.setCheckable( True )
        
        # style actions
        self.agStyles = pStylesActionGroup( self )
        self.agStyles.installInMenuBar( self.menuBar(), "mView/mStyle" )
        
        # action group
        agDockToolBarManagerMode = QActionGroup( self )
        agDockToolBarManagerMode.addAction( aClassic )
        agDockToolBarManagerMode.addAction( aModern )
        
        # add dock toolbar manager actions
        for dockToolBar in self.dockToolBarManager().dockToolBars():
            action = dockToolBar.toggleViewAction()
            self.mActionsModel.addAction(
                "mView/mDockToolBarManager/%s" % action.objectName() , action )
            
            action = dockToolBar.toggleExclusiveAction()
            self.mActionsModel.addAction(
                "mView/mDockToolBarManager/%s" % action.objectName(), action )
        
        # connections
        aQuit.triggered.connect(self.close)
        self.agStyles.styleSelected.connect(self.setCurrentStyle)
        self.dockToolBarManager().modeChanged.connect(
                            self.dockToolBarManagerModeChanged)
        aClassic.triggered.connect(self.dockToolBarManagerClassic)
        aModern.triggered.connect(self.dockToolBarManagerModern)

    def createPlainTextEdit(self):
        self.pteLog = QPlainTextEdit( self )
        self.pteLog.setReadOnly( True )
        self.pteLog.setTabStopWidth( 40 )
        self.twPages.addTab( self.pteLog, self.tr( "Log" ) )

    def createActionsTreeView(self):
        self.tvActions = QTreeView( self )
        self.tvActions.setModel( self.menuBar().model() )
        
        self.mActionsModel.addMenu( "mEdit/mActions", self.tr( "&Actions" ) )
        
        aAddAction = self.mActionsModel.addAction( "mEdit/mActions/aAddAction",
                                           self.tr( "&Add action" ) )
        aRemoveAction = self.mActionsModel.addAction( "mEdit/mActions/aRemoveAction",
                                        self.tr( "&Remove selected action" ) )
        aEditTextNode = self.mActionsModel.addAction( "mEdit/mActions/aEditTextNode",
                                        self.tr( "&Edit selected node text" ) )
        aEditShortcuts = self.mActionsModel.addAction( "mEdit/mActions/aEditShortcuts",
                                    self.tr( "Edit the actions &shortcuts" ) )
        
        aAddAction.triggered.connect(self.aAddAction_triggered)
        aRemoveAction.triggered.connect(self.aRemoveAction_triggered)
        aEditTextNode.triggered.connect(self.aEditTextNode_triggered)
        aEditShortcuts.triggered.connect(self.aEditShortcuts_triggered)
        
        self.twPages.addTab( self.tvActions, self.tr( "Actions" ) )

    def createConsole(self):
        cShell = pConsole( "Shell:/> ", self )
        self.commands = ConsoleCommands( self, self )
        cShell.addAvailableCommand( self.commands )
        
        self.dwShell = pDockWidget( self )
        self.dwShell.setObjectName( "Shell" )
        self.dwShell.setWidget( cShell )
        self.dwShell.toggleViewAction().setObjectName( "ShellViewAction" )
        self.dockToolBar( Qt.BottomToolBarArea ).addDockWidget(
               self.dwShell, 
               self.tr( "Shell" ),
               QIcon(pGuiUtils.scaledPixmap( ":/fresh/country-flags/ro.png",
                      QSize( 96, 96 ) ) ) )

    def createEnvironmentVariablesEditor(self):
        self.eveVariables = pEnvironmentVariablesEditor( self )
        
        self.dwEnvironmentVariablesEditor = pDockWidget( self )
        self.dwEnvironmentVariablesEditor.setObjectName(
                                        "EnvironmentVariablesEditor" )
        self.dwEnvironmentVariablesEditor.setWidget( self.eveVariables )
        self.dwEnvironmentVariablesEditor.toggleViewAction().setObjectName(
                                    "EnvironmentVariablesEditorViewAction" )
        self.dockToolBar( Qt.TopToolBarArea ).addDockWidget(
            self.dwEnvironmentVariablesEditor,
            self.tr( "Environment Variables Editor" ),
            QIcon( pGuiUtils.scaledPixmap(":/fresh/country-flags/it.png",
                                              QSize( 96, 96 ) ) ) )

    def createVersionsTests(self):
        v1 = pVersion ( "1.5.4" )
        v2 = pVersion ( "1.5.4a" )
        
        self.pteLog.appendPlainText( 
            self.tr( "Testing versions %s & %s:\n" % 
                    (v1.toString(), v2.toString() ) ))
        
        # test 1
        test1 = ''
        for op in [">", "<", ">=", "<=", "==", "!="]:
            test1 += '%s\t%s\t%s: %s\n' % \
                (v1.toString(),
                op,
                v2.toString(),
                str(bool(eval("v1 %s v2" % op))))
            
        # test 2
        test2 = ''
        for op in [">", "<", ">=", "<=", "==", "!="]:
            test2 += '%s\t%s\t%s: %s\n' % \
                     (v1.toString(),
                     op,
                     v1.toString(),
                     str(bool(eval("v1 %s v1" % op))))
        
        self.pteLog.appendPlainText( self.tr( "Test 1:\n%s\n" % test1 ))
        self.pteLog.appendPlainText( self.tr( "Test 2:\n%s" % test2 ))

    def createListEditors(self):
        # list editor dock
        self.dwListEditor = pDockWidget( self )
        twListEditors = QTabWidget( self.dwListEditor )
        self.dwListEditor.setObjectName( "DockListEditor" )
        self.dwListEditor.setWidget( twListEditors )
        self.dwListEditor.toggleViewAction().setObjectName(
                "DockListEditorViewAction" )
        self.dockToolBar( Qt.RightToolBarArea ).addDockWidget(
              self.dwListEditor,
              self.tr( "List Editor" ),
              QIcon(pGuiUtils.scaledPixmap( ":/fresh/country-flags/fr.png", 
                                                QSize( 96, 96 ))))
        
        twListEditors.addTab( 
              pStringListEditor( '', self ), self.tr( "Edit strings" ) )
        twListEditors.addTab(
              pPathListEditor( '', ".", self ), self.tr( "Edit paths" ) )
        twListEditors.addTab(
              pFileListEditor('', ".", "*.png", self ), self.tr( "Edit files" ))

    def createCustomWidgets(self):
        self.dwWidgets = pDockWidget( self )
        self.dwWidgets.setObjectName( "dwWidgets" )
        self.dwWidgets.toggleViewAction().setObjectName( "dwWidgetsViewAction" )
        self.dockToolBar( Qt.LeftToolBarArea ).addDockWidget(
              self.dwWidgets,
              self.tr( "Custom Widgets" ),
              QIcon( pGuiUtils.scaledPixmap( ":/fresh/country-flags/es.png",
              QSize( 96, 96 ) ) ) )
        
        self.dwWidgetsContents = QWidget( self )
        self.dwWidgetsContentsLayout = QGridLayout( self.dwWidgetsContents )
        self.dwWidgets.setWidget( self.dwWidgetsContents )
        
        pbOpenFile = QPushButton( self.tr( "Get open file names" ), self )
        self.dwWidgetsContentsLayout.addWidget( pbOpenFile, 0, 0 )
        pbOpenFile.clicked.connect(self.openFileDialog)
        
        pbOpenDirectory = QPushButton( self.tr( "Get open directory name" ),
                                       self )
        self.dwWidgetsContentsLayout.addWidget( pbOpenDirectory, 1, 0 )
        pbOpenDirectory.clicked.connect(self.openDirectoryDialog)
        
        pbQueuedMessage = QPushButton( self.tr( "Add queued message" ) )
        self.dwWidgetsContentsLayout.addWidget( pbQueuedMessage, 2, 0 )
        pbQueuedMessage.clicked.connect(self.addQueuedMessage)
        
        stylesButton = pStylesToolButton( self.dwWidgetsContents )
        stylesButton.setSizePolicy( pbQueuedMessage.sizePolicy() )
        stylesButton.setCheckableActions( False )
        self.dwWidgetsContentsLayout.addWidget( stylesButton, 3, 0 )
        stylesButton.styleSelected.connect(self.agStyles.setCurrentStyle)
        
        tcbActions = pTreeComboBox( self )
        tcbActions.setModel( self.mActionsModel )
        self.dwWidgetsContentsLayout.addWidget( tcbActions, 4, 0 )
        
        paypal = pPaypalButton( self )
        paypal.setBusinessId( "5R924WYXJ6BAW" )
        paypal.setItemName( "QWBFS Manager" )
        paypal.setItemId( "QWBFS-DONATION" )
        paypal.setCurrencyCode( "EUR" )
        self.dwWidgetsContentsLayout.addWidget( paypal, 5, 0 )
        
        toolButton1 = pToolButton( self.dwWidgetsContents )
        toolButton1.setToolButtonStyle( Qt.ToolButtonTextBesideIcon )
        toolButton1.setText( self.tr( "Bottom To Top" ) )
        toolButton1.setIcon( pIconManager.icon( "pt.png") )
        toolButton1.setDirection( QBoxLayout.BottomToTop )
        self.dwWidgetsContentsLayout.addWidget( toolButton1, 0, 1, 6, 1 )
        
        toolButton2 = pToolButton( self.dwWidgetsContents )
        toolButton2.setToolButtonStyle( Qt.ToolButtonTextBesideIcon )
        toolButton2.setText( self.tr( "Top To Bottom" ) )
        toolButton2.setIcon( pIconManager.icon( "br.png" ) )
        toolButton2.setDirection( QBoxLayout.TopToBottom )
        self.dwWidgetsContentsLayout.addWidget( toolButton2, 0, 2, 6, 1 )
        
        colorButton = pColorButton( self.dwWidgetsContents )
        self.dwWidgetsContentsLayout.addWidget( colorButton, 6, 0 )

    def createUpdateChecker(self):
        self.ucMkS = pUpdateChecker( self )
        self.ucMkS.setDownloadsFeedUrl( 
            QUrl("http:#code.google.com/feeds/p/monkeystudio/downloads/basic" ))
        self.ucMkS.setVersion( "1.6.0.0" )
        self.ucMkS.setVersionString( "1.6.0.0" )
        self.ucMkS.setVersionDiscoveryPattern( ".*mks_([0-9\\.]+).*" )
        
        self.mActionsModel.addMenu( "mHelp", self.tr( "&Help" ) )
        self.mActionsModel.addAction( "mHelp/aUpdateChecker", self.ucMkS.menuAction() )

    def aAddAction_triggered(self):
        index = self.tvActions.selectionModel().selectedIndexes()[0]
        path = ''
        
        if index.isValid():
            action = mActionsModel.action( index );   
            
            if action.menu():
                path = mActionsModel.path(action).split('/')[:-2]
            else:
                path = mActionsModel.path()
        
        if path:
            path += '/'
        
        path = QInputDialog.getText( 
                self,
                '',
                self.tr( "Enter the full path where to add " +
                         "the action (/some/path/to/add/the/actionName):" ),
                QLineEdit.Normal,
                path )
        
        if not "/" in path or path.replace("/", '').trim().isEmpty():
            return
        
        action = QAction( self )
        action.setText(path.split('/')[-1])
        
        if  not self.mActionsModel.addAction( path, action ) :
            del action
            QMessageBox.information(
                                self,
                                '',
                                self.tr( "Can't add action to '%s' % path" ))

    def aRemoveAction_triggered(self):
        index = self.tvActions.selectionModel().selectedIndexes()[0]
        
        if  index.isValid():
            node = self.mActionsModel.indexToNode( index )
            
            if not self.mActionsModel.removeAction( node.path() ):
                QMessageBox.information( self,
                                         '',
                                         self.tr( "Can't remove action '%s'" % 
                                                  node.path() ) )

    def aEditTextNode_triggered(self):
        index = self.tvActions.selectionModel().selectedIndexes()[0]
        
        if index.isValid():
            node = self.mActionsModel.indexToNode( index )
            text = QInputDialog.getText( self,
                                         '',
                                         self.tr( "Enter the node text:" ),
                                         QLineEdit.Normal,
                                         node.text())
            
            if text:
                node.setText( text )

    def aEditShortcuts_triggered(self):
        dlg = pActionsShortcutEditor ( self.mActionsModel, self )
        dlg.exec_()

    def dockToolBarManagerModeChanged(self, mode ):
        if mode == pDockToolBarManager.Classic:
            self.mActionsModel.action( "mView/mMode/aShowClassic" ).trigger()
        elif mode == pDockToolBarManager.Modern:
            self.mActionsModel.action( "mView/mMode/aShowModern" ).trigger()
        else:
            assert(0)

    def dockToolBarManagerClassic(self):
        self.dockToolBarManager().setMode( pDockToolBarManager.Classic )

    def dockToolBarManagerModern(self):
        self.dockToolBarManager().setMode( pDockToolBarManager.Modern )

    def addQueuedMessage(self):
        ok, message = QInputDialog.getText( 
                                    self,
                                    self.tr( "Add a queued message" ),
                                    self.tr( "Enter the message to show:" ),
                                    QLineEdit.Normal,
                                    self.tr( "This is the default message" ))
        
        if  ok and message:
            msg = pQueuedMessage()
            msg.message = message
            msg.buttons[ QDialogButtonBox.Ok ] = ''
            msg.buttons[ QDialogButtonBox.Yes ] = self.tr( "Show QMessageBox" )
            msg.object = self
            msg.slot = "queuedMessageToolBarButtonClicked"
            
            queuedMessageToolBar().appendMessage( msg )

    def queuedMessageToolBarButtonClicked(self, button, message ):
        if button == QDialogButtonBox.Yes:
            QMessageBox.information( self, '', message.message )

    def setCurrentStyle(self, style ):
        QApplication.setStyle( style )

    def openFileDialog(self):
        caption = ''
        dir = ''
        filter = ''
        enabledTextCodec = True
        enabledOpenReadOnly = True
        selectedFilter = ''
        options = 0
        result = pFileDialog.getOpenFileNames(self, caption, dir,
                                              filter, enabledTextCodec,
                                              enabledOpenReadOnly,
                                              selectedFilter, options)
        
        self.pteLog.appendPlainText( '' )
        
        if result.isEmpty():
            self.pteLog.appendPlainText(
                    self.tr( "You canceled the open file dialog" ) )
        else:
            texts = []
            
            texts.append(self.tr( "You accepted the open file dialog" ))
            
            for type in result.keys():
                if type == pFileDialog.TextCodec:
                    texts.append(
                      self.tr( "TextCodec: %s" % result[ type ].toString() ))
                elif type == pFileDialog.OpenReadOnly:
                    texts.append(
                      self.tr( "OpenReadOnly: %s" % result[ type ].toString() ))
                elif type == pFileDialog.Directory:
                    texts.append(
                      self.tr( "Directory: %s" % result[ type ].toString() ))
                elif type == pFileDialog.FileName:
                    texts.append(
                      self.tr( "FileName: %s" % result[ type ].toString() ))
                elif type == pFileDialog.FileNames:
                    texts.append(
                      self.tr( "FileNames: %s" % 
                                ", ".join(result[ type ].toStringList())))
                elif type == pFileDialog.SelectedFilter:
                    texts.append(
                    self.tr( "SelectedFilter: %s" % result[ type ].toString() ))
            
            self.pteLog.appendPlainText( '\n'.join(texts))

    def openDirectoryDialog(self):
        caption = ''
        dir = ''
        filter = ''
        enabledTextCodec = True
        enabledOpenReadOnly = True
        selectedFilter = ''
        options = 0
        result = pFileDialog.getExistingDirectory( 
                                        self, caption, dir, 
                                        enabledTextCodec, 
                                        enabledOpenReadOnly,
                                        options | QFileDialog.ShowDirsOnly )
        
        self.pteLog.appendPlainText( '' )
        
        if not result:
            self.pteLog.appendPlainText(
                        self.tr( "You canceled the open directory dialog" ) )
        else:
            texts = []
            
            texts.append(self.tr( "You accepted the open directory dialog" ))
            
            for type in result.keys():
                if type == pFileDialog.TextCodec:
                    texts.append(
                        self.tr( "TextCodec: %s" % result[ type ].toString() ))
                elif type == pFileDialog.OpenReadOnly:
                    texts.append(
                        self.tr("OpenReadOnly: %s" % result[ type ].toString()))
                elif type == pFileDialog.Directory:
                    texts.append(
                        self.tr( "Directory: %s" % result[ type ].toString() ))
                elif type == pFileDialog.FileName:
                    texts.append(
                        self.tr( "FileName: %s" % result[ type ].toString() ))
                elif type == pFileDialog.FileNames:
                    texts.append(
                        self.tr( "FileNames: %s" % 
                                  ", ".join(result[ type ].toStringList())))
                elif type == pFileDialog.SelectedFilter:
                    texts.append(self.tr( "SelectedFilter: %s" % 
                                 result[ type ].toString() ))
            
            self.pteLog.appendPlainText( '\n'.join(texts))
示例#34
0
class BluetoothWindow(QMainWindow):

    def __init__(self, inbuf, outbuf,parent=None):

        super(BluetoothWindow, self).__init__(parent)

        self.sendbuf=outbuf
        self.receivebuf=inbuf
        
        self.output=QPlainTextEdit()

        self.output.setReadOnly(True)
        self.output.setLineWrapMode(QPlainTextEdit.WidgetWidth)
        
        self.hor = QHBoxLayout()
        self.ver = QVBoxLayout()
        
        def updateValue(key, value):
            pidvalues[key] = float(value)
            print key, "updated to", value
        
        for k, v in pidvalues.iteritems():
            label = QLabel(k)
            edit = QLineEdit(str(v))
            button = QPushButton("Update")
            l = QHBoxLayout()
            l.addWidget(label, 2)
            l.addWidget(edit, 5)
            l.addWidget(button, 2)
            self.ver.addLayout(l)   
            button.clicked.connect(lambda clicked, label=label, edit=edit: updateValue(label.text(), edit.text()))        
        
        self.hor.addWidget(self.output)
        self.hor.addLayout(self.ver)
        
        w = QWidget()
        w.setLayout(self.hor)
        self.setCentralWidget(w)
        
        SampleTimeInSec = (pidvalues["PID_SAMPLE_TIME"]) / 1000.0
        
        for i in range(4):
          pid_params.append(pid_params_typedef())
        
        pid_params[pidvalues["PID_THROTTLE"]].kp = pidvalues["KP_THROTTLE"];
        pid_params[pidvalues["PID_THROTTLE"]].ki = pidvalues["KI_THROTTLE"] * SampleTimeInSec;
        pid_params[pidvalues["PID_THROTTLE"]].kd = pidvalues["KD_THROTTLE"] / SampleTimeInSec;
        pid_params[pidvalues["PID_THROTTLE"]].min = pidvalues["MIN_THROTTLE"];
        pid_params[pidvalues["PID_THROTTLE"]].max = pidvalues["MAX_THROTTLE"];

        pid_params[pidvalues["PID_PITCH"]].kp = pidvalues["KP_PITCH"];
        pid_params[pidvalues["PID_PITCH"]].ki = pidvalues["KI_PITCH"] * SampleTimeInSec; 
        pid_params[pidvalues["PID_PITCH"]].kd = pidvalues["KD_PITCH"] / SampleTimeInSec;
        pid_params[pidvalues["PID_PITCH"]].min = pidvalues["MIN_PITCH"];
        pid_params[pidvalues["PID_PITCH"]].max = pidvalues["MAX_PITCH"];

        pid_params[pidvalues["PID_ROLL"]].kp = pidvalues["KP_ROLL"];
        pid_params[pidvalues["PID_ROLL"]].ki = pidvalues["KI_ROLL"] * SampleTimeInSec;
        pid_params[pidvalues["PID_ROLL"]].kd = pidvalues["KD_ROLL"] / SampleTimeInSec;
        pid_params[pidvalues["PID_ROLL"]].min = pidvalues["MIN_ROLL"];
        pid_params[pidvalues["PID_ROLL"]].max = pidvalues["MAX_ROLL"];
        
        pid_params[pidvalues["PID_YAW"]].kp = pidvalues["KP_YAW"];
        pid_params[pidvalues["PID_YAW"]].ki = pidvalues["KI_YAW"] * SampleTimeInSec;
        pid_params[pidvalues["PID_YAW"]].kd = pidvalues["KD_YAW"] / SampleTimeInSec;
        pid_params[pidvalues["PID_YAW"]].min = pidvalues["MIN_YAW"];
        pid_params[pidvalues["PID_YAW"]].max = pidvalues["MAX_YAW"];

        for i in pid_params:
           print i              
 
    def receiveText(self):
          
#        | 2-5   | Roll    | [-pi, pi]   |
#        | 6-9   | Pitch   | [-pi, pi]   |
#        | 10-13 | Yaw     | [-pi, pi]   |
#        | 14-17 | Height  | [0, 10m]  |
#        | 18-21 | Battery | [0, 100%] |
        
        rolldata=""
        pitchdata=""
        yawdata=""
        heightdata=""
        batterydata=""
        
        for i in range(4):
            rolldata+=self.receivebuf.pop(0)
        
        for i in range(4):
            pitchdata+=self.receivebuf.pop(0)
        
        for i in range(4):
            yawdata+=self.receivebuf.pop(0)
        
        for i in range(4):
            heightdata+=self.receivebuf.pop(0)
        
        for i in range(4):
            batterydata+=self.receivebuf.pop(0)
        
        roll=struct.unpack('f', rolldata)
        pitch=struct.unpack('f', pitchdata)
        yaw=struct.unpack('f', yawdata)
        
        self.output.appendPlainText("p "+str(pitch[0])+", r "+str(roll[0])+", y "+str(yaw[0]))
        
        ## pids 
        data.pitch = pitch[0]
        data.roll = roll[0]
        data.yaw = yaw[0]
                
        global lastThrottle
                
        pid_output.throttle = self.pid_compute(pidvalues["PID_THROTTLE"], lastThrottle, command.throttle);
        pid_output.pitch = self.pid_compute(pidvalues["PID_PITCH"], data.pitch, command.pitch);
        pid_output.roll = self.pid_compute(pidvalues["PID_ROLL"], data.roll, command.roll);
        pid_output.yaw = self.pid_compute(pidvalues["PID_YAW"], data.yaw, command.yaw);
        
        #Save last throttle value
        lastThrottle = pid_output.throttle * 2 * ( pidvalues["MAX_THROTTLE"] / MOTOR_SPEED_MAX) - pidvalues["MIN_THROTTLE"];
    

        #Add offset to throttle
        pid_output.throttle += MOTOR_SPEED_HALF;
        
        self.motors_pid_apply()
                
        ## update gui
        self.repaint()   

    def motor_name(self, motor):
        if (motor == MOTOR_RIGHT_BACK):
            return "RIGHT__BACK"
        elif (motor == MOTOR_LEFT_BACK):
            return "LEFT___BACK"
        elif (motor == MOTOR_RIGHT_FRONT):
            return "RIGHT_FRONT"
        elif (motor == MOTOR_LEFT_FRONT):
            return "LEFT__FRONT"
        else:
            return "UNKNOWN"

    def motors_set_speed(self, motor, value):
        self.output.appendPlainText("motor "+str(self.motor_name(motor))+", value "+str(int(value)))
        

    def motors_pid_apply(self):
      self.motors_set_speed(MOTOR_RIGHT_FRONT, pid_output.throttle - pid_output.pitch - pid_output.roll - pid_output.yaw);
      self.motors_set_speed(MOTOR_LEFT_FRONT, pid_output.throttle - pid_output.pitch + pid_output.roll + pid_output.yaw);
      self.motors_set_speed(MOTOR_RIGHT_BACK, pid_output.throttle + pid_output.pitch - pid_output.roll + pid_output.yaw);
      self.motors_set_speed(MOTOR_LEFT_BACK, pid_output.throttle + pid_output.pitch + pid_output.roll - pid_output.yaw);
                
                
    def pid_compute(self, index, input, setpoint):
     
      pid = pid_params[index]
      retVal = 0

      #Compute all the working error variables*/
      error = setpoint - input;
      pid.iterm += pid.ki * error;
      if (pid.iterm > pid.max) :
        pid.iterm = pid.max;
      else:
        if (pid.iterm < pid.min):
          pid.iterm = pid.min;
          
      dInput = (input - pid.lastInput);

      #Compute PID Output*/
      retVal = (pid.kp * error + pid.iterm - pid.kd * dInput);
      if (retVal > pid.max):
        retVal = pid.max;
      else:
         if (retVal < pid.min):
           retVal = pid.min;

      #Remember some variables for next time*/
      pid.lastInput = input;
      pid_params[index] = pid
      return retVal        
      
    def reset(self):
        self.output.clear()
示例#35
0
class StripWidget(QWidget):
    timer_timeout = 100

    def __init__(self, device,speed=115200,timeout=1,debug=True):
        super(StripWidget,self).__init__()
        self.device  = device
        self.speed   = speed
        self.timeout = timeout
        self.strip       = Strip()
        self.strip.debug = debug
        self.initGUI()
        self.setInputState(False)
        self.setMinimumSize( 600, 400)
        self.timer = None
        QTimer.singleShot( 500, self.initSerial)
        
    def closeEvent(self,e):
        e.accept()
        self.closeSerial()
            
    def initSerial(self):
        if self.strip.isConnected():
            return
        if not self.device:
            self.device = self.strip.findDevice()
        if not self.device:
            self.printLog("No device found")
            return
        self.printLog("Opening '%s'" % self.device)
        if not self.strip.connect(self.device, self.speed, self.timeout):
            sys.exit(1)
        self.printLog("Opened  '%s' with speed %i" %
                      (self.device, self.strip.baudrate()))
        
        retries = 10
        while retries > 0:
            if self.strip.pingDevice():
                break
            retries -= 1
            QApplication.processEvents()
            time.sleep(1)
        else:
            print "Error connecting to device"
            sys.exit(1)
        self.printLog("Device is READY")
        self.setInputState(True)
        self.timer = self.startTimer(self.timer_timeout)
        self.updateConfig(True)
        
    def closeSerial(self):
        if self.strip.isConnected():
            self.setInputState(False)
            if self.timer:
                self.killTimer(self.timer)
            self.printLog("Disconnecting")
            self.strip.disconnect()
    
    def reconnect(self):
        self.closeSerial()
        self.initSerial()
        
    def printLog(self, s):
        if not s.endswith("\n"): s+="\n"
        self.log.moveCursor( QTextCursor.End)
        self.log.insertPlainText(s)
        self.log.moveCursor( QTextCursor.End)
        self.log.ensureCursorVisible()
    
    def initGUI(self):
        self.inputs = []
        layout = QHBoxLayout()
        
        textLayout = QVBoxLayout()
        self.log = QPlainTextEdit()
        f = QFont("Monospace")
        f.setStyleHint(QFont.TypeWriter)
        self.log.setFont(f)
        self.log.setReadOnly(True)
        textLayout.addWidget( self.log)
        self.input = QLineEdit()
        self.input.returnPressed.connect(self.sendSerial)
        self.setFocusProxy( self.input)
        textLayout.addWidget(self.input)
        self.inputs += [self.input]
        layout.addLayout( textLayout)
 
        buttonLayout = QVBoxLayout()
        p = QPushButton("Reconnect")
        p.clicked.connect(self.reconnect)
        buttonLayout.addWidget(p)
        p = QPushButton("Rainbow")
        p.clicked.connect(
            lambda: self.strip.write( bytearray( [MAGIC,Command.RAINBOW] )))
        buttonLayout.addWidget(p)
        self.inputs += [p]
        p = QPushButton("Test")
        p.clicked.connect(
            lambda: self.strip.write( bytearray( [MAGIC,Command.TEST] )))
        buttonLayout.addWidget(p)
        self.inputs += [p]
        p = QPushButton("Blank")
        p.clicked.connect(
            lambda: self.strip.write( bytearray( [MAGIC,Command.BLANK] )))
        buttonLayout.addWidget(p)
        self.inputs += [p]
        p = QPushButton("UniColor")
        p.clicked.connect( self.openUnicolor )
        buttonLayout.addWidget(p)
        self.inputs += [p]
        p = QPushButton("LED State")
        p.clicked.connect( self.getLEDState)
        buttonLayout.addWidget(p)
        self.inputs += [p]
        p = QPushButton("Conf")
        p.clicked.connect( lambda: self.updateConfig(True))
        buttonLayout.addWidget(p)
        self.inputs += [p]
        p = QPushButton("Debug")
        p.clicked.connect( self.strip.toggleDebug)
        buttonLayout.addWidget(p)
        self.inputs += [p]
        p = QPushButton("Reset")
        p.clicked.connect(
            lambda: self.strip.write( bytearray( [MAGIC,Command.RESET] )))
        buttonLayout.addWidget(p)
        self.inputs += [p]
        p = QPushButton("Set Size")
        p.clicked.connect( self.setSize)
        buttonLayout.addWidget(p)
        self.inputs += [p]
        p = QPushButton("Speed Test")
        p.clicked.connect( self.speedTest)
        buttonLayout.addWidget(p)
        self.inputs += [p]
        p = QPushButton("Free Mem")
        p.clicked.connect( self.freeMemory)
        buttonLayout.addWidget(p)
        self.inputs += [p]
        buttonLayout.addStretch(1)
        p = QPushButton("Quit")
        p.clicked.connect( self.close)
        buttonLayout.addWidget(p)
        layout.addLayout(buttonLayout)
       
        self.setLayout(layout)

    def setInputState(self,state):
        for i in self.inputs:
            i.setEnabled(state)
        if state: self.input.setFocus()
        
    def updateConfig(self, printConfig):
        self.killTimer( self.timer)
        if not self.strip.updateConfig():
            self.printLog( "Error retrieving config: " + str(self.strip.config))
        else:
            if printConfig:
                self.printLog( "Config: " + str(self.strip.config))
        self.timer = self.startTimer( self.timer_timeout)
        
    def speedTest(self):
        self.killTimer(self.timer)
        msg = self.strip.speedTest()
        if not len(msg):
            self.printLog("Error testing serial speed")
        else:
            self.printLog(msg)
        self.timer = self.startTimer(self.timer_timeout)
        
    def sendSerial(self):
        if not len(self.input.text()): return
        try:
            c = [ int(s,16) for s in str(self.input.text()).split(" ") ]
            s = bytearray( c)
            self.printLog( "Sending %s\n" % repr([hex(i) for i in s]))
            self.strip.write(s)
            self.input.selectAll()
        except ValueError:
            self.printLog( "Invalid input")
        
    def tryReadSerial(self,printData=True):
        try:
            s = self.strip.tryReadSerial()
            if printData and len(s):
                self.printLog(s)
        except:
            self.killTimer(self.timer)
            self.setInputState(False)
        
    def timerEvent(self,e):
        e.accept()
        self.tryReadSerial()

    def openUnicolor(self):
        self.killTimer(self.timer)
        debug = False
        if self.strip.config['debug'] == '1':
            self.strip.toggleDebug()
            debug = True
        d = ColorChooserDialog(self.strip,self)
        d.exec_()
        if debug: self.strip.toggleDebug()
        self.timer = self.startTimer(self.timer_timeout)

    def getLEDState(self):
        self.killTimer(self.timer)
        debug = False
        if self.strip.config['debug'] == '1':
            self.strip.toggleDebug()
            debug = True
        d = LEDDialog(self.strip,self)
        d.exec_()
        if debug: self.strip.toggleDebug()
        self.timer = self.startTimer(self.timer_timeout)

    def setSize(self):
        oldsize = int(self.strip.config['nleds'])
        maxsize = int(self.strip.config['nleds_max'])
        newsize = int(QInputDialog.getInt(
            self, "Set Size", "Enter Size (0-%d):" % maxsize, oldsize,
            0, maxsize)[0])
        self.strip.setSize(newsize)

    def freeMemory(self):
        self.killTimer( self.timer)
        self.printLog(self.strip.freeMemory())
        self.timer = self.startTimer( self.timer_timeout)
示例#36
0
class TagHelpViewer( QWidget ):
    """ The tag help viewer widget """

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

        self.__isEmpty = True
        self.__copyAvailable = False
        self.__clearButton = None
        self.__textEdit = None
        self.__header = None
        self.__copyButton = None
        self.__selectAllButton = None
        self.__createLayout( parent )

        # create the context menu
        self.__menu = QMenu( self )
        self.__selectAllMenuItem = self.__menu.addAction(
                            PixmapCache().getIcon( 'selectall.png' ),
                            'Select All', self.__textEdit.selectAll )
        self.__copyMenuItem = self.__menu.addAction(
                            PixmapCache().getIcon( 'copytoclipboard.png' ),
                            'Copy', self.__textEdit.copy )
        self.__menu.addSeparator()
        self.__clearMenuItem = self.__menu.addAction(
                            PixmapCache().getIcon( 'trash.png' ),
                            'Clear', self.__clear )

        self.__textEdit.setContextMenuPolicy( Qt.CustomContextMenu )
        self.__textEdit.customContextMenuRequested.connect(
                                                self.__handleShowContextMenu )
        self.__textEdit.copyAvailable.connect( self.__onCopyAvailable )

        self.__updateToolbarButtons()
        return

    def __createLayout( self, parent ):
        " Helper to create the viewer layout "

        # __textEdit list area
        self.__textEdit = QPlainTextEdit( parent )
        self.__textEdit.setLineWrapMode( QPlainTextEdit.NoWrap )
        self.__textEdit.setFont( QFont( GlobalData().skin.baseMonoFontFace ) )
        self.__textEdit.setReadOnly( True )

        # Default font size is good enough for most of the systems.
        # 12.0 might be good only in case of the XServer on PC (Xming).
        # self.__textEdit.setFontPointSize( 12.0 )

        # Buttons
        self.__selectAllButton = QAction(
            PixmapCache().getIcon( 'selectall.png' ),
            'Select all', self )
        self.__selectAllButton.triggered.connect(self.__textEdit.selectAll )
        self.__copyButton = QAction(
            PixmapCache().getIcon( 'copytoclipboard.png' ),
            'Copy to clipboard', self )
        self.__copyButton.triggered.connect( self.__textEdit.copy )
        spacer = QWidget()
        spacer.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Expanding )
        self.__clearButton = QAction(
            PixmapCache().getIcon( 'trash.png' ),
            'Clear all', self )
        self.__clearButton.triggered.connect( self.__clear )

        # Toolbar
        toolbar = QToolBar()
        toolbar.setOrientation( Qt.Vertical )
        toolbar.setMovable( False )
        toolbar.setAllowedAreas( Qt.LeftToolBarArea )
        toolbar.setIconSize( QSize( 16, 16 ) )
        toolbar.setFixedWidth( 28 )
        toolbar.setContentsMargins( 0, 0, 0, 0 )
        toolbar.addAction( self.__selectAllButton )
        toolbar.addAction( self.__copyButton )
        toolbar.addWidget( spacer )
        toolbar.addAction( self.__clearButton )

        self.__header = QLabel( "Signature: none" )
        self.__header.setFrameStyle( QFrame.StyledPanel )
        self.__header.setSizePolicy( QSizePolicy.Ignored, QSizePolicy.Fixed )
        self.__header.setAutoFillBackground( True )
        headerPalette = self.__header.palette()
        headerBackground = headerPalette.color( QPalette.Background )
        headerBackground.setRgb( min( headerBackground.red() + 30, 255 ),
                                 min( headerBackground.green() + 30, 255 ),
                                 min( headerBackground.blue() + 30, 255 ) )
        headerPalette.setColor( QPalette.Background, headerBackground )
        self.__header.setPalette( headerPalette )
        verticalLayout = QVBoxLayout()
        verticalLayout.setContentsMargins( 2, 2, 2, 2 )
        verticalLayout.setSpacing( 2 )
        verticalLayout.addWidget( self.__header )
        verticalLayout.addWidget( self.__textEdit )

        # layout
        layout = QHBoxLayout()
        layout.setContentsMargins( 0, 0, 0, 0 )
        layout.setSpacing( 0 )
        layout.addWidget( toolbar )
        layout.addLayout( verticalLayout )

        self.setLayout( layout )
        return

    def __handleShowContextMenu( self, coord ):
        """ Show the context menu """

        self.__selectAllMenuItem.setEnabled( not self.__isEmpty )
        self.__copyMenuItem.setEnabled( self.__copyAvailable )
        self.__clearMenuItem.setEnabled( not self.__isEmpty )

        self.__menu.popup( QCursor.pos() )
        return

    def __calltipDisplayable( self, calltip ):
        " True if calltip is displayable "
        if calltip is None:
            return False
        if calltip.strip() == "":
            return False
        return True

    def __docstringDisplayable( self, docstring ):
        " True if docstring is displayable "
        if docstring is None:
            return False
        if isinstance( docstring, dict ):
            if docstring[ "docstring" ].strip() == "":
                return False
            return True
        if docstring.strip() == "":
            return False
        return True

    def display( self, calltip, docstring ):
        " Displays the given help information "

        calltipDisplayable = self.__calltipDisplayable( calltip )
        docstringDisplayable = self.__docstringDisplayable( docstring )
        self.__isEmpty = True
        if calltipDisplayable or docstringDisplayable:
            self.__isEmpty = False

        if calltipDisplayable:
            if '\n' in calltip:
                calltip = calltip.split( '\n' )[ 0 ]
            self.__header.setText( "Signature: " + calltip.strip() )
        else:
            self.__header.setText( "Signature: n/a" )

        self.__textEdit.clear()
        if docstringDisplayable:
            if isinstance( docstring, dict ):
                docstring = docstring[ "docstring" ]
            self.__textEdit.insertPlainText( docstring )

        self.__updateToolbarButtons()
        QApplication.processEvents()
        return

    def __updateToolbarButtons( self ):
        " Contextually updates toolbar buttons "

        self.__selectAllButton.setEnabled( not self.__isEmpty )
        self.__copyButton.setEnabled( self.__copyAvailable )
        self.__clearButton.setEnabled( not self.__isEmpty )
        return

    def __clear( self ):
        " Triggers when the clear function is selected "
        self.__isEmpty = True
        self.__copyAvailable = False
        self.__header.setText( "Signature: none" )
        self.__textEdit.clear()
        self.__updateToolbarButtons()
        return

    def __onCopyAvailable( self, isAvailable ):
        " Triggers on the copyAvailable signal "
        self.__copyAvailable = isAvailable
        self.__updateToolbarButtons()
        return
示例#37
0
    def _update_client_tab(self):
        print '[_update_client_tab]'
        self.pre_selected_client_name = self.cur_selected_client_name
        self._widget.tabWidget.clear()   
        
        for k in self._graph._client_info_list.values(): 
            main_widget=QWidget()
           
            ver_layout=QVBoxLayout(main_widget)
           
            ver_layout.setContentsMargins (9,9,9,9)
            ver_layout.setSizeConstraint (ver_layout.SetDefaultConstraint)
            
            #button layout
            sub_widget=QWidget()
            sub_widget.setAccessibleName('sub_widget')
            btn_grid_layout=QGridLayout(sub_widget)

            btn_grid_layout.setContentsMargins (9,9,9,9)

            btn_grid_layout.setColumnStretch (1, 0)
            btn_grid_layout.setRowStretch (2, 0)

            invite_btn=QPushButton("Invite")
            platform_info_btn=QPushButton("Get Platform Info")
            status_btn=QPushButton("Get Status")
            start_app_btn=QPushButton("Start App")
            stop_app_btn=QPushButton("Stop App")              

            invite_btn.clicked.connect(lambda: self._start_service(self._widget.tabWidget.tabText(self._widget.tabWidget.currentIndex()),"invite"))
            platform_info_btn.clicked.connect(lambda: self._start_service(self._widget.tabWidget.tabText(self._widget.tabWidget.currentIndex()),"platform_info"))  
            status_btn.clicked.connect(lambda: self._start_service(self._widget.tabWidget.tabText(self._widget.tabWidget.currentIndex()),"status"))  
            start_app_btn.clicked.connect(lambda: self._start_service(self._widget.tabWidget.tabText(self._widget.tabWidget.currentIndex()),"start_app"))  
            stop_app_btn.clicked.connect(lambda: self._start_service(self._widget.tabWidget.tabText(self._widget.tabWidget.currentIndex()),"stop_app"))
                    
            btn_grid_layout.addWidget(invite_btn)
            btn_grid_layout.addWidget(platform_info_btn)
            btn_grid_layout.addWidget(status_btn)
            btn_grid_layout.addWidget(start_app_btn)
            btn_grid_layout.addWidget(stop_app_btn)             
            ver_layout.addWidget(sub_widget)            

            #client information layout
            context_label = QLabel()
            context_label.setText("Client information")
            ver_layout.addWidget(context_label)
            
            app_context_widget=QPlainTextEdit()
            app_context_widget.setObjectName(k["name"]+'_'+'app_context_widget')
            app_context_widget.setAccessibleName('app_context_widget')
            app_context_widget.appendHtml(k["app_context"])
            app_context_widget.setReadOnly(True) 
            
            cursor = app_context_widget.textCursor()
            cursor.movePosition(QTextCursor.Start,QTextCursor.MoveAnchor,0)
            app_context_widget.setTextCursor(cursor)
            ver_layout.addWidget(app_context_widget)
            
            #service layout
            context_label = QLabel()
            context_label.setText("Service result")
            ver_layout.addWidget(context_label)
            
            services_text_widget=QPlainTextEdit()
            services_text_widget.setObjectName(k["name"]+'_'+'services_text_widget')
            services_text_widget.setReadOnly(True) 
            cursor = services_text_widget.textCursor()
            cursor.movePosition(QTextCursor.Start,QTextCursor.MoveAnchor,0)
            services_text_widget.setTextCursor(cursor)            
            ver_layout.addWidget(services_text_widget)
            
            # new icon
            path=""
            if k["is_new"]==True:
                path=os.path.join(os.path.dirname(os.path.abspath(__file__)),"../../resources/images/new.gif")            

            #add tab
            self._widget.tabWidget.addTab(main_widget,QIcon(path), k["name"]);

        #set previous selected tab
        for k in range(self._widget.tabWidget.count()):
            tab_text=self._widget.tabWidget.tabText(k)
            if tab_text == self.pre_selected_client_name:
                self._widget.tabWidget.setCurrentIndex(k)
示例#38
0
class BR_JobDock(QDockWidget):
    transcode_data = pyqtSignal([dict], [str])
    job_complete = pyqtSignal()

    def __init__(self, job, passes, job_id, closesig, source, parent=None):
        name = source.title
        super().__init__(name, parent)
        self.job = job
        self.passes = passes
        self.job_id = job_id
        self.closesig = closesig
        self.source = source

        self.setWindowTitle(name)
        self.setFeatures(QDockWidget.DockWidgetMovable
                         | QDockWidget.DockWidgetFloatable)
        self.setAllowedAreas(Qt.BottomDockWidgetArea)
        self.setFloating(True)

        self.widget = QWidget()
        layout = QVBoxLayout()
        #        layout.setSizeConstraint(QVBoxLayout.SetFixedSize)
        message_layout = QFormLayout()
        self.lblPass = QLabel('Pass ? of {}'.format(passes))
        message_layout.addRow(self.lblPass)
        self.lblFrame = QLabel('?')
        message_layout.addRow('Frame:', self.lblFrame)
        self.lblFps = QLabel('?')
        message_layout.addRow('Frames per Second:', self.lblFps)
        self.lblSize = QLabel('?')
        message_layout.addRow('File Size:', self.lblSize)
        self.lblTime = QLabel('?')
        message_layout.addRow('Video Time:', self.lblTime)
        self.lblBitrate = QLabel('?')
        message_layout.addRow('Bitrate:', self.lblBitrate)
        layout.addLayout(message_layout)

        self.progressbar = QProgressBar()
        self.progressbar.setRange(0, self.source.length.total_seconds())
        layout.addWidget(self.progressbar)

        self.qualitybar = QualityBar()
        layout.addWidget(self.qualitybar)

        btn_layout = QHBoxLayout()
        btn_More = QPushButton('More')
        btn_More.setCheckable(True)
        btn_layout.addWidget(btn_More)
        btn_layout.addStretch()
        self.btnCancel = QPushButton('Close')
        self.btnCancel.setIcon(QIcon(QPixmap(':/icons/application-exit.png')))
        self.btnCancel.clicked.connect(self.on_cancel_clicked)
        btn_layout.addWidget(self.btnCancel)
        layout.addLayout(btn_layout)

        self.terminal = QPlainTextEdit()
        self.terminal.setReadOnly(True)
        self.terminal.setShown(False)
        #        self.terminal.setMinimumWidth(400)
        btn_More.toggled.connect(self.terminal.setVisible)
        layout.addWidget(self.terminal)

        griplayout = QHBoxLayout()
        griplayout.addWidget(QSizeGrip(self.widget))
        griplayout.addStretch()
        griplayout.addWidget(QSizeGrip(self.widget))
        layout.addLayout(griplayout)

        self.widget.setLayout(layout)
        self.setWidget(self.widget)

        self.transcode_data[dict].connect(self.on_avconv_data)
        self.transcode_data[str].connect(self.on_terminal_data)
        self.closesig.connect(parent.on_jobclose)

    def start(self, dir):
        self.runjob = TranscodeJob(self.job, self.passes, self.source, dir,
                                   self.transcode_data, self.job_complete)
        self.runjob.completesig.connect(self.on_job_complete)
        self.btnCancel.setText('Stop')
        self.runjob.start()

    @pyqtSlot(dict)
    def on_avconv_data(self, match):
        self.lblPass.setText('Pass {pass} of {passes}'.format(**match))
        self.lblFrame.setText('{frame}'.format(**match))
        self.lblFps.setText('{fps}'.format(**match))
        size = round(int(match['size']) / 1024, 2)
        self.lblSize.setText('{} MB'.format(size))
        time = DvdTimeDelta(seconds=float(match['time']))
        self.lblTime.setText('{}'.format(time))
        self.lblBitrate.setText('{bitrate} kbps'.format(**match))
        self.qualitybar.setValue(int(round(float(match['q']) * 10)))
        self.progressbar.setValue(int(round(float(match['time']))))

    @pyqtSlot(str)
    def on_terminal_data(self, text):
        self.terminal.appendPlainText(text)

    @pyqtSlot()
    def on_cancel_clicked(self):
        if self.runjob.is_alive():
            msg = QMessageBox(QMessageBox.Question, 'Cancelling Job',
                              'Do you want to cancel the running job?')
            msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
            msg.setDefaultButton(QMessageBox.No)
            ans = msg.exec_()
            if ans == QMessageBox.Yes:
                self.runjob.cancel()
        else:
            self.close_demand()

    @pyqtSlot()
    def on_job_complete(self):
        self.lblPass.setText('Completed')
        self.btnCancel.setText('Close')

    def close_demand(self):
        self.closesig.emit(self.job_id)
        self.close()

    def cancel(self):
        self.runjob.cancel()
        self.runjob.join()
示例#39
0
class TagHelpViewer(QWidget):
    """ The tag help viewer widget """
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        self.__isEmpty = True
        self.__copyAvailable = False
        self.__clearButton = None
        self.__textEdit = None
        self.__header = None
        self.__copyButton = None
        self.__selectAllButton = None
        self.__createLayout(parent)

        # create the context menu
        self.__menu = QMenu(self)
        self.__selectAllMenuItem = self.__menu.addAction(
            PixmapCache().getIcon('selectall.png'), 'Select All',
            self.__textEdit.selectAll)
        self.__copyMenuItem = self.__menu.addAction(
            PixmapCache().getIcon('copytoclipboard.png'), 'Copy',
            self.__textEdit.copy)
        self.__menu.addSeparator()
        self.__clearMenuItem = self.__menu.addAction(
            PixmapCache().getIcon('trash.png'), 'Clear', self.__clear)

        self.__textEdit.setContextMenuPolicy(Qt.CustomContextMenu)
        self.__textEdit.customContextMenuRequested.connect(
            self.__handleShowContextMenu)
        self.__textEdit.copyAvailable.connect(self.__onCopyAvailable)

        self.__updateToolbarButtons()
        return

    def __createLayout(self, parent):
        " Helper to create the viewer layout "

        # __textEdit list area
        self.__textEdit = QPlainTextEdit(parent)
        self.__textEdit.setLineWrapMode(QPlainTextEdit.NoWrap)
        self.__textEdit.setFont(QFont(GlobalData().skin.baseMonoFontFace))
        self.__textEdit.setReadOnly(True)

        # Default font size is good enough for most of the systems.
        # 12.0 might be good only in case of the XServer on PC (Xming).
        # self.__textEdit.setFontPointSize( 12.0 )

        # Buttons
        self.__selectAllButton = QAction(
            PixmapCache().getIcon('selectall.png'), 'Select all', self)
        self.__selectAllButton.triggered.connect(self.__textEdit.selectAll)
        self.__copyButton = QAction(
            PixmapCache().getIcon('copytoclipboard.png'), 'Copy to clipboard',
            self)
        self.__copyButton.triggered.connect(self.__textEdit.copy)
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.__clearButton = QAction(PixmapCache().getIcon('trash.png'),
                                     'Clear all', self)
        self.__clearButton.triggered.connect(self.__clear)

        # Toolbar
        toolbar = QToolBar()
        toolbar.setOrientation(Qt.Vertical)
        toolbar.setMovable(False)
        toolbar.setAllowedAreas(Qt.LeftToolBarArea)
        toolbar.setIconSize(QSize(16, 16))
        toolbar.setFixedWidth(28)
        toolbar.setContentsMargins(0, 0, 0, 0)
        toolbar.addAction(self.__selectAllButton)
        toolbar.addAction(self.__copyButton)
        toolbar.addWidget(spacer)
        toolbar.addAction(self.__clearButton)

        self.__header = QLabel("Signature: none")
        self.__header.setFrameStyle(QFrame.StyledPanel)
        self.__header.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed)
        self.__header.setAutoFillBackground(True)
        headerPalette = self.__header.palette()
        headerBackground = headerPalette.color(QPalette.Background)
        headerBackground.setRgb(min(headerBackground.red() + 30, 255),
                                min(headerBackground.green() + 30, 255),
                                min(headerBackground.blue() + 30, 255))
        headerPalette.setColor(QPalette.Background, headerBackground)
        self.__header.setPalette(headerPalette)
        verticalLayout = QVBoxLayout()
        verticalLayout.setContentsMargins(2, 2, 2, 2)
        verticalLayout.setSpacing(2)
        verticalLayout.addWidget(self.__header)
        verticalLayout.addWidget(self.__textEdit)

        # layout
        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)
        layout.addWidget(toolbar)
        layout.addLayout(verticalLayout)

        self.setLayout(layout)
        return

    def __handleShowContextMenu(self, coord):
        """ Show the context menu """

        self.__selectAllMenuItem.setEnabled(not self.__isEmpty)
        self.__copyMenuItem.setEnabled(self.__copyAvailable)
        self.__clearMenuItem.setEnabled(not self.__isEmpty)

        self.__menu.popup(QCursor.pos())
        return

    def __calltipDisplayable(self, calltip):
        " True if calltip is displayable "
        if calltip is None:
            return False
        if calltip.strip() == "":
            return False
        return True

    def __docstringDisplayable(self, docstring):
        " True if docstring is displayable "
        if docstring is None:
            return False
        if isinstance(docstring, dict):
            if docstring["docstring"].strip() == "":
                return False
            return True
        if docstring.strip() == "":
            return False
        return True

    def display(self, calltip, docstring):
        " Displays the given help information "

        calltipDisplayable = self.__calltipDisplayable(calltip)
        docstringDisplayable = self.__docstringDisplayable(docstring)
        self.__isEmpty = True
        if calltipDisplayable or docstringDisplayable:
            self.__isEmpty = False

        if calltipDisplayable:
            if '\n' in calltip:
                calltip = calltip.split('\n')[0]
            self.__header.setText("Signature: " + calltip.strip())
        else:
            self.__header.setText("Signature: n/a")

        self.__textEdit.clear()
        if docstringDisplayable:
            if isinstance(docstring, dict):
                docstring = docstring["docstring"]
            self.__textEdit.insertPlainText(docstring)

        self.__updateToolbarButtons()
        QApplication.processEvents()
        return

    def __updateToolbarButtons(self):
        " Contextually updates toolbar buttons "

        self.__selectAllButton.setEnabled(not self.__isEmpty)
        self.__copyButton.setEnabled(self.__copyAvailable)
        self.__clearButton.setEnabled(not self.__isEmpty)
        return

    def __clear(self):
        " Triggers when the clear function is selected "
        self.__isEmpty = True
        self.__copyAvailable = False
        self.__header.setText("Signature: none")
        self.__textEdit.clear()
        self.__updateToolbarButtons()
        return

    def __onCopyAvailable(self, isAvailable):
        " Triggers on the copyAvailable signal "
        self.__copyAvailable = isAvailable
        self.__updateToolbarButtons()
        return