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
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))
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
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)
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)
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)
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)
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()
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 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()
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)
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("")
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()
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'))
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)
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)
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 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)
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))
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()
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()
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()
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()
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))
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()
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()
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()
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()
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()
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))
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()
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)
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
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)
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()
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