class ValidatingLineEdit(LineEdit): statusChanged = pyqtSignal() def __init__(self, parent=None): super(ValidatingLineEdit, self).__init__(parent) self.invalid_entry_label = QLabel(self) self.invalid_entry_label.setFixedSize(18, 16) self.invalid_entry_label.setPixmap( QPixmap(Resources.get('icons/invalid16.png'))) self.invalid_entry_label.setScaledContents(False) self.invalid_entry_label.setAlignment(Qt.AlignCenter) self.invalid_entry_label.setObjectName('invalid_entry_label') self.invalid_entry_label.hide() self.addTailWidget(self.invalid_entry_label) option = QStyleOptionFrameV2() self.initStyleOption(option) frame_width = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth, option, self) self.setMinimumHeight(self.invalid_entry_label.minimumHeight() + 2 + 2 * frame_width) self.textChanged.connect(self._SH_TextChanged) self.text_correct = True self.text_allowed = True self.exceptions = set() self.regexp = re.compile(r'.*') def _get_regexp(self): return self.__dict__['regexp'] def _set_regexp(self, regexp): self.__dict__['regexp'] = regexp self._validate() regexp = property(_get_regexp, _set_regexp) del _get_regexp, _set_regexp @property def text_valid(self): return self.text_correct and self.text_allowed def _SH_TextChanged(self, text): self._validate() def _validate(self): text = self.text() text_correct = self.regexp.search(text) is not None text_allowed = text not in self.exceptions if self.text_correct != text_correct or self.text_allowed != text_allowed: self.text_correct = text_correct self.text_allowed = text_allowed self.invalid_entry_label.setVisible(not self.text_valid) self.statusChanged.emit() def addException(self, exception): self.exceptions.add(exception) self._validate() def removeException(self, exception): self.exceptions.remove(exception) self._validate()
class DialogLoginKey(QDialog): def __init__(self, parent, windowTitle, icon=None): def initGui(): def connect(): buttonLogin.clicked.connect(self.onLogin) self.textKey.textEdited.connect(self.onTextEdited) # self.setWindowTitle(windowTitle) if not icon is None: self.setWindowIcon(icon) labelKey = QLabel("Key: ", self) self.labelError = QLabel(self) self.labelError.hide() self.textKey = QLineEdit(self) self.textKey.setEchoMode(QLineEdit.Password) buttonLogin = QPushButton("Login", self) connect() layout = QVBoxLayout(self) layout.addWidget(labelKey) layout.addWidget(self.textKey) layout.addWidget(buttonLogin) layout.addWidget(self.labelError) # self.resize(4 * len(windowTitle) + 200, 30) # super(DialogLoginKey, self).__init__(parent) self.apiPL = API_PlanetLabs() self.responsePL = None initGui() @pyqtSlot(bool) def onLogin(self, checked): def setFinishedPL(response): self.responsePL = response loop.quit() def setKeyResponse(): if self.responsePL['isOk']: self.accept() else: self.labelError.setTextFormat(Qt.RichText) msg = "<font color=\"red\"><b><i>Invalid key! %s</i></b></font>" % self.responsePL[ 'message'] self.labelError.setText(msg) self.labelError.show() key = self.textKey.text().encode('ascii', 'ignore') self.responsePL = None loop = QEventLoop() self.apiPL.setKey(key, setFinishedPL) loop.exec_() setKeyResponse() @pyqtSlot(str) def onTextEdited(self, text): if self.labelError.isHidden(): return self.labelError.hide()
class TrueFalseCardShowWidget(QWidget): def __init__(self, parent=None): super(TrueFalseCardShowWidget, self).__init__(parent) self.grid = QGridLayout() self.setLayout(self.grid) self.word_label = QLabel('Word') self.word_label.setAlignment(Qt.AlignCenter) self.grid.addWidget(self.word_label, 0, 0) self.word_label.setFont(QFont('SansSerif', 13)) self.example_label = QLabel('Example') self.example_label.setWordWrap(True); self.example_label.setAlignment(Qt.AlignCenter) self.grid.addWidget(self.example_label, 1, 0) self.example_label.setFont(QFont('SansSerif', 13)) self.translation_label = QLabel('Translation') self.translation_label.setWordWrap(True); self.translation_label.setAlignment(Qt.AlignCenter) self.grid.addWidget(self.translation_label, 2, 0) self.translation_label.setFont(QFont('SansSerif', 13)) self.translation_label.hide() def show_card(self, card): """ Show card :param card: the card to show :type card:Card """ self.word_label.setText(card.word) self.example_label.setText(card.example) self.translation_label.setText(card.translation) self.translation_label.hide()
def createPixmapWidget(self, parent, iconName): w = QLabel(parent) parent.layout().addWidget(w) w.setFixedSize(16, 16) w.hide() if os.path.exists(iconName): w.setPixmap(QPixmap(iconName)) return w
class ValidatingLineEdit(LineEdit): statusChanged = pyqtSignal() def __init__(self, parent=None): super(ValidatingLineEdit, self).__init__(parent) self.invalid_entry_label = QLabel(self) self.invalid_entry_label.setFixedSize(18, 16) self.invalid_entry_label.setPixmap(QPixmap(Resources.get('icons/invalid16.png'))) self.invalid_entry_label.setScaledContents(False) self.invalid_entry_label.setAlignment(Qt.AlignCenter) self.invalid_entry_label.setObjectName('invalid_entry_label') self.invalid_entry_label.hide() self.addTailWidget(self.invalid_entry_label) option = QStyleOptionFrameV2() self.initStyleOption(option) frame_width = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth, option, self) self.setMinimumHeight(self.invalid_entry_label.minimumHeight() + 2 + 2*frame_width) self.textChanged.connect(self._SH_TextChanged) self.text_correct = True self.text_allowed = True self.exceptions = set() self.regexp = re.compile(r'.*') def _get_regexp(self): return self.__dict__['regexp'] def _set_regexp(self, regexp): self.__dict__['regexp'] = regexp self._validate() regexp = property(_get_regexp, _set_regexp) del _get_regexp, _set_regexp @property def text_valid(self): return self.text_correct and self.text_allowed def _SH_TextChanged(self, text): self._validate() def _validate(self): text = self.text() text_correct = self.regexp.search(text) is not None text_allowed = text not in self.exceptions if self.text_correct != text_correct or self.text_allowed != text_allowed: self.text_correct = text_correct self.text_allowed = text_allowed self.invalid_entry_label.setVisible(not self.text_valid) self.statusChanged.emit() def addException(self, exception): self.exceptions.add(exception) self._validate() def removeException(self, exception): self.exceptions.remove(exception) self._validate()
def download_(self): print("download_") self.b = QCommandLinkButton("") self.b.clicked.connect(self.get_setup) msg = QLabel("Connexion ...") self.addWidget(msg) msg.hide() self.b.setText(self.check.data.get("message")) self.addWidget(self.b)
def add_group_selector(self): self.module_group_box = QComboBox(self) self.module_group_box.currentIndexChanged.connect(self.state_changed) lab = QLabel("Module Group:") lab.setAlignment(Qt.AlignRight) self.grid_layout.addWidget(lab, self.rowCount(), 0) self.grid_layout.addWidget(self.module_group_box, self.rowCount() - 1, 1) lab.hide() self.module_group_box.hide() self.module_group_box.addItem("R (0)") self.module_group_box.addItem("Phi (1)")
def buildInterface(self, config): #<server uri> self.uri = QLineEdit() self.texts.add(self.uri) self.connect(self.uri, SIGNAL('textChanged(QString)'), self.setUri) self.connect(self.uri, SIGNAL('textChanged(QString)'), self.signalModified) self.connect(self.uri, SIGNAL('textEdited(QString)'), self.helpURI) self.connect(self.uri, SIGNAL('editingFinished()'), self.noHelpURI) self.connect(self.uri, SIGNAL('editingFinished()'), self.updateUri) self.form.addRow(tr('LDAP Server(s) uri'), self.uri) self.uri.setToolTip(help_uri_tooltip) self.connect(self.uri, SIGNAL('returnPressed()'), self.signalModified) self.uri_message_area = MessageArea() self.empty_uri_label = QLabel() self.form.addRow(self.empty_uri_label, self.uri_message_area) self.empty_uri_label.hide() self.uri_message_area.hide() self.uri_message_area.setMessage(help_uri_title, help_uri_message_area) self.numeric_uri_warning = MessageArea() empty = QLabel() self.form.addRow(empty, self.numeric_uri_warning) empty.hide() self.numeric_uri_warning.hide() self.numeric_uri_warning.warning(numeric_warning_title, numeric_warning) self.numeric_uri_warning.setWidth(60) #</server uri> #<other fields> for args in self._genTextFieldsData(): text_input = self.addTextInput(*args[1:]) setattr(self, args[0], text_input) self.connect(text_input, SIGNAL('editingFinished(QString)'), self.valid) #</other fields> self.ssl_box = self.mkSslBox() self.connect(self.ssl_box, SIGNAL('toggled(bool)'), self.toggleSsl) self.form.addRow(self.ssl_box) self.form.addRow(separator()) test_widget = QPushButton(tr("Test this configuration")) self.form.addRow("", test_widget) test_widget.connect(test_widget, SIGNAL('clicked()'), self.test_ldap)
class InteractiveItem(QGraphicsRectItem): def __init__(self, bgc_info, *args, **kargs): QGraphicsRectItem.__init__(self, *args, **kargs) self.node = None self.label = None self.bgc_info = bgc_info self.setCursor(QtCore.Qt.PointingHandCursor) self.setAcceptsHoverEvents(True) def hoverEnterEvent (self, e): # Show/hide a text item over the custom DynamicItemFace if not self.label: self.label = QLabel(self.bgc_info) self.label.show() def hoverLeaveEvent(self, e): if self.label: self.label.hide()
class Help(QFrame): def __init__(self, parent=None): QFrame.__init__(self, parent) layout = QHBoxLayout(self) self.icon = QLabel() self.icon.setPixmap(QPixmap(":/icons-32/info")) layout.addWidget(self.icon) self.message = QLabel() self.message.setWordWrap(True) layout.addWidget(self.message) layout.addStretch() self.setNoMessage() def setMessage(self, text): self.message.setText(text) self.message.show() self.icon.show() self.setFrameStyle(QFrame.StyledPanel) def setNoMessage(self): self.message.hide() self.icon.hide() self.setFrameStyle(QFrame.NoFrame)
class ResultPlot(QWidget): def __init__(self): super(ResultPlot, self).__init__() vl = QVBoxLayout() self.plot = Plot() vl.setAlignment(Qt.AlignTop) vl.addWidget(self.plot) self.residual_plot = ResidualPlot() self.residual_plot.setFixedHeight(150) vl.addWidget(self.residual_plot) hl = QHBoxLayout() #hl.setAlignment(Qt.AlignHCenter) self.chi2_label = QLabel('chi^2') self.chi2_label.setFixedWidth(30) self.chi2_label.hide(); self.chi2_value = QLineEdit() self.chi2_value.setAlignment(Qt.AlignRight) self.chi2_value.setFixedWidth(120) self.chi2_value.hide() auto_plot = QCheckBox('Auto plot finished result') auto_plot.stateChanged.connect(self._on_auto_plot_state_changed) hl.addWidget(auto_plot, Qt.AlignLeft) hl.addWidget(self.chi2_label) hl.addWidget(self.chi2_value) hl.setStretch(1, 0) vl.addLayout(hl) self.setLayout(vl) def _on_auto_plot_state_changed(self, checked_state): checked_state = True if checked_state else False Global.event.interface_auto_plot_state_changed.emit(checked_state)
class FeatureFormWidget(Ui_Form, QWidget): # Raise the cancel event, takes a reason and a level cancel = pyqtSignal(str, int) featuresaved = pyqtSignal() featuredeleted = pyqtSignal() def __init__(self, parent=None): super(FeatureFormWidget, self).__init__(parent) self.setupUi(self) toolbar = QToolBar() size = QSize(48, 48) toolbar.setIconSize(size) style = Qt.ToolButtonTextUnderIcon toolbar.setToolButtonStyle(style) self.actionDelete = toolbar.addAction(QIcon(":/icons/delete"), "Delete") self.actionDelete.triggered.connect(self.delete_feature) label = 'Required fields marked in <b style="background-color:rgba(255, 221, 48,150)">yellow</b>' self.missingfieldsLabel = QLabel(label) self.missingfieldsLabel.hide() self.missingfieldaction = toolbar.addWidget(self.missingfieldsLabel) titlespacer = QWidget() titlespacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) toolbar.addWidget(titlespacer) self.titlellabel = QLabel(label) self.titlellabel.setProperty("headerlabel", True) self.titlelabelaction = toolbar.addWidget(self.titlellabel) spacer = QWidget() spacer2 = QWidget() spacer2.setMinimumWidth(20) spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) spacer2.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) toolbar.addWidget(spacer) self.actionCancel = toolbar.addAction(QIcon(":/icons/cancel"), "Cancel") toolbar.addWidget(spacer2) self.actionSave = toolbar.addAction(QIcon(":/icons/save"), "Save") self.actionSave.triggered.connect(self.save_feature) self.layout().insertWidget(0, toolbar) self.flickwidget = FlickCharm() self.flickwidget.activateOn(self.scrollArea) self.featureform = None self.values = {} self.config = {} self.feature = None def set_featureform(self, featureform): """ Note: There can only be one feature form. If you need to show another one make a new FeatureFormWidget """ self.featureform = featureform self.titlellabel.setText(self.featureform.windowTitle()) self.featureform.formvalidation.connect(self._update_validation) self.featureform.helprequest.connect(functools.partial(RoamEvents.helprequest.emit, self)) self.featureform.showlargewidget.connect(RoamEvents.show_widget.emit) self.featureform.enablesave.connect(self.actionSave.setEnabled) self.featureform.enablesave.connect(self.actionSave.setVisible) self.featureform.rejected.connect(self.cancel.emit) self.featureformarea.layout().addWidget(self.featureform) def delete_feature(self): try: msg = self.featureform.deletemessage except AttributeError: msg = 'Do you really want to delete this feature?' box = DeleteFeatureDialog(msg) if not box.exec_(): return try: self.featureform.delete() except featureform.DeleteFeatureException as ex: RoamEvents.raisemessage(*ex.error) self.featureform.featuredeleted(self.feature) self.featuredeleted.emit() def save_feature(self): try: self.featureform.save() except featureform.MissingValuesException as ex: RoamEvents.raisemessage(*ex.error) return except featureform.FeatureSaveException as ex: RoamEvents.raisemessage(*ex.error) self.featuresaved.emit() RoamEvents.featuresaved.emit() def set_config(self, config): self.config = config editmode = config['editmode'] allowsave = config.get('allowsave', True) self.feature = config.get('feature', None) self.featureform.feature = self.feature self.featureform.editingmode = editmode self.actionDelete.setVisible(editmode) self.actionSave.setEnabled(allowsave) def _update_validation(self, passed): # Show the error if there is missing fields self.missingfieldaction.setVisible(not passed) def bind_values(self, values): self.values = values self.featureform.bindvalues(values) def after_load(self): self.featureform.loaded() def before_load(self): self.featureform.load(self.config['feature'], self.config['layers'], self.values)
class entrar(QDialog): def __init__(self): super(entrar, self).__init__(None) self.resize(400, 440) self.setWindowTitle('Datos de Usuario') self.imaje = QLabel(self) self.imaje.setGeometry(160, 210, 225, 225) self.imaje.setPixmap(QPixmap(getcwd() + "/usuario.gif")) self.n = QLabel('Nombre Completo:', self) self.n.move(10, 10) self.u = QLabel('Nombre de Usuario:', self) self.u.move(10, 50) self.failu = QLabel('Este Usuario ya Existe', self) self.failu.move(140, 70) self.failu.hide() self.c = QLabel('Correo Electronico:', self) self.c.move(10, 90) self.a = QLabel('Edad:', self) self.a.move(10, 130) self.faila = QLabel('Ingrese una Edad', self) self.faila.move(140, 150) self.faila.hide() self.p = QLabel('Clave:', self) self.p.move(10, 170) self.failp = QLabel('Clave muy Debil', self) self.failp.move(140, 190) self.failp.hide() self.f = QLabel('Foto:', self) self.f.move(10, 210) self.Name = QLineEdit(self) self.Name.setGeometry(140, 10, 200, 20) self.User = QLineEdit(self) self.User.setGeometry(140, 50, 200, 20) self.Mail = QLineEdit(self) self.Mail.setGeometry(140, 90, 200, 20) self.Age = QLineEdit(self) self.Age.setGeometry(140, 130, 200, 20) self.Pass = QLineEdit(self) self.Pass.setGeometry(140, 170, 200, 20) self.buscarfoto = QPushButton('Buscar Foto', self) self.buscarfoto.setGeometry(10, 250, 100, 30) self.guardar = QPushButton('Guardar', self) self.guardar.setGeometry(30, 300, 60, 30) self.failc = QLabel('Llenar Campos Vacios', self) self.failc.move(10, 350) self.failc.hide() self.connect(self.buscarfoto, SIGNAL('clicked()'), lambda: self.buscar()) self.connect( self.guardar, SIGNAL('clicked()'), lambda: self.nuevo( self.Name, self.User, self.Mail, self.Age, self.Pass)) #sys.exit(self.editar.exec_()) def ponfoto(self, a): self.imaje.hide() #self.imaje.setPixmap(QPixmap(a)) def buscar(self): e = explorador() e.exec_() def nuevo(self, name, user, mail, age, passw): n = name.text() u = user.text() m = mail.text() a = age.text() p = passw.text() if (n != '' and u != '' and m != '' and a != '' and p != ''): #revisa que todos los campos esten llenos login = open('login.txt', 'r') self.failc.hide() for i in login: if str(u) in i: # revisa si ya existe este nombre de usuario self.failu.show() else: self.failu.hide() try: # revisa si se ingresa un numero int(a) self.faila.hide() usuarios = open('usuarios.txt', 'a') usuarios.write(n + ',' + u + ',' + m + ',' + a + ',' + p + '\n') usuarios.close() except ValueError: self.faila.show() login.close() else: self.failc.show()
class RunWidget(QWidget): def __init__(self): QWidget.__init__(self) vbox = QVBoxLayout(self) vbox.setSpacing(0) vbox.setContentsMargins(0, 0, 0, 0) self.output = OutputWidget(self) hbox = QHBoxLayout() self.input = QLineEdit() self.lblInput = QLabel(self.tr("Input:")) vbox.addWidget(self.output) hbox.addWidget(self.lblInput) hbox.addWidget(self.input) vbox.addLayout(hbox) #process self._proc = QProcess(self) self.connect(self._proc, SIGNAL("readyReadStandardOutput()"), self.output._refresh_output) self.connect(self._proc, SIGNAL("readyReadStandardError()"), self.output._refresh_error) self.connect(self._proc, SIGNAL("finished(int, QProcess::ExitStatus)"), self.finish_execution) self.connect(self._proc, SIGNAL("error(QProcess::ProcessError)"), self.process_error) self.connect(self.input, SIGNAL("returnPressed()"), self.insert_input) def process_error(self, error): self.lblInput.hide() self.input.hide() self._proc.kill() format = QTextCharFormat() format.setAnchor(True) format.setForeground(Qt.red) if error == 0: self.output.textCursor().insertText(self.tr('Failed to start'), format) else: self.output.textCursor().insertText( self.tr('Error during execution, QProcess error: %d' % error), format) def finish_execution(self, exitCode, exitStatus): self.lblInput.hide() self.input.hide() format = QTextCharFormat() format.setAnchor(True) self.output.textCursor().insertText('\n\n') if exitStatus == QProcess.NormalExit: format.setForeground(Qt.green) self.output.textCursor().insertText( self.tr("Execution Successful!"), format) else: format.setForeground(Qt.red) self.output.textCursor().insertText( self.tr("Execution Interrupted"), format) def insert_input(self): text = self.input.text() + '\n' self._proc.writeData(text) self.input.setText("") def start_process(self, fileName, pythonPath=False, programParams=''): self.lblInput.show() self.input.show() self.output.setCurrentCharFormat(self.output.plain_format) self.output.setPlainText('Running: %s (%s)\n\n' % (fileName, unicode(time.ctime()))) self.output.moveCursor(QTextCursor.Down) self.output.moveCursor(QTextCursor.Down) self.output.moveCursor(QTextCursor.Down) #runner.run_code_from_file(fileName) if not pythonPath: pythonPath = settings.PYTHON_PATH #change the working directory to the fileName dir file_directory = file_manager.get_folder(fileName) self._proc.setWorkingDirectory(file_directory) #force python to unbuffer stdin and stdout options = ['-u'] + settings.EXECUTION_OPTIONS.split() self._proc.start(pythonPath, options + [fileName] + \ [p.strip() for p in programParams.split(',') if p]) def kill_process(self): self._proc.kill()
class ADBaseWidget(DirectoryWidget): def __init__(self, config, specific_config, mainwindow, parent=None): DirectoryWidget.__init__(self, config, specific_config, mainwindow, parent=None) self.qhostname_object = QHostnameObject.getInstance() self.buildInterface(config) self.updateView() self._poll() def register_qobjects(self): self.qhostname_object.registerCallbacks( self.acceptHostnameChange, self.handleHostnameChange, attach=self ) def _poll(self): self.ad_status.fetch_data(self.mainwindow.client) timer = QTimer() timer.setSingleShot(True) timer.setInterval(20000) # ms timer.start() self.connect(timer, SIGNAL('timeout()'), self._poll) self.connect(self, SIGNAL('destroyed()'), timer.stop) def unregister_qobjects(self): self.qhostname_object.forget(self) def updateView(self, config=None): if config is None: config = self.specific_config self.setText(self.controller_ip, config.controller_ip) self.setDefaultText(self.user, config.user) self.setDefaultText(self.password, config.password) self.setDefaultText(self.workgroup, config.workgroup) self.setDefaultText(self.domain, config.domain) self.setDefaultText(self.dns_domain, config.dns_domain) self.setText(self.wins_ip, config.wins_ip) self.displayHostname() def acceptHostnameChange(self): button = QMessageBox.warning( self, tr("Hostname change"), tr("Warning: this hostname change will cause the appliance to register again on Active Directory."), QMessageBox.Cancel | QMessageBox.Ok ) if button == QMessageBox.Ok: self.signalModified() return True return False def handleHostnameChange(self): self.displayHostname() def displayHostname(self): self.netbios_name.setText(u"<b>%s</b>" % unicode(self.qhostname_object.hostnamecfg.hostname)) def buildInterface(self, config): fqdn_tooltip = tr("IP address, FQDN or Hostname") self.controller_ip = QLineEdit() self.texts.add(self.controller_ip) self.connect(self.controller_ip, SIGNAL('textChanged(QString)'), self.setControllerIp) self.form.addRow(tr('Authentication server'), self.controller_ip) self.controller_ip.setToolTip(help_ps_tooltip) self.connect(self.controller_ip, SIGNAL('returnPressed()'), self.signalModified) self.ps_message_area = MessageArea() self.empty_ps_label = QLabel() self.form.addRow(self.empty_ps_label, self.ps_message_area) self.empty_ps_label.hide() self.ps_message_area.hide() self.ps_message_area.setMessage(help_ps_title, help_ps_message_area) self.wins_ip = IpOrHostnameOrFqdnEdit(accept_empty=True) self.texts.add(self.wins_ip) self.connect(self.wins_ip, SIGNAL('textChanged(QString)'), self.setWinsIp) self.form.addRow(tr('WINS server (optional)'), self.wins_ip) self.wins_ip.setToolTip( "%s\n%s" % ( fqdn_tooltip, tr("This field is useful if the AD and EdenWall appliances don't share the same subnet") ) ) self.connect(self.wins_ip, SIGNAL('returnPressed()'), self.signalModified) for args in ( ('domain', tr('Active Directory Domain'), self.setDomain), ('dns_domain', tr('Active Directory DNS Domain (if different from the AD domain)'), self.setDNSDomain), ('workgroup', tr('Workgroup (optional)'), self.setWorkgroup) ): setattr(self, args[0], self.addTextInput(*args[1:])) #flagWriteAccess(text_input) self.netbios_name = QLabel() self.form.addRow(tr("Netbios name"), self.netbios_name) for args in ( ('user', tr('Name used to join the domain'), self.setUser), ('password', tr('Password used to join the domain'), self.setPassword, False) ): setattr(self, args[0], self.addTextInput(*args[1:])) #flagWriteAccess(text_input) #flagWriteAccess(password_server) self.connect(self.controller_ip, SIGNAL('textEdited(QString)'), self.helpPS) self.connect(self.controller_ip, SIGNAL('editingFinished()'), self.noHelpPS) self.ad_status = ADStatus() self.form.addRow('', self.ad_status) def helpPS(self, text): self.ps_message_area.show() def noHelpPS(self): self.controller_ip.setText( unicode( self.controller_ip.text() ).strip() ) self.ps_message_area.hide() def setControllerIp(self, server): self.specific_config.controller_ip = unicode(server).strip() self.signalModified() def setWinsIp(self, server): self.specific_config.wins_ip = unicode(server) self.signalModified() def setDomain(self, domain): self.specific_config.domain = domain def setDNSDomain(self, domain): self.specific_config.dns_domain = domain def setUser(self, user): self.specific_config.user = user def setPassword(self, password): self.specific_config.password = password def setWorkgroup(self, workgroup): self.specific_config.workgroup = workgroup def signalModified(self): self.config.org = self.specific_config DirectoryWidget.signalModified(self)
class Search(QWidget, plugin.MainWindowPlugin): def __init__(self, mainwindow): super(Search, self).__init__(mainwindow) self._currentView = None self._positions = None self._replace = False # are we in replace mode? mainwindow.currentViewChanged.connect(self.viewChanged) mainwindow.actionCollection.edit_find_next.triggered.connect(self.findNext) mainwindow.actionCollection.edit_find_previous.triggered.connect(self.findPrevious) # dont inherit looks from view self.setFont(QApplication.font()) self.setPalette(QApplication.palette()) grid = QGridLayout() grid.setContentsMargins(4, 0, 4, 0) grid.setVerticalSpacing(0) self.setLayout(grid) self.searchEntry = QLineEdit(textChanged=self.slotSearchChanged) self.searchLabel = QLabel() self.caseCheck = QCheckBox(checked=True, focusPolicy=Qt.NoFocus) self.regexCheck = QCheckBox(focusPolicy=Qt.NoFocus) self.countLabel = QLabel(alignment=Qt.AlignRight | Qt.AlignVCenter) self.countLabel.setMinimumWidth(QApplication.fontMetrics().width("9999")) self.closeButton = QToolButton(autoRaise=True, focusPolicy=Qt.NoFocus) self.hideAction = QAction(self, triggered=self.slotHide) self.hideAction.setShortcut(QKeySequence(Qt.Key_Escape)) self.hideAction.setIcon(self.style().standardIcon(QStyle.SP_DialogCloseButton)) self.closeButton.setDefaultAction(self.hideAction) grid.addWidget(self.searchLabel, 0, 0) grid.addWidget(self.searchEntry, 0, 1) grid.addWidget(self.caseCheck, 0, 2) grid.addWidget(self.regexCheck, 0, 3) grid.addWidget(self.countLabel, 0, 4) grid.addWidget(self.closeButton, 0, 5) self.caseCheck.toggled.connect(self.slotSearchChanged) self.regexCheck.toggled.connect(self.slotSearchChanged) self.replaceEntry = QLineEdit() self.replaceLabel = QLabel() self.replaceButton = QPushButton(clicked=self.slotReplace) self.replaceAllButton = QPushButton(clicked=self.slotReplaceAll) grid.addWidget(self.replaceLabel, 1, 0) grid.addWidget(self.replaceEntry, 1, 1) grid.addWidget(self.replaceButton, 1, 2) grid.addWidget(self.replaceAllButton, 1, 3) app.settingsChanged.connect(self.readSettings) self.readSettings() app.translateUI(self) def translateUI(self): self.searchLabel.setText(_("Search:")) self.caseCheck.setText(_("&Case")) self.caseCheck.setToolTip(_("Case Sensitive")) self.regexCheck.setText(_("&Regex")) self.regexCheck.setToolTip(_("Regular Expression")) self.countLabel.setToolTip(_("The total number of matches")) self.hideAction.setToolTip(_("Close")) self.replaceLabel.setText(_("Replace:")) self.replaceButton.setText(_("Re&place")) self.replaceButton.setToolTip(_("Replaces the next occurrence of the search term.")) self.replaceAllButton.setText(_("&All")) self.replaceAllButton.setToolTip(_("Replaces all occurrences of the search term in the document or selection.")) def readSettings(self): data = textformats.formatData('editor') self.searchEntry.setFont(data.font) self.replaceEntry.setFont(data.font) p = data.palette() self.searchEntry.setPalette(p) self.replaceEntry.setPalette(p) def currentView(self): return self._currentView and self._currentView() def setCurrentView(self, view): self._currentView = weakref.ref(view) if view else None def showWidget(self): if self.isVisible(): self.hideWidget() view = self.window().currentView() self.setCurrentView(view) layout = widgets.borderlayout.BorderLayout.get(view) layout.addWidget(self, widgets.borderlayout.BOTTOM) self.show() def hideWidget(self): view = self.currentView() if view: viewhighlighter.highlighter(view).clear("search") self.hide() layout = widgets.borderlayout.BorderLayout.get(view) layout.removeWidget(self) def viewChanged(self, new): self.setParent(None) self.hideWidget() self.setCurrentView(new) self.updatePositions() def slotHide(self): view = self.currentView() if view: self.hideWidget() view.setFocus() def find(self): # hide replace stuff self.replaceLabel.hide() self.replaceEntry.hide() self.replaceButton.hide() self.replaceAllButton.hide() self._replace = False # we are not in replace mode visible = self.isVisible() if not visible: with qutil.signalsBlocked(self.searchEntry): self.searchEntry.clear() self.showWidget() if not visible and self.currentView(): # pick current word cursor = self.currentView().textCursor() cursor.movePosition(QTextCursor.StartOfWord) cursor.movePosition(QTextCursor.EndOfWord, QTextCursor.KeepAnchor) word = cursor.selection().toPlainText() if not re.search(r'\w', word): word = "" self.searchEntry.setText(word) self.searchEntry.selectAll() else: self.slotSearchChanged() self.searchEntry.setFocus() def replace(self): # show replace stuff self.replaceLabel.show() self.replaceEntry.show() self.replaceButton.show() self.replaceAllButton.show() focus = self.replaceEntry if self.isVisible() and self.searchEntry.text() else self.searchEntry self._replace = True # we are in replace mode self.showWidget() self.slotSearchChanged() focus.setFocus() def slotSearchChanged(self): self.updatePositions() viewhighlighter.highlighter(self.currentView()).highlight("search", self._positions, 1) def updatePositions(self): search = self.searchEntry.text() view = self.currentView() document = view.document() self._positions = [] if search: text = document.toPlainText() flags = re.MULTILINE | re.DOTALL if not self.caseCheck.isChecked(): flags |= re.IGNORECASE if not self.regexCheck.isChecked(): search = re.escape(search) try: matches = re.finditer(search, text, flags) except re.error: pass else: for m in matches: c = QTextCursor(document) c.setPosition(m.end()) c.setPosition(m.start(), QTextCursor.KeepAnchor) self._positions.append(c) self.countLabel.setText(unicode(len(self._positions))) def findNext(self): view = self.currentView() if view and self._positions: positions = [c.position() for c in self._positions] index = bisect.bisect_right(positions, view.textCursor().position()) if index < len(positions): view.setTextCursor(self._positions[index]) else: view.setTextCursor(self._positions[0]) view.ensureCursorVisible() def findPrevious(self): view = self.currentView() positions = [c.position() for c in self._positions] if view and positions: index = bisect.bisect_left(positions, view.textCursor().position()) - 1 view.setTextCursor(self._positions[index]) view.ensureCursorVisible() def keyPressEvent(self, ev): if ev.key() == Qt.Key_Tab: # prevent Tab from reaching the View widget self.window().focusNextChild() return # if in search mode, Up and Down jump between search results if not self._replace and self._positions and self.searchEntry.text() and not ev.modifiers(): if ev.key() == Qt.Key_Up: self.findPrevious() return elif ev.key() == Qt.Key_Down: self.findNext() return # use enter or return for search next if ev.key() in (Qt.Key_Enter, Qt.Key_Return): self.findNext() return super(Search, self).keyPressEvent(ev) def doReplace(self, cursor): text = cursor.selection().toPlainText() search = self.searchEntry.text() replace = self.replaceEntry.text() ok = text == self.searchEntry.text() if self.regexCheck.isChecked(): m = re.match(search, text) ok = False if m: try: replace = m.expand(replace) ok = True except re.error: pass if ok: pos = cursor.position() cursor.insertText(replace) cursor.setPosition(pos, QTextCursor.KeepAnchor) return ok def slotReplace(self): view = self.currentView() if view and self._positions: positions = [c.position() for c in self._positions] index = bisect.bisect_left(positions, view.textCursor().position()) if index >= len(positions): index = 0 if self.doReplace(self._positions[index]): viewhighlighter.highlighter(view).highlight("search", self._positions, 1) if index < len(positions) - 1: view.setTextCursor(self._positions[index+1]) else: view.setTextCursor(self._positions[0]) view.ensureCursorVisible() def slotReplaceAll(self): view = self.currentView() if view: replaced = False cursors = self._positions if view.textCursor().hasSelection(): cursors = [cursor for cursor in cursors if cursortools.contains(view.textCursor(), cursor)] view.textCursor().beginEditBlock() for cursor in cursors: if self.doReplace(cursor): replaced = True view.textCursor().endEditBlock() if replaced: viewhighlighter.highlighter(view).highlight("search", self._positions, 1)
class LCD20x4(PluginBase): MAX_LINE = 4 MAX_POSITION = 20 qtcb_pressed = pyqtSignal(int) qtcb_released = pyqtSignal(int) def __init__(self, ipcon, uid, version): PluginBase.__init__(self, ipcon, uid, 'LCD 20x4 Bricklet', version) self.version = version self.lcd = BrickletLCD20x4(uid, ipcon) self.hardware_version = (1, 0, 0) self.qtcb_pressed.connect(self.cb_pressed) self.lcd.register_callback(self.lcd.CALLBACK_BUTTON_PRESSED, self.qtcb_pressed.emit) self.qtcb_released.connect(self.cb_released) self.lcd.register_callback(self.lcd.CALLBACK_BUTTON_RELEASED, self.qtcb_released.emit) self.line_label = QLabel('Line: ') self.line_combo = QComboBox() for i in range(LCD20x4.MAX_LINE): self.line_combo.addItem(str(i)) self.pos_label = QLabel('Position: ') self.pos_combo = QComboBox() for i in range(LCD20x4.MAX_POSITION): self.pos_combo.addItem(str(i)) self.pos_layout = QHBoxLayout() self.pos_layout.addWidget(self.pos_label) self.pos_layout.addWidget(self.pos_combo) self.pos_layout.addStretch() self.line_layout = QHBoxLayout() self.line_layout.addWidget(self.line_label) self.line_layout.addWidget(self.line_combo) self.line_layout.addStretch() self.text_label = QLabel('Text: ') self.text_edit = QLineEdit(); self.text_edit.setMaxLength(LCD20x4.MAX_POSITION) self.text_button = QPushButton('Send Text') self.text_layout = QHBoxLayout() self.text_layout.addWidget(self.text_label) self.text_layout.addWidget(self.text_edit) self.text_layout.addWidget(self.text_button) self.clear_button = QPushButton("Clear Display") self.bl_button = QPushButton() self.cursor_button = QPushButton() self.blink_button = QPushButton() self.onofflayout = QHBoxLayout() self.onofflayout.addWidget(self.bl_button) self.onofflayout.addWidget(self.cursor_button) self.onofflayout.addWidget(self.blink_button) self.b0_label = QLabel('Button 0: Released,') self.b1_label = QLabel('Button 1: Released,') self.b2_label = QLabel('Button 2: Released,') self.b3_label = QLabel('Button 3: Released') self.buttonlayout = QHBoxLayout() self.buttonlayout.addWidget(self.b0_label) self.buttonlayout.addWidget(self.b1_label) self.buttonlayout.addWidget(self.b2_label) self.buttonlayout.addWidget(self.b3_label) self.cursor_button.pressed.connect(self.cursor_pressed) self.blink_button.pressed.connect(self.blink_pressed) self.clear_button.pressed.connect(self.clear_pressed) self.bl_button.pressed.connect(self.bl_pressed) self.text_button.pressed.connect(self.text_pressed) if self.version >= (2, 0, 1): line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) gridlayout = QGridLayout() gridlayout.setHorizontalSpacing(2) gridlayout.setVerticalSpacing(2) self.character_boxes_bool = [] self.character_boxes = [] for i in range(5): self.character_boxes.append([]) self.character_boxes_bool.append([]) for j in range(8): b = QToolButton() b.setAutoFillBackground(True) b.setStyleSheet("background-color: rgb(255, 255, 255)") b.setMaximumSize(25, 25) b.setMinimumSize(25, 25) def get_lambda(i, j): return lambda: self.char_button_pressed(i, j) b.pressed.connect(get_lambda(i, j)) self.character_boxes[i].append(b) self.character_boxes_bool[i].append(True) gridlayout.addWidget(b, j, i) self.char_index_label = QLabel('Index:') self.char_index_combo = QComboBox() self.char_index_combo.currentIndexChanged.connect(self.char_index_changed) for i in range(8): self.char_index_combo.addItem(str(i)) self.char_index_layout = QHBoxLayout() self.char_index_layout.addStretch() self.char_index_layout.addWidget(self.char_index_label) self.char_index_layout.addWidget(self.char_index_combo) self.char_index_layout.addStretch() self.char_index_save = QPushButton('Save Character') self.char_index_save.pressed.connect(self.char_index_save_pressed) self.char_show = QPushButton('Show all Custom Characters on LCD') self.char_show.pressed.connect(self.show_pressed) self.char_save_layout = QVBoxLayout() self.char_save_layout.addStretch() self.char_save_layout.addLayout(self.char_index_layout) self.char_save_layout.addWidget(self.char_index_save) self.char_save_layout.addWidget(self.char_show) self.char_save_layout.addStretch() grid_stretch_layout = QHBoxLayout() grid_stretch_layout.addWidget(QLabel('Custom Character: ')) grid_stretch_layout.addLayout(gridlayout) grid_stretch_layout.addLayout(self.char_save_layout) grid_stretch_layout.addStretch() self.char_main_layout = QHBoxLayout() self.char_main_layout.addStretch() self.char_main_layout.addLayout(grid_stretch_layout) self.char_main_layout.addStretch() self.char_main_layoutv = QVBoxLayout() self.char_main_layoutv.addLayout(self.char_main_layout) self.char_main_layoutv.addWidget(QLabel('Use "\\0, \\1, ..., \\7" in text field to show custom characters.')) layout = QVBoxLayout(self) layout.addLayout(self.line_layout) layout.addLayout(self.pos_layout) layout.addLayout(self.text_layout) layout.addWidget(self.clear_button) layout.addLayout(self.onofflayout) layout.addLayout(self.buttonlayout) if self.version >= (2, 0, 1): layout.addWidget(line) layout.addLayout(self.char_main_layoutv) layout.addStretch(1) def char_button_pressed(self, i, j): if self.character_boxes_bool[i][j]: self.character_boxes_bool[i][j] = False self.character_boxes[i][j].setStyleSheet("background-color: rgb(0, 0, 255)") else: self.character_boxes_bool[i][j] = True self.character_boxes[i][j].setStyleSheet("background-color: rgb(255, 255, 255)") def is_backlight_on_async(self, on): if on: self.bl_button.setText('Backlight Off') else: self.bl_button.setText('Backlight On') def get_config_async(self, config): cursor, blink = config if cursor: self.cursor_button.setText('Cursor Off') else: self.cursor_button.setText('Cursor On') if blink: self.blink_button.setText('Blink Off') else: self.blink_button.setText('Blink On') def start(self): async_call(self.lcd.is_backlight_on, None, self.is_backlight_on_async, self.increase_error_count) async_call(self.lcd.get_config, None, self.get_config_async, self.increase_error_count) def stop(self): pass def get_url_part(self): return 'lcd_20x4_v{0}{1}'.format(self.hardware_version[0], self.hardware_version[1]) def is_hardware_version_relevant(self, hardware_version): # FIXME: hack to avoid passing the hardware_version to all plugins self.hardware_version = hardware_version if hardware_version <= (1, 1, 0): self.b3_label.hide() return True @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickletLCD20x4.DEVICE_IDENTIFIER def cb_pressed(self, button): if button == 0: self.b0_label.setText('Button 0: Pressed,') elif button == 1: self.b1_label.setText('Button 1: Pressed,') elif button == 2: self.b2_label.setText('Button 2: Pressed,') elif button == 3: self.b3_label.setText('Button 3: Pressed') def cb_released(self, button): if button == 0: self.b0_label.setText('Button 0: Released,') elif button == 1: self.b1_label.setText('Button 1: Released,') elif button == 2: self.b2_label.setText('Button 2: Released,') elif button == 3: self.b3_label.setText('Button 3: Released') def bl_pressed(self): try: if self.bl_button.text() == 'Backlight On': self.lcd.backlight_on() self.bl_button.setText('Backlight Off') else: self.lcd.backlight_off() self.bl_button.setText('Backlight On') except ip_connection.Error: return def get_config(self): cursor = self.cursor_button.text() == 'Cursor Off' blink = self.blink_button.text() == 'Blink Off' return (cursor, blink) def cursor_pressed(self): cursor, blink = self.get_config() try: self.lcd.set_config(not cursor, blink) except ip_connection.Error: return if cursor: self.cursor_button.setText('Cursor On') else: self.cursor_button.setText('Cursor Off') def blink_pressed(self): cursor, blink = self.get_config() try: self.lcd.set_config(cursor, not blink) except ip_connection.Error: return if blink: self.blink_button.setText('Blink On') else: self.blink_button.setText('Blink Off') def clear_pressed(self): try: self.lcd.clear_display() except ip_connection.Error: return def text_pressed(self): line = int(self.line_combo.currentText()) position = int(self.pos_combo.currentText()) text = unicode(self.text_edit.text().toUtf8(), 'utf-8') if self.version >= (2, 0, 1): for i in range(8): text = text.replace('\\' + str(i), chr(i+8)) try: self.lcd.write_line(line, position, unicode_to_ks0066u(text)) except ip_connection.Error: return def char_index_save_pressed(self): char = [0]*8 for i in range(len(self.character_boxes)): for j in range(len(self.character_boxes[i])): if self.character_boxes_bool[i][j]: char[j] |= 1 << (4 - i) index = int(self.char_index_combo.currentText()) self.lcd.set_custom_character(index, char) def show_pressed(self): self.lcd.clear_display() line1 = '0:{0} 1:{1} 2:{2} 3:{3}'.format(chr(8), chr(9), chr(10), chr(11)) line2 = '4:{0} 5:{1} 6:{2} 7:{3}'.format(chr(12), chr(13), chr(14), chr(15)) self.lcd.write_line(0, 0, line1) self.lcd.write_line(1, 0, line2) def custom_character_async(self, characters): for i in range(len(self.character_boxes)): for j in range(len(self.character_boxes[i])): if characters[j] & (1 << i): self.character_boxes_bool[4-i][j] = True self.character_boxes[4-i][j].setStyleSheet("background-color: rgb(255, 255, 255)") else: self.character_boxes_bool[4-i][j] = False self.character_boxes[4-i][j].setStyleSheet("background-color: rgb(0, 0, 255)") def char_index_changed(self, index): async_call(self.lcd.get_custom_character, (index,), self.custom_character_async, self.increase_error_count)
def create_rows(self, layout): u"""Build the rows of the dialog box""" play_button_group = QButtonGroup(self) old_play_button_group = QButtonGroup(self) for num, entry in enumerate(self.entries_list, 3): tt_text = self.build_text_help_label(entry) ico_label = QLabel('', self) ico_label.setToolTip(tt_text) if entry.icon: ico_label.setPixmap(QPixmap.fromImage(entry.icon)) layout.addWidget(ico_label, num, 0) tt_label = QLabel(entry.display_word, self) tt_label.setToolTip(tt_text) layout.addWidget(tt_label, num, 1) if self.hide_text: tt_label.hide() # Play button. t_play_button = QPushButton(self) play_button_group.addButton(t_play_button, num - 3) t_play_button.setToolTip(self.play_help) t_play_button.setIcon(QIcon(os.path.join(icons_dir, 'play.png'))) layout.addWidget(t_play_button, num, self.play_column) if self.note[entry.audio_field_name]: t_play_old_button = QPushButton(self) old_play_button_group.addButton(t_play_old_button, num - 3) t_play_old_button.setIcon( QIcon(os.path.join(icons_dir, 'play.png'))) if not self.hide_text: t_play_old_button.setToolTip( self.note[entry.audio_field_name]) else: t_play_old_button.setToolTip(self.play_old_help_short) layout.addWidget(t_play_old_button, num, self.play_old_column) else: dummy_label = QLabel('', self) dummy_label.setToolTip(self.play_old_empty_line_help) layout.addWidget(dummy_label, num, self.play_old_column) # The group where we later look what to do: t_button_group = QButtonGroup(self) t_button_group.setExclusive(True) # Now the four buttons t_add_button = QPushButton(self) t_add_button.setCheckable(True) t_add_button.setFlat(True) t_add_button.setToolTip(self.add_help_text_short) t_add_button.setIcon(QIcon(os.path.join(icons_dir, 'add.png'))) layout.addWidget(t_add_button, num, self.add_column) t_button_group.addButton(t_add_button, Action.Add) t_keep_button = QPushButton(self) t_keep_button.setCheckable(True) t_keep_button.setFlat(True) t_keep_button.setToolTip(self.keep_help_text_short) t_keep_button.setIcon(QIcon(os.path.join(icons_dir, 'keep.png'))) layout.addWidget(t_keep_button, num, self.keep_column) t_button_group.addButton(t_keep_button, Action.Keep) t_delete_button = QPushButton(self) t_delete_button.setCheckable(True) t_delete_button.setFlat(True) t_delete_button.setToolTip(self.delete_help_text_short) t_delete_button.setIcon( QIcon(os.path.join(icons_dir, 'delete.png'))) layout.addWidget(t_delete_button, num, self.delete_column) t_button_group.addButton(t_delete_button, Action.Delete) t_blacklist_button = QPushButton(self) t_blacklist_button.setCheckable(True) t_blacklist_button.setFlat(True) t_blacklist_button.setToolTip(self.blacklist_help_text_short) t_blacklist_button.setIcon( QIcon(os.path.join(icons_dir, 'blacklist.png'))) if entry.entry_hash: layout.addWidget( t_blacklist_button, num, self.blacklist_column) else: t_blacklist_button.hide() dummy_label_bl = QLabel('', self) dummy_label_bl.setToolTip(self.blacklist_empty_line_help) layout.addWidget(dummy_label_bl, num, self.blacklist_column) t_button_group.button(entry.action).setChecked(True) # New: check a button based on how good the downloader is. t_button_group.addButton(t_blacklist_button, Action.Blacklist) self.buttons_groups.append(t_button_group) play_button_group.buttonClicked.connect( lambda button: play( self.entries_list[play_button_group.id(button)].file_path)) # N.B.: anki.sound.play() plays files from anywhere, not just # from the colection.media folder. We should be good, # here. (This behaviour may be a security risk, idk.) old_play_button_group.buttonClicked.connect( lambda button: playFromText( self.note[ self.entries_list[ old_play_button_group.id(button)].audio_field_name]))
class GenericParameterWidget(QWidget, object): """Widget class for generic parameter.""" def __init__(self, parameter, parent=None): """Constructor .. versionadded:: 2.2 :param parameter: A Generic object. :type parameter: GenericParameter """ QWidget.__init__(self, parent) self._parameter = parameter # Create elements # Label (name) self._label = QLabel(self._parameter.name) # Label (help text) self._help_text_label = QLabel(self._parameter.help_text) self._help_text_label.setWordWrap(True) # Label (description) self._description_label = QLabel(self._parameter.description) self._description_label.setWordWrap(True) self._description_label.hide() # Flag for show-status of description self._hide_description = True # Tool button for showing and hide detail description self._switch_button = QToolButton() self._switch_button.setArrowType(4) # 2=down arrow, 4=right arrow # noinspection PyUnresolvedReferences self._switch_button.clicked.connect(self.show_hide_description) self._switch_button.setToolTip('Click for detail description') self._switch_button_stylesheet = 'border: none;' self._switch_button.setStyleSheet(self._switch_button_stylesheet) # Layouts self._main_layout = QVBoxLayout() self._input_layout = QHBoxLayout() self._help_layout = QGridLayout() # _inner_input_layout must be filled with widget in the child class self._inner_input_layout = QHBoxLayout() self._inner_help_layout = QVBoxLayout() # spacing self._main_layout.setSpacing(0) self._input_layout.setSpacing(0) self._help_layout.setSpacing(0) self._inner_input_layout.setSpacing(7) self._inner_help_layout.setSpacing(0) # Put elements into layouts self._input_layout.addWidget(self._label) self._input_layout.addLayout(self._inner_input_layout) # self._input_layout.addSpacing(100) self._help_layout.addWidget(self._switch_button, 0, 0) self._help_layout.addWidget(self._help_text_label, 0, 1) self._help_layout.addWidget(self._description_label, 1, 1) self._main_layout.addLayout(self._input_layout) self._main_layout.addLayout(self._help_layout) self.setLayout(self._main_layout) self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.MinimumExpanding) def get_parameter(self): """Interface for returning parameter object. This must be implemented in child class. :raises: NotImplementedError """ raise NotImplementedError('Must be implemented in child class') def show_hide_description(self): """Show and hide long description.""" if self._hide_description: self._hide_description = False self._description_label.show() self._switch_button.setArrowType(2) self._switch_button.setToolTip('Click for hide detail description') else: self._hide_description = True self._description_label.hide() self._switch_button.setArrowType(4) self._switch_button.setToolTip('Click for detail description')
class GenericParameterWidget(QWidget, object): """Widget class for generic parameter.""" def __init__(self, parameter, parent=None): """Constructor .. versionadded:: 2.2 :param parameter: A Generic object. :type parameter: GenericParameter """ QWidget.__init__(self, parent) self._parameter = parameter # Create elements # Label (name) self.label = QLabel(self._parameter.name) # Label (description text) # Hacky fix for #1830 - checking the base type if isinstance(self._parameter.description, basestring): self.description_text_label = QLabel(self._parameter.description) else: self.description_text_label = QLabel() self.description_text_label.setWordWrap(True) # Label (help) self.help_label = QLabel(self._parameter.help_text) self.help_label.setWordWrap(True) self.help_label.hide() # Flag for show-status of help self._hide_help = True # Tool button for showing and hide detail help self.switch_button = QToolButton() self.switch_button.setArrowType(4) # 2=down arrow, 4=right arrow # noinspection PyUnresolvedReferences self.switch_button.clicked.connect(self.show_hide_help) self.switch_button.setToolTip('Click for detail help') self.switch_button_stylesheet = 'border: none;' self.switch_button.setStyleSheet(self.switch_button_stylesheet) # Layouts self.main_layout = QVBoxLayout() self.input_layout = QHBoxLayout() self.help_layout = QGridLayout() # _inner_input_layout must be filled with widget in the child class self.inner_input_layout = QHBoxLayout() self.inner_help_layout = QVBoxLayout() # spacing self.main_layout.setSpacing(0) self.main_layout.setContentsMargins(0, 0, 0, 0) self.input_layout.setSpacing(0) self.input_layout.setContentsMargins(0, 0, 0, 0) self.help_layout.setSpacing(0) self.help_layout.setContentsMargins(0, 0, 0, 0) self.inner_input_layout.setSpacing(7) self.inner_input_layout.setContentsMargins(0, 0, 0, 0) self.inner_help_layout.setSpacing(0) self.inner_help_layout.setContentsMargins(0, 0, 0, 0) # Put elements into layouts self.input_layout.addWidget(self.label) self.input_layout.addLayout(self.inner_input_layout) if self._parameter.description: self.help_layout.addWidget(self.description_text_label, 0, 1) if self._parameter.help_text: self.help_layout.addWidget(self.switch_button, 0, 0) self.help_layout.addWidget(self.help_label, 1, 1) self.main_layout.addLayout(self.input_layout) self.main_layout.addLayout(self.help_layout) self.setLayout(self.main_layout) self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.MinimumExpanding) def get_parameter(self): """Interface for returning parameter object. This must be implemented in child class. :raises: NotImplementedError """ raise NotImplementedError('Must be implemented in child class') def show_hide_help(self): """Show and hide long help.""" if self._hide_help: self._hide_help = False self.help_label.show() self.switch_button.setArrowType(2) self.switch_button.setToolTip('Click for hide detail help') else: self._hide_help = True self.help_label.hide() self.switch_button.setArrowType(4) self.switch_button.setToolTip('Click for detail help')
class PreprocessorModule(QWidget): """The base widget for the pre-processing modules.""" change_signal = Signal() # Emitted when the settings are changed. # Emitted when the module has a message to display in the main widget. error_signal = Signal(str) enabled = False # If the module is enabled. def __init__(self, title, toggle_enabled, is_enabled): super().__init__() # Title bar. title_holder = QWidget() title_holder.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed) title_holder.setStyleSheet(""" .QWidget { background: qlineargradient( x1:0 y1:0, x2:0 y2:1, stop:0 #F8F8F8, stop:1 #C8C8C8); border-bottom: 1px solid #B3B3B3; } """) self.titleArea = QHBoxLayout() self.titleArea.setContentsMargins(15, 10, 15, 10) self.titleArea.setSpacing(0) title_holder.setLayout(self.titleArea) self.title_label = QLabel(title) self.title_label.setStyleSheet('font-size: 12px;') self.titleArea.addWidget(self.title_label) self.off_label = QLabel('[disabled]') self.off_label.setStyleSheet('color: #B0B0B0; margin-left: 5px;') self.titleArea.addWidget(self.off_label) self.off_label.hide() self.titleArea.addStretch() # Root. self.rootArea = QVBoxLayout() self.rootArea.setContentsMargins(0, 0, 0, 0) self.rootArea.setSpacing(0) self.setLayout(self.rootArea) self.rootArea.addWidget(title_holder) self.contents = QWidget() contentArea = QVBoxLayout() contentArea.setContentsMargins(15, 10, 15, 10) self.contents.setLayout(contentArea) self.rootArea.addWidget(self.contents) self.enabled = is_enabled if toggle_enabled: self.toggle_module_switch = QCheckBox() switch_icon_on_resource = _i('on_button.png') switch_icon_off_resource = _i('off_button.png') style_sheet = ''' QCheckBox::indicator { width: 23px; height: 23px; } QCheckBox::indicator:checked { image: url(%s); } QCheckBox::indicator:unchecked { image: url(%s); } ''' % (switch_icon_on_resource, switch_icon_off_resource) self.toggle_module_switch.setStyleSheet(style_sheet) self.toggle_module_switch.setChecked(self.enabled) self.toggle_module_switch.stateChanged.connect(self.on_toggle) # Change the view according to the flag. if self.enabled: self.off_label.hide() self.contents.show() self.title_label.setStyleSheet('color: #000000;') else: self.off_label.show() self.contents.hide() self.title_label.setStyleSheet('color: #B0B0B0;') self.titleArea.addWidget(self.toggle_module_switch) def add_to_content_area(self, new_widget): self.contents.layout().addWidget(new_widget) def add_layout_to_content_area(self, new_layout): self.contents.layout().addLayout(new_layout) def notify_on_change(self): # Emits signals corresponding to the changes done. self.change_signal.emit() def on_toggle(self): # Activated when the widget is enabled/disabled. self.enabled = not self.enabled if self.enabled: self.off_label.hide() self.contents.show() self.title_label.setStyleSheet('color: #000000;') else: self.off_label.show() self.contents.hide() self.title_label.setStyleSheet('color: #B0B0B0;') self.change_signal.emit() def restore_data(self, data): # Restores the widget state from the input data. raise NotImplementedError def export_data(self): # Export the settings for this module instance. return NotImplementedError @staticmethod def get_pp_settings(): # Returns the dict representation of this portion of a pre-processor. return NotImplementedError
class Stopat(QWidget): def __init__(self, images, parent=None, options = None): QWidget.__init__(self, parent) self.images = images self.options = options self.info = QFrame() self.mediacache = [] self.threads = [] self.synced = True LL0 = dict(lab=None, lag=None) self.elems = dict( at =dict(up=LL0, bl=LL0, br=LL0), # up, bottom-left, bottom-right after=dict(s1=LL0, s2=LL0, s3=LL0), # 1st stop, 2nd stop, 3rd stop ) self.bgs =dict(unregistered="bg-"+WSU+".jpg", registered="bg-noinfo2-"+WSU+".jpg", disconnected="bg-"+WSU+".jpg", connected="bg-noinfo2-"+WSU+".jpg") self.tags_l1 = ('at', 'after') for t in self.tags_l1: self.bgs[t] = BG_STYLE if self.images is None else "background-image:url(" + self.images[t] + ");" self.set_bg("unregistered") self.setContentsMargins(0, 0, 0, 0) self.route = self.setlabel(None, 'route', Qt.AlignCenter) self.tags_l2 = dict( at=dict( # up, bottom-left, bottom-right up=dict(text=None, lag=None, align=Qt.AlignCenter), bl=dict(text=TS_TEXT, lag=None, align=(Qt.AlignVCenter|Qt.AlignLeft)), br=dict(text=None, lag=None, align=(Qt.AlignVCenter|Qt.AlignLeft)), ), after=dict( # 1st stop, 2nd stop, 3rd stop s1=dict(text=None, lag=None, align=Qt.AlignCenter), s2=dict(text=None, lag=0, align=Qt.AlignVCenter|Qt.AlignLeft), s3=dict(text=None, lag=0, align=Qt.AlignVCenter|Qt.AlignLeft), ) ) for t1 in self.tags_l1: for t2 in self.tags_l2[t1]: v = self.tags_l2[t1][t2] self.elems[t1][t2] = self.setlabel(v['text'], t2, v['align'], v['lag']) for t1 in self.elems: # hide them all for t2 in self.elems[t1]: for t3 in self.elems[t1][t2]: v = self.elems[t1][t2][t3] if v is not None: v.hide() self.sw_label = QLabel(PROGNAME+"-"+SW_VERSION, self.info) self.sw_label.setStyleSheet(stop_css['version']['style']) self.sw_label.setGeometry(stop_css['version']['geom']['x'], stop_css['version']['geom']['y'], stop_css['version']['geom']['w'], stop_css['version']['geom']['h']) self.sw_timer = QTimer() self.sw_timer.timeout.connect(self.rm_sw) self.sw_timer.start(5000) self.box = QHBoxLayout() self.box.setSpacing(0) self.box.setContentsMargins(0, 0, 0, 0) self.box.addWidget(self.info) self.setLayout(self.box) # audio only (without any video out, without window, i.e. some background audio) self.player = vlc.MediaPlayer(vlc.Instance()) if self.options is None else vlc.MediaPlayer(vlc.Instance(self.options)) def rm_sw(self): self.sw_label.hide() self.sw_timer.stop() def look_in_cache(self, filename, timestamp): for k in self.mediacache: if (k['fn'] == filename) and (k['ts'] == timestamp): return k['path'] return None def getter(self, url, fpath): try: re = urllib.request.urlretrieve(url, fpath) except urllib.error.ContentTooShortError as err: print_n_log("Got truncated data: {} ({})".forma(err.msg, url)) except urllib.error.HTTPError as err: print_n_log("Got HTTP error: {} {} ({})".format(err.code, err.reason, url)) except urllib.error.URLError as err: print_n_log("Got URL error: {} ({})".format(err.reason, url)) def squeeze_threads_out(self): for t in self.threads: if not t['thr'].isAlive(): t['thr'].handled = True self.threads = [t for t in self.threads if not t['thr'].handled] # remove finished threads def in_progress(self, url): for t in self.threads: if t['thr'].isAlive(): if t['url'] == url: return True return False def is_it_localmedia(self, rid, sid, category, url, timestamp, retrieve = True): filename = os.path.basename(url) cached = self.look_in_cache(filename, timestamp) if cached is not None: return (True, cached) if len(self.threads) > 0: # squeeze threads out by the way self.threads = [t for t in self.threads if t['thr'].isAlive()] if self.in_progress(url): print_n_log("Retrieving", url, "in progress..") return (False, None) ldir = MEDIA_DIR + str(rid) fpath = "{}/{:02d}-{}-{}-{}".format(ldir, sid, category, timestamp, filename) if os.path.isfile(fpath): self.mediacache.append(dict(fn=filename, ts=timestamp, path=fpath)) return (True, fpath) else: if retrieve: if not os.path.isdir(ldir): try: os.makedirs(ldir, exist_ok=True) except OSError as e: print_n_log(e) return (False, None) print_n_log("Retrieve", url, "as", fpath) t = threading.Thread(target=self.getter, args=(url, fpath)) t.start() self.threads.append(dict(thr=t, url=url)) return (False, None) def check_all_media(self, data, callback): for m in data: url = m.get('url', None) rid = m.get('rid', None) sid = m.get('sid', None) cat = m.get('category', None) ts = m.get('timestamp', None) hsum = m.get('hash', None) if all(v is not None for v in (rid, sid, cat, url, ts, hsum)): if not callback(rid, sid, cat, url, ts, hsum): return False else: print_n_log("Not enough attributes (url/rid/sid/cat/ts) in:", m) return False return True def is_it_actual(self, lfile, hsum, ts): if not os.path.isfile(lfile): return False try: lsum = hashlib.md5(open(lfile,'rb').read()).hexdigest() except Exception as e: print_n_log("Got hashlib exception:", e) return False if hsum != lsum: print_n_log("hash error:", hsum, lsum) return False else: return True def local_or_retrieve(self, rid, sid, cat, url, ts, hsum): its_local, localfile = self.is_it_localmedia(rid, sid, cat, url, ts) if its_local: if not self.is_it_actual(localfile, hsum, ts): try: os.remove(localfile) self.is_it_localmedia(rid, sid, cat, url, ts) except OSError as e: if e.errno != errno.ENOENT: print_n_log("IO error:", e) return False return True def only_localmedia(self, rid, sid, cat, url, ts, hsum): its_local, localfile = self.is_it_localmedia(rid, sid, cat, url, ts, retrieve = False) if its_local: if self.is_it_actual(localfile, hsum, ts): return True return False def savemedia(self, data): sync = 0 while sync < 3: sync += 1 start_tm = time.time() again = "" if sync == 1 else "again" print_n_log("Syncing {}...".format(again)) if not self.check_all_media(data, self.local_or_retrieve): continue for t in self.threads: t['thr'].join() if self.check_all_media(data, self.only_localmedia): print_n_log("Elapsed synchronization time:", (time.time() - start_tm)) self.synced = True return self.synced print_n_log("Synchronization failed") self.synced = False return self.synced def is_synced(self): return self.synced def playnsave(self, rid, sid, category, url, timestamp): # vlc http://dl6.mp3party.net/download/7952427 --vout dummy --sout "#duplicate{dst=std{access=file,mux=raw,dst=OUT.mp3},dst=display" --sout-all if (not isinstance(rid, int)) or (not isinstance(sid, int)): print_n_log("RouteID and StopID must be INT:", ris, sid) return its_local, localfile = self.is_it_localmedia(rid, sid, category, url, timestamp) item = localfile if its_local else url self.playfile(dict(file=item), True if its_local else None) def playfile(self, media, cached=None): if self.player.is_playing(): print_n_log("Stop playing") self.player.stop() sfx = "" if self.options is None else ", options: "+self.options pfx = "" if cached is None else "(cached)" print_n_log("Play" + pfx + ": " + media['file'] + sfx) self.player.set_mrl(media['file']) if self.options is None else self.player.set_mrl(media['file'], self.options) self.player.play() i = 0 while (not self.player.is_playing()) and (i < 6): # wait for start upto 3sec time.sleep(0.5) i += 1 def setlabel(self, txt, tag, align, lag = None): lab = QLabel(txt, self.info) lab.setAlignment(align) lab.setStyleSheet(stop_css[tag]['style']) lab.setGeometry(stop_css[tag]['geom']['x'], stop_css[tag]['geom']['y'], stop_css[tag]['geom']['w'], stop_css[tag]['geom']['h']) lab.setWordWrap(True) # f = QFont(BASE_FF) # f.setStretch(110) #QFont.SemiExpanded) # f.setWeight(800) #QFont.Black) # f.setLetterSpacing(QFont.PercentageSpacing, 110) # lab.setFont(f) lag_lab = None if lag is not None: lag_lab = QLabel(str(lag)+" хв", self.info) lag_lab.setAlignment(Qt.AlignVCenter|Qt.AlignRight) lag_lab.setStyleSheet(stop_css[tag]['lag']['style']) lag_lab.setGeometry(stop_css[tag]['lag']['geom']['x'], stop_css[tag]['lag']['geom']['y'], stop_css[tag]['lag']['geom']['w'], stop_css[tag]['lag']['geom']['h']) return dict(lab=lab, lag=lag_lab) def change_display(self, active, inactive): for t in self.elems[active]: self.elems[active][t]['lab'].show() ll = self.elems[active][t].get('lag', None) if ll is not None: ll.show() for t in self.elems[inactive]: self.elems[inactive][t]['lab'].hide() ll = self.elems[inactive][t].get('lag', None) if ll is not None: ll.hide() def display_stop(self, stop, elem): (name, eta) = ('', 0) if stop is None else (stop.get('name', None), stop.get('lag', None)) if name is not None: lab = elem.get('lab', None) if lab is not None: lab.setText(name.upper()) if eta is not None: lag = elem.get('lag', None) if lag is not None: eta_txt = '' if name == '' else str(round((eta+0.1)/60))+" хв" lag.setText(eta_txt) def set_stops(self, tag, stops): ina = 'after' if tag == 'at' else 'at' if tag == 'at': self.display_stop(stops['s1'], self.elems[tag]['up']) self.display_stop(stops['s2'], self.elems[tag]['br']) elif tag == 'after': self.display_stop(stops['s2'], self.elems[tag]['s1']) self.display_stop(stops['s3'], self.elems[tag]['s2']) self.display_stop(stops['s4'], self.elems[tag]['s3']) self.change_display(tag, ina) self.info.setStyleSheet(self.bgs[tag]) self.info.update() def set_title(self, text): self.route['lab'].setText(text) def set_bg(self, tag): if tag in self.bgs: print_n_log("Set background:", BASE_DIR+self.bgs[tag]) self.info.setStyleSheet("background-image:url("+BASE_DIR+self.bgs[tag]+");")
class XLoaderWidget(QWidget): """ """ Mode = enum('Spinner', 'Progress') MOVIE = None def __init__( self, parent = None, style='gray' ): super(XLoaderWidget, self).__init__( parent ) # define properties self._currentMode = None self._showSubProgress = False self.setAttribute(Qt.WA_DeleteOnClose) # udpate the palette palette = self.palette() if style == 'white': palette.setColor( palette.Window, QColor(255, 255, 255, 180) ) else: palette.setColor( palette.Window, QColor( 80, 80, 80, 180 ) ) palette.setColor( palette.Base, Qt.gray ) palette.setColor( palette.AlternateBase, Qt.lightGray ) palette.setColor( palette.WindowText, Qt.gray ) self.setPalette(palette) # create the movie label self._movieLabel = QLabel(self) self._movieLabel.setAlignment(Qt.AlignCenter) self._movieLabel.setMovie(XLoaderWidget.getMovie()) self._movieLabel.setPalette(palette) self._smallMovieLabel = QLabel(self) self._smallMovieLabel.setAlignment(Qt.AlignCenter) self._smallMovieLabel.setMovie(XLoaderWidget.getMovie()) self._smallMovieLabel.setPalette(palette) self._smallMovieLabel.hide() # create text label self._messageLabel = QLabel(self) self._messageLabel.setAlignment(Qt.AlignCenter) self._messageLabel.setText('Loading...') self._messageLabel.setPalette(palette) # create primary progress bar self._primaryProgressBar = XLoaderProgressBar(self) self._subProgressBar = XLoaderProgressBar(self) self._primaryProgressBar.setPalette(palette) self._subProgressBar.setPalette(palette) # create the loader widget self._loaderFrame = QFrame(self) self._loaderFrame.setFrameShape(QFrame.Box) self._loaderFrame.setAutoFillBackground(True) self._loaderFrame.setFixedWidth(160) self._loaderFrame.setFixedHeight(60) if style == 'white': palette.setColor(palette.Window, QColor('white')) else: palette.setColor(palette.Window, QColor(85, 85, 85)) self._loaderFrame.setPalette(palette) layout = QVBoxLayout() layout.addWidget(self._movieLabel) layout.addWidget(self._primaryProgressBar) layout.addWidget(self._subProgressBar) layout.addStretch() layout.addWidget(self._messageLabel) self._loaderFrame.setLayout(layout) # set default properties self.setAutoFillBackground(True) # layout the controls layout = QVBoxLayout() layout.addStretch(1) layout.addWidget(self._loaderFrame) layout.addWidget(self._smallMovieLabel) layout.addStretch(1) hlayout = QHBoxLayout() hlayout.addStretch(1) hlayout.addLayout(layout) hlayout.addStretch(1) self.setLayout(hlayout) self.setCurrentMode(XLoaderWidget.Mode.Spinner) # create connections def currentMode( self ): """ Returns the current mode that this loader's in. :return <XLoaderWidget.Mode> """ return self._currentMode def eventFilter( self, object, event ): """ Resizes this widget with the parent when its resize event is triggered. :param object | <QObject> event | <QEvent> :return <bool> | consumed """ if event.type() == event.Resize: self.resize(event.size()) elif event.type() == event.Move: self.move(event.pos()) elif event.type() == event.Close: self.setParent(None) self.deleteLater() return False def increment( self, amount=1): """ Increments the main progress bar by amount. """ self._primaryProgressBar.setValue(self.value() + amount) def incrementSub( self, amount=1): """ Increments the sub-progress bar by amount. """ self._subProgressBar.setValue(self.subValue() + amount) def message( self ): """ Returns the current message being displayed in the loader. :return <str> """ return self._messageLabel.text() def movie(self): """ Returns the movie linked with this loader. :return <QMovie> """ return self._movieLabel.movie() def resize(self, size): """ Handles when the loader is too small for an area. :param event | <QResizeEvent> """ super(XLoaderWidget, self).resize(size) # show small loader if size.width() < self._loaderFrame.width() or \ size.height() < self._loaderFrame.height(): self._loaderFrame.hide() self._smallMovieLabel.show() # show regular loader else: self._loaderFrame.show() self._smallMovieLabel.hide() def subValue( self ): """ Returns the value of the sub progress bar. :return <int> """ return self._subProgressBar.value() def setCurrentMode( self, mode ): """ Sets what mode this loader will be in. :param mode | <XLoaderWidget.Mode> """ if ( mode == self._currentMode ): return self._currentMode = mode ajax = mode == XLoaderWidget.Mode.Spinner self._movieLabel.setVisible(ajax) self._primaryProgressBar.setVisible(not ajax) self._subProgressBar.setVisible(not ajax and self._showSubProgress) def setMessage( self, message ): """ Sets the loading message to display. :param message | <str> """ self._messageLabel.setText(message) def setMovie( self, movie ): """ Sets the movie for this loader to the inputed movie. :param movie | <QMovie> """ self._movieLabel.setMovie(movie) self._smallMovieLabel.setMovie(movie) def setTotal( self, amount ): """ Sets the total amount for the main progress bar. :param amount | <int> """ self._primaryProgressBar.setValue(0) self._primaryProgressBar.setMaximum(amount) if amount: self.setCurrentMode(XLoaderWidget.Mode.Progress) def setSubTotal( self, amount ): """ Sets the total value for the sub progress bar. :param amount | <int> """ self._subProgressBar.setValue(0) self._subProgressBar.setMaximum(amount) if amount: self.setShowSubProgress(True) def setSubValue( self, value ): """ Sets the current value for the sub progress bar. :param value | <int> """ self._subProgressBar.setValue(value) def setShowSubProgress( self, state ): """ Toggles whether or not the sub progress bar should be visible. :param state | <bool> """ ajax = self.currentMode() == XLoaderWidget.Mode.Spinner self._showSubProgress = state self._subProgressBar.setVisible(not ajax and state) def setValue(self, value): """ Sets the current value for the primary progress bar. :param value | <int> """ self._primaryProgressBar.setValue(value) def showSubProgress( self ): """ Returns whether or not the sub progress bar is visible when not in ajax mode. :return <bool> """ return self._showSubProgress def subValue( self ): """ Returns the sub value for this loader. :return <int> """ return self._subProgressBar.value() def value( self ): """ Returns the value for the primary progress bar. :return <int> """ return self._primaryProgressBar.value() @staticmethod def getMovie(): """ Returns the movie instance for the loader widget. :return <QMovie> """ if not XLoaderWidget.MOVIE: filename = projexui.resources.find('img/ajax_loader.gif') XLoaderWidget.MOVIE = QMovie() XLoaderWidget.MOVIE.setFileName(filename) XLoaderWidget.MOVIE.start() return XLoaderWidget.MOVIE @staticmethod def start(widget, processEvents=True, style=None, movie=None): """ Starts a loader widget on the inputed widget. :param widget | <QWidget> :return <XLoaderWidget> """ if style is None: style = os.environ.get('PROJEXUI_LOADER_STYLE', 'gray') # there is a bug with the way the loader is handled in a splitter, # so bypass it parent = widget.parent() while isinstance(parent, QSplitter): parent = parent.parent() # retrieve the loader widget loader = getattr(widget, '_private_xloader_widget', None) if not loader: loader = XLoaderWidget(parent, style) # make sure that if the widget is destroyed, the loader closes widget.destroyed.connect(loader.deleteLater) setattr(widget, '_private_xloader_widget', loader) setattr(widget, '_private_xloader_count', 0) loader.move(widget.pos()) if widget.isVisible(): loader.show() if movie: loader.setMovie(movie) widget.installEventFilter(loader) else: count = getattr(widget, '_private_xloader_count', 0) setattr(widget, '_private_xloader_count', count + 1) loader.resize(widget.size()) return loader @staticmethod def stop(widget, force=False): """ Stops a loader widget on the inputed widget. :param widget | <QWidget> """ # make sure we have a widget to stop loader = getattr(widget, '_private_xloader_widget', None) if not loader: return # decrement the number of times this loader was created for the widget # to allow for stacked closure count = getattr(widget, '_private_xloader_count', 0) if force or count <= 1: # close out the loader widget setattr(widget, '_private_xloader_count', 0) setattr(widget, '_private_xloader_widget', None) loader.close() loader.setParent(None) loader.deleteLater() else: setattr(widget, '_private_xloader_count', count - 1) @staticmethod def stopAll(widget): """ Stops all loader widgets from this parent down, cleaning out the \ memory for them. :param widget | <QWidget> """ for loader in widget.findChildren(XLoaderWidget): loader.setParent(None) loader.deleteLater()
class FindDialog(QDialog): def __init__(self,parent=None): logging.debug(__name__ +': __init__') QDialog.__init__(self,parent) self.setWindowFlags(Qt.Window) self.setWindowTitle("Find...") self._findAlgorithm=None self._properties=[] self._scripts=[] self._find=True self._filter=False self.fill() def fill(self): logging.debug(__name__ +': fill') self._findLabelLabel = QLabel("Label: ") self._findLabelLineEdit = QLineEdit() self._findLabelLineEdit.setToolTip("Example: Particle1") self._caseSensitiveCheckBox=QCheckBox("Case sensitive") self._exactMatchCheckBox=QCheckBox("Exact match") self._helpButton = QPushButton("&Help") self._findPreviousButton = QPushButton("&Previous") self._findPreviousButton.hide() self._findNumberLabel = QLabel("?/?") self._findNumberLabel.hide() self._findNextButton = QPushButton("&Find") self._filterButton = QPushButton("&Filter") self._resetButton = QPushButton("&Reset") self._closeButton = QPushButton("&Close") self.setLayout(QVBoxLayout()) self.layout().setSizeConstraint(QLayout.SetFixedSize) self._layout1=QHBoxLayout() self._layout3=QHBoxLayout() self._layout4=QHBoxLayout() self._layout1.setSizeConstraint(QLayout.SetDefaultConstraint) self._layout3.setSizeConstraint(QLayout.SetDefaultConstraint) self._layout4.setSizeConstraint(QLayout.SetDefaultConstraint) self.layout().addLayout(self._layout1) self.layout().addLayout(self._layout3) self.layout().addStretch() self.layout().addLayout(self._layout4) self._layout1.addWidget(self._findLabelLabel) self._layout1.addWidget(self._findLabelLineEdit) self._layout3.addWidget(self._helpButton) self._layout3.addStretch() self._layout3.addWidget(self._caseSensitiveCheckBox) self._layout3.addWidget(self._exactMatchCheckBox) self._layout4.addWidget(self._findPreviousButton) self._layout4.addWidget(self._findNumberLabel) self._layout4.addWidget(self._findNextButton) self._layout4.addWidget(self._filterButton) self._layout4.addWidget(self._resetButton) self._layout4.addStretch() self._layout4.addWidget(self._closeButton) self.connect(self._findLabelLineEdit, SIGNAL('textChanged(QString)'), self.edited) self.connect(self._caseSensitiveCheckBox, SIGNAL('stateChanged(int)'), self.edited) self.connect(self._exactMatchCheckBox, SIGNAL('stateChanged(int)'), self.edited) self.connect(self._findPreviousButton, SIGNAL('clicked(bool)'), self.findPrevious) self.connect(self._findNextButton, SIGNAL('clicked(bool)'), self.findNext) self.connect(self._filterButton, SIGNAL('clicked(bool)'), self.filter) self.connect(self._resetButton, SIGNAL('clicked(bool)'), self.reset) self.connect(self._helpButton, SIGNAL('clicked(bool)'), self.help) self.connect(self._closeButton, SIGNAL('clicked(bool)'), self.reject) self._addStringProperty(False,False) self._addScript(False,False) def _removeProperty(self): for property in self._properties: if self.sender() in property: self._remove(property) return def _remove(self,object): for o in object: if isinstance(o,QWidget): o.close() self.layout().removeItem(object[0]) if object in self._properties: self._properties.remove(object) elif object in self._scripts: self._scripts.remove(object) def _addStringProperty(self,bool,deletable=True): layout2=QHBoxLayout() findPropertyNameLabel = QLabel("Property: ") findPropertyNameLineEdit = QLineEdit() findPropertyNameLineEdit.setToolTip("Example: Label = Particle1 ") findPropertyValueLabel = QLabel(" = ") findPropertyValueLineEdit = QLineEdit() findPropertyValueLineEdit.setToolTip("Example: Label = Particle1 ") propertyAdd = QToolButton() propertyAdd.setText("+") propertyDelete = QToolButton() propertyDelete.setText("-") if deletable: propertyAdd.hide() else: propertyDelete.hide() layout2.addWidget(propertyAdd) layout2.addWidget(propertyDelete) layout2.addWidget(findPropertyNameLabel) layout2.addWidget(findPropertyNameLineEdit) layout2.addWidget(findPropertyValueLabel) layout2.addWidget(findPropertyValueLineEdit) self.connect(findPropertyNameLineEdit, SIGNAL('textChanged(QString)'), self.edited) self.connect(findPropertyValueLineEdit, SIGNAL('textChanged(QString)'), self.edited) self.connect(propertyAdd, SIGNAL('clicked(bool)'), self._addStringProperty) self.connect(propertyDelete, SIGNAL('clicked(bool)'), self._removeProperty) self.layout().insertLayout(len(self._properties)+len(self._scripts)+1,layout2) self._properties+=[(layout2,findPropertyNameLineEdit,findPropertyValueLineEdit,findPropertyNameLabel,findPropertyValueLabel,propertyAdd,propertyDelete)] def _removeScript(self): for script in self._scripts: if self.sender() in script: self._remove(script) return def _addScript(self,bool,deletable=True): layout2=QHBoxLayout() findScriptLabel = QLabel("Filter = ") findScriptLineEdit = QLineEdit("") findScriptLineEdit.setToolTip("Example: object.Label == 'Particle1' ") scriptAdd = QToolButton() scriptAdd.setText("+") scriptDelete = QToolButton() scriptDelete.setText("-") if deletable: scriptAdd.hide() else: scriptDelete.hide() layout2.addWidget(scriptAdd) layout2.addWidget(scriptDelete) layout2.addWidget(findScriptLabel) layout2.addWidget(findScriptLineEdit) self.connect(findScriptLineEdit, SIGNAL('textChanged(QString)'), self.edited) self.connect(scriptAdd, SIGNAL('clicked(bool)'), self._addScript) self.connect(scriptDelete, SIGNAL('clicked(bool)'), self._removeScript) self.layout().insertLayout(len(self._properties)+len(self._scripts)+1,layout2) self._scripts+=[(layout2,findScriptLineEdit,findScriptLabel,scriptAdd,scriptDelete)] def onScreen(self, filter=False, find=True): logging.debug(__name__ +': onScreen') self._find=find self._filter=filter if self._find and self._filter: self._findNextButton.setDefault(True) self.setWindowTitle("Find/Filter...") elif self._find: self._findNextButton.setDefault(True) self.setWindowTitle("Find...") elif self._filter: self._filterButton.setDefault(True) self.setWindowTitle("Filter...") self._findNextButton.setVisible(find) if not find: self._findPreviousButton.setVisible(find) self._filterButton.setVisible(filter) self.show() self.raise_() self.activateWindow() self._findLabelLineEdit.setFocus() def keyPressEvent(self, event): """ """ if event.modifiers() == Qt.ControlModifier and event.key() == Qt.Key_W: self.close() QDialog.keyPressEvent(self, event) def setFindAlgorithm(self,findAlgorithm): logging.debug(__name__ +': setFindAlgorithm') self._findAlgorithm=findAlgorithm def findAlgorithm(self): return self._findAlgorithm def label(self): return str(self._findLabelLineEdit.text().toAscii()) def setLabel(self,label): logging.debug(__name__ +': setLabel '+label) self._findLabelLineEdit.setText(label) def properties(self): return [(str(property[1].text().toAscii()),str(property[2].text().toAscii())) for property in self._properties] def scripts(self): return [str(script[1].text().toAscii()) for script in self._scripts] def caseSensitive(self): return self._caseSensitiveCheckBox.checkState()==Qt.Checked def exactMatch(self): return self._exactMatchCheckBox.checkState()==Qt.Checked def edited(self): self._findPreviousButton.hide() if self._findNextButton.isVisible(): self._findNumberLabel.hide() self._findNextButton.setText("&Find") def _updateNumberLabel(self): current=self._findAlgorithm.currentNumber() total=self._findAlgorithm.numberOfResults() message=self._findAlgorithm.message() text="" if self._filter: text=str(total)+" found" else: if total>0: text=str(current)+"/"+str(total) else: text="not found" if message: text+=" ("+message+")" self._findNumberLabel.setText(text) def findPrevious(self): logging.debug(__name__ +': findPrevious') object=self._findAlgorithm.previous() self._updateNumberLabel() self.emit(SIGNAL("found"),object) def findNext(self): logging.debug(__name__ +': findNext') if not self._findPreviousButton.isVisible(): self._findNextButton.setVisible(False) self._filterButton.setVisible(False) self._resetButton.setVisible(False) self._findNumberLabel.setText("Searching...") self._findNumberLabel.show() thread = ThreadChain(self._findAlgorithm.findUsingFindDialog, self) while thread.isRunning(): if not Application.NO_PROCESS_EVENTS: QCoreApplication.instance().processEvents() object=thread.returnValue() self._findNextButton.setVisible(True) if self._filter: self._filterButton.setVisible(True) self._resetButton.setVisible(True) self._findPreviousButton.show() self._findNextButton.setText("&Next") else: object=next(self._findAlgorithm) self._updateNumberLabel() self.emit(SIGNAL("found"),object) def filter(self): logging.debug(__name__ +': filter') self._findNextButton.setVisible(False) self._filterButton.setVisible(False) self._resetButton.setVisible(False) self._findNumberLabel.setText("Searching...") self._findNumberLabel.show() thread = ThreadChain(self._findAlgorithm.findUsingFindDialog, self) while thread.isRunning(): if not Application.NO_PROCESS_EVENTS: QCoreApplication.instance().processEvents() if self._find: self._findNextButton.setVisible(True) self._filterButton.setVisible(True) self._resetButton.setVisible(True) self._updateNumberLabel() self.emit(SIGNAL("filtered"),self._findAlgorithm.results()) def reset(self): self.setLabel("") for o in self._scripts+self._properties: self._remove(o) self._addStringProperty(False,False) self._addScript(False,False) self._findAlgorithm.clear() self._updateNumberLabel() if self._filter: self.emit(SIGNAL("filtered"),None) self.update() def help(self): QMessageBox.about(self, 'Info', "You can find objects \n1. using their label shown in the center view, \n2. their properties shown in the property view, or \n3. using a Python script returning a boolean. Empty fields are ignored. Examples are shown as tool tips.")
class LCD20x4(PluginBase): MAX_LINE = 4 MAX_POSITION = 20 qtcb_pressed = pyqtSignal(int) qtcb_released = pyqtSignal(int) def __init__(self, *args): PluginBase.__init__(self, BrickletLCD20x4, *args) self.lcd = self.device self.qtcb_pressed.connect(self.cb_pressed) self.lcd.register_callback(self.lcd.CALLBACK_BUTTON_PRESSED, self.qtcb_pressed.emit) self.qtcb_released.connect(self.cb_released) self.lcd.register_callback(self.lcd.CALLBACK_BUTTON_RELEASED, self.qtcb_released.emit) self.line_label = QLabel('Line: ') self.line_combo = QComboBox() for i in range(LCD20x4.MAX_LINE): self.line_combo.addItem(str(i)) self.pos_label = QLabel('Position: ') self.pos_combo = QComboBox() for i in range(LCD20x4.MAX_POSITION): self.pos_combo.addItem(str(i)) self.line_pos_layout = QHBoxLayout() self.line_pos_layout.addWidget(self.line_label) self.line_pos_layout.addWidget(self.line_combo) self.line_pos_layout.addWidget(self.pos_label) self.line_pos_layout.addWidget(self.pos_combo) self.line_pos_layout.addStretch() self.text_label = QLabel('Text: ') self.text_edit = QLineEdit() self.text_edit.setMaxLength(LCD20x4.MAX_POSITION) self.text_button = QPushButton('Send Text') self.text_layout = QHBoxLayout() self.text_layout.addWidget(self.text_label) self.text_layout.addWidget(self.text_edit) self.text_layout.addWidget(self.text_button) self.clear_button = QPushButton("Clear Display") self.bl_button = QPushButton() self.cursor_button = QPushButton() self.blink_button = QPushButton() self.onofflayout = QHBoxLayout() self.onofflayout.addWidget(self.bl_button) self.onofflayout.addWidget(self.cursor_button) self.onofflayout.addWidget(self.blink_button) self.b0_label = QLabel('Button 0: Released,') self.b1_label = QLabel('Button 1: Released,') self.b2_label = QLabel('Button 2: Released,') self.b3_label = QLabel('Button 3: Released') self.buttonlayout = QHBoxLayout() self.buttonlayout.addWidget(self.b0_label) self.buttonlayout.addWidget(self.b1_label) self.buttonlayout.addWidget(self.b2_label) self.buttonlayout.addWidget(self.b3_label) self.cursor_button.clicked.connect(self.cursor_clicked) self.blink_button.clicked.connect(self.blink_clicked) self.clear_button.clicked.connect(self.clear_clicked) self.bl_button.clicked.connect(self.bl_clicked) self.text_button.clicked.connect(self.text_clicked) if self.firmware_version >= (2, 0, 1): line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) gridlayout = QGridLayout() gridlayout.setHorizontalSpacing(2) gridlayout.setVerticalSpacing(2) self.character_boxes_bool = [] self.character_boxes = [] for i in range(5): self.character_boxes.append([]) self.character_boxes_bool.append([]) for j in range(8): b = QToolButton() b.setAutoFillBackground(True) b.setStyleSheet("background-color: rgb(255, 255, 255)") b.setMaximumSize(25, 25) b.setMinimumSize(25, 25) def get_lambda(i, j): return lambda: self.char_button_clicked(i, j) b.clicked.connect(get_lambda(i, j)) self.character_boxes[i].append(b) self.character_boxes_bool[i].append(True) gridlayout.addWidget(b, j, i) self.char_index_label = QLabel('Index:') self.char_index_combo = QComboBox() self.char_index_combo.currentIndexChanged.connect( self.char_index_changed) for i in range(8): self.char_index_combo.addItem(str(i)) self.char_index_layout = QHBoxLayout() self.char_index_layout.addStretch() self.char_index_layout.addWidget(self.char_index_label) self.char_index_layout.addWidget(self.char_index_combo) self.char_index_layout.addStretch() self.char_index_save = QPushButton('Save Character') self.char_index_save.clicked.connect(self.char_index_save_clicked) self.char_show = QPushButton('Show all Custom Characters on LCD') self.char_show.clicked.connect(self.show_clicked) self.char_save_layout = QVBoxLayout() self.char_save_layout.addStretch() self.char_save_layout.addLayout(self.char_index_layout) self.char_save_layout.addWidget(self.char_index_save) self.char_save_layout.addWidget(self.char_show) help_label = QLabel( 'Use "\\0, \\1, ..., \\7" in text field to show custom characters.' ) help_label.setWordWrap(True) self.char_save_layout.addWidget(help_label) self.char_save_layout.addStretch() grid_stretch_layout = QHBoxLayout() grid_stretch_layout.addWidget(QLabel('Custom Character: ')) grid_stretch_layout.addLayout(gridlayout) grid_stretch_layout.addLayout(self.char_save_layout) grid_stretch_layout.addStretch() self.char_main_layout = QHBoxLayout() self.char_main_layout.addStretch() self.char_main_layout.addLayout(grid_stretch_layout) self.char_main_layout.addStretch() layout = QVBoxLayout(self) layout.addLayout(self.line_pos_layout) layout.addLayout(self.text_layout) layout.addWidget(self.clear_button) layout.addLayout(self.onofflayout) layout.addLayout(self.buttonlayout) if self.hardware_version <= (1, 1, 0): self.b3_label.hide() if self.firmware_version >= (2, 0, 1): layout.addWidget(line) layout.addLayout(self.char_main_layout) layout.addStretch(1) def char_button_clicked(self, i, j): if self.character_boxes_bool[i][j]: self.character_boxes_bool[i][j] = False self.character_boxes[i][j].setStyleSheet( "background-color: rgb(0, 0, 255)") else: self.character_boxes_bool[i][j] = True self.character_boxes[i][j].setStyleSheet( "background-color: rgb(255, 255, 255)") def is_backlight_on_async(self, on): if on: self.bl_button.setText('Backlight Off') else: self.bl_button.setText('Backlight On') def get_config_async(self, config): cursor, blink = config if cursor: self.cursor_button.setText('Cursor Off') else: self.cursor_button.setText('Cursor On') if blink: self.blink_button.setText('Blink Off') else: self.blink_button.setText('Blink On') def start(self): async_call(self.lcd.is_backlight_on, None, self.is_backlight_on_async, self.increase_error_count) async_call(self.lcd.get_config, None, self.get_config_async, self.increase_error_count) def stop(self): pass def destroy(self): pass def get_url_part(self): return 'lcd_20x4_v{0}{1}'.format(self.hardware_version[0], self.hardware_version[1]) def is_hardware_version_relevant(self): return True @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickletLCD20x4.DEVICE_IDENTIFIER def cb_pressed(self, button): if button == 0: self.b0_label.setText('Button 0: Pressed,') elif button == 1: self.b1_label.setText('Button 1: Pressed,') elif button == 2: self.b2_label.setText('Button 2: Pressed,') elif button == 3: self.b3_label.setText('Button 3: Pressed') def cb_released(self, button): if button == 0: self.b0_label.setText('Button 0: Released,') elif button == 1: self.b1_label.setText('Button 1: Released,') elif button == 2: self.b2_label.setText('Button 2: Released,') elif button == 3: self.b3_label.setText('Button 3: Released') def bl_clicked(self): try: if self.bl_button.text() == 'Backlight On': self.lcd.backlight_on() self.bl_button.setText('Backlight Off') else: self.lcd.backlight_off() self.bl_button.setText('Backlight On') except ip_connection.Error: return def get_config(self): cursor = self.cursor_button.text() == 'Cursor Off' blink = self.blink_button.text() == 'Blink Off' return (cursor, blink) def cursor_clicked(self): cursor, blink = self.get_config() try: self.lcd.set_config(not cursor, blink) except ip_connection.Error: return if cursor: self.cursor_button.setText('Cursor On') else: self.cursor_button.setText('Cursor Off') def blink_clicked(self): cursor, blink = self.get_config() try: self.lcd.set_config(cursor, not blink) except ip_connection.Error: return if blink: self.blink_button.setText('Blink On') else: self.blink_button.setText('Blink Off') def clear_clicked(self): try: self.lcd.clear_display() except ip_connection.Error: return def text_clicked(self): line = int(self.line_combo.currentText()) position = int(self.pos_combo.currentText()) text = self.text_edit.text() if self.firmware_version >= (2, 0, 1): for i in range(8): text = text.replace('\\' + str(i), chr(i + 8)) try: self.lcd.write_line(line, position, unicode_to_ks0066u(text)) except ip_connection.Error: return def char_index_save_clicked(self): char = [0] * 8 for i in range(len(self.character_boxes)): for j in range(len(self.character_boxes[i])): if self.character_boxes_bool[i][j]: char[j] |= 1 << (4 - i) index = int(self.char_index_combo.currentText()) self.lcd.set_custom_character(index, char) def show_clicked(self): self.lcd.clear_display() line1 = '0:{0} 1:{1} 2:{2} 3:{3}'.format(chr(8), chr(9), chr(10), chr(11)) line2 = '4:{0} 5:{1} 6:{2} 7:{3}'.format(chr(12), chr(13), chr(14), chr(15)) self.lcd.write_line(0, 0, line1) self.lcd.write_line(1, 0, line2) def custom_character_async(self, characters): for i in range(len(self.character_boxes)): for j in range(len(self.character_boxes[i])): if characters[j] & (1 << i): self.character_boxes_bool[4 - i][j] = True self.character_boxes[4 - i][j].setStyleSheet( "background-color: rgb(255, 255, 255)") else: self.character_boxes_bool[4 - i][j] = False self.character_boxes[4 - i][j].setStyleSheet( "background-color: rgb(0, 0, 255)") def char_index_changed(self, index): async_call(self.lcd.get_custom_character, (index, ), self.custom_character_async, self.increase_error_count)
class RunWidget(QWidget): def __init__(self): QWidget.__init__(self) vbox = QVBoxLayout(self) vbox.setSpacing(0) vbox.setContentsMargins(0, 0, 0, 0) self.output = OutputWidget(self) hbox = QHBoxLayout() self.input = QLineEdit() self.lblInput = QLabel(self.tr("Input:")) vbox.addWidget(self.output) hbox.addWidget(self.lblInput) hbox.addWidget(self.input) vbox.addLayout(hbox) #process self._proc = QProcess(self) self.connect(self._proc, SIGNAL("readyReadStandardOutput()"), self.output._refresh_output) self.connect(self._proc, SIGNAL("readyReadStandardError()"), self.output._refresh_error) self.connect(self._proc, SIGNAL("finished(int, QProcess::ExitStatus)"), self.finish_execution) self.connect(self.input, SIGNAL("returnPressed()"), self.insert_input) def finish_execution(self, exitCode, exitStatus): self.lblInput.hide() self.input.hide() format = QTextCharFormat() format.setAnchor(True) self.output.textCursor().insertText('\n\n') if exitStatus == QProcess.NormalExit: format.setForeground(Qt.green) self.output.textCursor().insertText( self.tr("Execution Successful!"), format) else: format.setForeground(Qt.red) self.output.textCursor().insertText( self.tr("Execution Interrupted"), format) def insert_input(self): text = self.input.text() + '\n' self._proc.writeData(text) self.input.setText("") def start_process(self, fileName, pythonPath=False, programParams=''): self.lblInput.show() self.input.show() self.output.setCurrentCharFormat(self.output.plain_format) self.output.setPlainText('Running: %s (%s)\n\n' % (fileName, unicode(time.ctime()))) self.output.moveCursor(QTextCursor.Down) self.output.moveCursor(QTextCursor.Down) self.output.moveCursor(QTextCursor.Down) #runner.run_code_from_file(fileName) if not pythonPath: pythonPath = settings.PYTHON_PATH #change the working directory to the fileName dir file_directory = file_manager.get_folder(fileName) self._proc.setWorkingDirectory(file_directory) #force python to unbuffer stdin and stdout options = ['-u'] + settings.EXECUTION_OPTIONS.split() self._proc.start(pythonPath, options + [fileName] + \ [p.strip() for p in programParams.split(',') if p]) def kill_process(self): self._proc.kill()
class WidgetFFmpeg(QDialog): def __init__(self, idCodec, cheminVideoEntre, cheminSorti, valeurNum=0, laisserOuvert=1, tailleIm=None, tailleVideo=None, systeme=None, cheminFfmpeg=None, tempsApercu=None, optionSpeciale=None, cheminMPlayer=None): """widget ffmpeg""" super(WidgetFFmpeg, self).__init__() self.cheminFfmpeg=u"ffmpeg" self.cheminVideoEntre = unicode(cheminVideoEntre) self.cheminSorti = unicode(cheminSorti) # identifiant du codec self.idCodec = idCodec # valeur de la boite de spin pour l'encodage self.valeurNum = valeurNum # dimension des images (liste de 2 éléments) self.tailleIm = tailleIm # dimension de la vidéo (liste de 2 éléments) self.tailleVideo = tailleVideo # laisser ouvert la fenêtre après encodage self.laisserOuvert = laisserOuvert # Conversion minimale du filtre pour avoir un aperçu. # Indique le temps où l'aperçu doit être créé self.tempsApercu = tempsApercu # drapeau pour ne pas lancer 2 fois l'encodage self.estLancee = False # Est-ce que le 1er % de progression a été récupéré (utile pour montage vidéo -> découper)? self.__recupPourcentDebut = 0 # Pour le son lors de la découpe vidéo pour l'instant if optionSpeciale!=None: self.optionSpeciale = optionSpeciale self.resize(500, 100) #=== Widgets ===# self.labelAttente=QLabel() self.labelAttente.setText(_(u"Attendez la fin du calcul s'il vous plaît, soyez patient !")) self.zoneTexte = QTextEdit("") # là où s'afficheront les infos if PYQT_VERSION_STR < "4.1.0": self.zoneTexte.setText = self.zoneTexte.setPlainText self.zoneTexte.setReadOnly(True) self.zoneTexte.setText("#######\n# LOG :\n#######\n") self.zoneTexte.hide() self.bout_annuler = QPushButton(_(u"Annuler")) self.bout_preZoneTexte = QPushButton(_("Voir les informations de l'encodage")) self.bout_preZoneTexte.hide() self.pbar = QProgressBar() self.pbar.setMaximum(100) vbox = QVBoxLayout() vbox.addWidget(self.labelAttente) vbox.addWidget(self.bout_preZoneTexte) vbox.addWidget(self.zoneTexte) hbox = QHBoxLayout() hbox.addWidget(self.pbar) hbox.addWidget(self.bout_annuler) vbox.addLayout(hbox) self.setLayout(vbox) self.ffmpegProcess = FFmpeg(inputfile = unicode(self.cheminVideoEntre), outputfile = unicode(self.cheminSorti), codec = self.idCodec, imgsize = self.tailleIm, videosize = self.tailleVideo) #=== connexion des widgets à des fonctions ===# self.connect(self.ffmpegProcess, SIGNAL('progress(int)'), self.pbar.setValue) self.connect(self.ffmpegProcess, SIGNAL('log(QString)'), self.zoneTexte.append) self.connect(self.ffmpegProcess, SIGNAL('finished(int)'), self.finEncodage) self.connect(self.bout_annuler, SIGNAL('clicked()'), self.close) self.connect(self.bout_preZoneTexte, SIGNAL('clicked()'), self.afficherLog) ## On sort cette partie qui ne doit pas être lancée dans l'init de l'objet. # Uniquement FFmpeg #self.demarrerEncodeur('Ffmpeg') def setVideoLen(self, videoLen) : self.ffmpegProcess.setVideoLen(videoLen) def close(self): """ Annule le traitement en cours """ self.ffmpegProcess.cancel() self.ffmpegProcess.wait() #super(WidgetFFmpeg, self).close() # Python 2.6 QDialog.close(self) def exec_(self): """ Surcharge de la fonction exec permettant l'execution hors de l'init""" self.demarrerEncodeur('Ffmpeg') #super(WidgetFFmpeg, self).exec_() # Python 2.6 QDialog.exec_(self) def demarrerEncodeur(self, encodeur): """démarrage de mencoder avec les arguments choisis""" if self.estLancee == False: # pas question de démarrer 2 fois l'encodage commande = None has_audio = False debug('\n') # Si la conversion d'images en vidéo est sélectionné, aucune # info Mplayer n'est affichée (problème de récup infos par Mplayer) if self.idCodec in ['mpeg1video', 'mjpeg', 'h263p', 'mpeg4', 'msmpeg4v2', 'ljpeg', 'dv', 'huffyuv', 'mov', 'flv', 'mp4', 'vob']: # ICI SI LES FICHIERS CHARGES SONT DES IMAGES a = "###############################" b = "# Informations sur les images :" c = "###############################" infos = '\n'+a+'\n'+b+'\n'+c+'\n' debug(infos) self.zoneTexte.append(infos) import glob # Le chemin pour l'affichage des infos sur les images ne fonctionnait # plus après la nouvelle structure des fichiers temporaires self.recupTempImgAnim = glob.glob(EkdConfig.getTempDir() + os.sep + "*.*") self.recupTempImgAnim.sort() # Affichage du chemin (temp) + le poids de chaque image # --> Une énumération de parcours a été introduite for parcNb, parcInfIm in enumerate(self.recupTempImgAnim): debug('* '+str(parcNb+1)+'. '+parcInfIm+' --> '+str(float(os.path.getsize(parcInfIm)/1000))+' ko'+'\n') self.zoneTexte.append('* '+str(parcNb+1)+'. '+parcInfIm+' --> '+str(float(os.path.getsize(parcInfIm)/1000))+' ko'+'\n') # Elimination de la dernière image de la liste car car elle # s'affiche en double ds la fenêtre information de l'encodage # et aussi ds la console #self.log = self.log[:len(self.log)-1] # On définie la longueur de la futur vidéo en divisant le nombre d'image par le # nombre d'image par seconde (valeurNum ici) self.ffmpegProcess.setVideoLen(len(self.recupTempImgAnim) / int(self.valeurNum)) # Pour les traitements autres que la transformation des images en vidéo if self.idCodec not in ['mpeg1video', 'mjpeg', 'h263p', 'mpeg4', 'msmpeg4v2', 'ljpeg', 'dv', 'huffyuv', 'mov', 'flv', 'mp4', 'vob']: a = "########################" b = "# Informations MPlayer :" c = "########################" infos = '\n'+a+'\n'+b+'\n'+c+'\n' debug(infos) ######## Ajouté le 24/07/09 ################################################################## # Utilisation de la classe infovideo (et en particilier la fonction setVideo) # présents dans gui_modules_animation/infoVideo.py info = infovideo(self.cheminVideoEntre) id_filename = 'ID_FILENAME='+self.cheminVideoEntre+'\n' debug(id_filename) id_demuxer = 'ID_DEMUXER='+info.demux+'\n' debug(id_demuxer) id_video_format = 'ID_VIDEO_FORMAT='+info.videoFormat+'\n' debug(id_video_format) id_video_codec = 'ID_VIDEO_CODEC='+info.video_codec+'\n' debug(id_video_codec) id_video_bitrate = 'ID_VIDEO_BITRATE='+str(info.videoBitrate)+'\n' debug(id_video_bitrate) id_video_largeur = 'ID_VIDEO_WIDTH='+str(info.videoLargeur)+'\n' debug(id_video_largeur) id_video_hauteur = 'ID_VIDEO_HEIGHT='+str(info.videoHauteur)+'\n' debug(id_video_hauteur) id_img_par_sec = 'ID_VIDEO_FPS='+str(info.imgParSec)+'\n' debug(id_img_par_sec) ##### Donnée très importante pour la suite du calcul (pour ffmpeg.py et ffmpeg2theora) #### self.dureeTotaleVideo = float(info.dureeTotaleVideo) ########################################################################################### id_duree_totale_video = 'ID_LENGTH='+str(info.dureeTotaleVideo)+'\n' debug(id_duree_totale_video) id_audio_codec = 'ID_AUDIO_CODEC='+info.audioCodec+'\n' debug(id_audio_codec) id_audio_rate = 'ID_AUDIO_RATE='+str(info.audioRate)+'\n' debug(id_audio_rate) id_audio_bitrate = 'ID_AUDIO_BITRATE='+str(info.audioBitrate)+'\n' debug(id_audio_bitrate) self.zoneTexte.append(infos+id_filename+id_demuxer+id_video_format+id_video_codec+id_video_bitrate+id_video_largeur+id_video_hauteur+id_img_par_sec+id_duree_totale_video+id_audio_codec+id_audio_rate+id_audio_bitrate) ############################################################################################## ## On définie la longueur de la vidéo pour le process self.ffmpegProcess.setVideoLen(self.dureeTotaleVideo) if info.audioCodec : has_audio = True debug('\n') a = "############################" b = "# Informations %s :" %encodeur c = "############################" infos = '\n'+a+'\n'+b+'\n'+c+'\n' debug(infos) self.zoneTexte.append(infos) if self.idCodec=='codec_dv_ffmpeg': self.ffmpegProcess.commandeFfmpegEncodageDv() elif self.idCodec=='codec_mov_ffmpeg': #### Enlevé le 09/04/11 ############################## #self.ffmpegProcess.commandeFfmpegEncodageMov() ###################################################### #### Ajouté/rectifié le 09/04/11 ##################### self.ffmpegProcess.commandeFfmpegEncodageMov(comp = self.valeurNum[0], size = self.valeurNum[1]) ###################################################### elif self.idCodec=='codec_hfyu_ffmpeg': #### Enlevé le 10/04/11 ############################## #self.ffmpegProcess.commandeFfmpegEncodageHfyu(audio = has_audio) ###################################################### #### Ajouté/rectifié le 10/04/11 ##################### self.ffmpegProcess.commandeFfmpegEncodageHfyu(size = self.valeurNum, audio = has_audio) ###################################################### elif self.idCodec=='codec_vob_ffmpeg': self.ffmpegProcess.commandeFfmpegEncodageVob(vquantizer = self.valeurNum) elif self.idCodec=='codec_3GP_ffmpeg': #### Enlevé le 30/03/11 ############################## #self.ffmpegProcess.commandeFfmpegEncodage3gp(audio = has_audio) #### Ajouté/rectifié le 30/03/11 ##################### self.ffmpegProcess.commandeFfmpegEncodage3gp(size = self.valeurNum) ###################################################### elif self.idCodec=='codec_AMV_ffmpeg': #### Rectifié le 30/03/11 ## Ajout de size ########### self.ffmpegProcess.commandeFfmpegEncodageAMV(size = self.valeurNum) ###################################################### elif self.idCodec=='idx': self.ffmpegProcess.commandeFfmpegNbrImgSec(rate = self.valeurNum) elif self.idCodec in ['mpeg1video', 'mjpeg', 'h263p', 'mpeg4', 'msmpeg4v2', 'ljpeg', 'dv', 'huffyuv', 'mov', 'flv', 'mp4', 'vob']: self.ffmpegProcess.commandeFfmpegConvertImg(rate = self.valeurNum, size = "%sx%s" % (self.tailleIm[0], self.tailleIm[1]), vcodec = self.idCodec) # --------------------------------------------------------------------------------- # # Traitement pour chaque entrée concernant la HD (classique, en dehors du codec Avid DNxHD) # --------------------------------------------------------------------------------- # elif self.idCodec in ['hd_1920x1080_mov__pcm_s16be__16/9', 'hd_1280x720_mov__pcm_s16be__16/9', 'hd_1440x1080_mov__pcm_s16be__4/3']: ## FIXME : La taille est récupérée du nom de idCodec (crade) self.ffmpegProcess.commandeFfmpegConvHD(size = self.idCodec.split("_")[1]) ### Ajouté le 19/08/10 (Gestion du codec Avid DNxHD) ################################ # --------------------------------------------------------------------------------- # # Traitement pour chaque entrée (24) concernant le codec Avid DNxHD pour la HD # --------------------------------------------------------------------------------- # elif self.idCodec=='hd_dnxhd_1920x1080_29.97_220_mbs': ## FIXME : Les éléments utiles sont récupérés du nom de idCodec (crade mais utile) self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 1 elif self.idCodec=='hd_dnxhd_1920x1080_29.97_145_mbs': self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 2 elif self.idCodec=='hd_dnxhd_1920x1080_25_185_mbs': self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 3 elif self.idCodec=='hd_dnxhd_1920x1080_25_120_mbs': self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 4 elif self.idCodec=='hd_dnxhd_1920x1080_25_36_mbs': self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 5 elif self.idCodec=='hd_dnxhd_1920x1080_24_175_mbs': self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 6 elif self.idCodec=='hd_dnxhd_1920x1080_24_115_mbs': self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 7 elif self.idCodec=='hd_dnxhd_1920x1080_24_36_mbs': self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 8 elif self.idCodec=='hd_dnxhd_1920x1080_23.976_175_mbs': self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 9 elif self.idCodec=='hd_dnxhd_1920x1080_23.976_115_mbs': self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 10 elif self.idCodec=='hd_dnxhd_1920x1080_23.976_36_mbs': self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 11 elif self.idCodec=='hd_dnxhd_1920x1080_29.97_220_mbs': self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 12 elif self.idCodec=='hd_dnxhd_1920x1080_29.97_145_mbs': self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 13 elif self.idCodec=='hd_dnxhd_1920x1080_29.97_45_mbs': self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 14 elif self.idCodec=='hd_dnxhd_1280x720_59.94_220_mbs': self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 15 elif self.idCodec=='hd_dnxhd_1280x720_59.94_145_mbs': self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 16 elif self.idCodec=='hd_dnxhd_1280x720_50_175_mbs': self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 17 elif self.idCodec=='hd_dnxhd_1280x720_50_115_mbs': self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 18 elif self.idCodec=='hd_dnxhd_1280x720_29.97_110_mbs': self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 19 elif self.idCodec=='hd_dnxhd_1280x720_29.97_75_mbs': self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 20 elif self.idCodec=='hd_dnxhd_1280x720_25_90_mbs': self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 21 elif self.idCodec=='hd_dnxhd_1280x720_25_60_mbs': self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 22 elif self.idCodec=='hd_dnxhd_1280x720_23.976_90_mbs': self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 23 elif self.idCodec=='hd_dnxhd_1280x720_23.976_60_mbs': self.ffmpegProcess.commandeFfmpegConvHD_DNxHD(size=self.idCodec.split("_")[2], vcodec=self.idCodec.split("_")[1], rate=self.idCodec.split("_")[3], vbitrate=self.idCodec.split("_")[4]+'000k') # 24 ################################################################################# elif self.idCodec=='jpeg': # convertir animation en images self.ffmpegProcess.commandeFfmpegConvAnimImg() elif self.idCodec=='extractionaudio': self.ffmpegProcess.commandeFfmpegSeparation() elif self.idCodec=='encodage_wav': # encodage de fichiers audio en wav self.ffmpegProcess.commandeFfmpegEncodageWav() elif self.idCodec=='conv_en_16_9_ou_4_3': # Convertir vidéo en 16/9 ou 4/3 self.ffmpegProcess.commandeFfmpegConv_16_9_ou_4_3( ext = os.path.splitext(self.cheminVideoEntre)[1], size = "%sx%s" % (self.tailleVideo[0], self.tailleVideo[1]), aspect = self.valeurNum, audio = has_audio) # Remonté d'un niveau pour simplifier le code et éviter les répetitions if commande == None: commande = self.ffmpegProcess.command else : self.ffmpegProcess.command = commande debug(commande) self.zoneTexte.append(commande+'\n\n') self.ffmpegProcess.start() debug(u"Commande lancée") self.estLancee = True def finEncodage(self, statutDeSortie): """choses à faire à la fin de l'encodage de la vidéo""" # fermer la fenêtre à la fin de l'encodage if not self.laisserOuvert: self.close() debug("fini!") self.labelAttente.hide() self.pbar.setValue(100) # l'encodage est fini. Il ne peut plus être annulé. La # seule action possible devient ainsi la fermeture self.bout_annuler.setText(_(u"Fermer")) if statutDeSortie != 0 : self.bout_annuler.setText(_(u"Crash")) self.bout_preZoneTexte.show() self.emit(SIGNAL("finEncodage")) def afficherLog(self): """afficher les information de la vidéo de départ et de l'encodage""" self.zoneTexte.setText(self.ffmpegProcess.log) self.zoneTexte.show() self.resize(500, 300)
class PylintViewer( QWidget ): " Pylint tab widget " # Limits to colorize the final score BadLimit = 8.5 GoodLimit = 9.5 # Options of providing a report SingleFile = 0 DirectoryFiles = 1 ProjectFiles = 2 SingleBuffer = 3 updatePylintTooltip = pyqtSignal( str ) def __init__( self, parent = None ): QWidget.__init__( self, parent ) self.__reportUUID = "" self.__reportFileName = "" self.__reportOption = -1 self.__reportShown = False self.__report = None self.__widgets = [] # Prepare members for reuse if GlobalData().pylintAvailable: self.__noneLabel = QLabel( "\nNo results available" ) else: self.__noneLabel = QLabel( "\nPylint is not available" ) self.__noneLabel.setAutoFillBackground( True ) noneLabelPalette = self.__noneLabel.palette() noneLabelPalette.setColor( QPalette.Background, GlobalData().skin.nolexerPaper ) self.__noneLabel.setPalette( noneLabelPalette ) self.__noneLabel.setFrameShape( QFrame.StyledPanel ) self.__noneLabel.setAlignment( Qt.AlignHCenter ) self.__headerFont = self.__noneLabel.font() self.__headerFont.setPointSize( self.__headerFont.pointSize() + 4 ) self.__noneLabel.setFont( self.__headerFont ) self.__createLayout( parent ) self.__updateButtonsStatus() self.resizeEvent() return def __createLayout( self, parent ): " Creates the toolbar and layout " # Buttons self.printButton = QAction( PixmapCache().getIcon( 'printer.png' ), 'Print', self ) #printButton.setShortcut( 'Ctrl+' ) self.printButton.triggered.connect( self.__onPrint ) self.printButton.setVisible( False ) self.printPreviewButton = QAction( PixmapCache().getIcon( 'printpreview.png' ), 'Print preview', self ) #printPreviewButton.setShortcut( 'Ctrl+' ) self.printPreviewButton.triggered.connect( self.__onPrintPreview ) self.printPreviewButton.setVisible( False ) spacer = QWidget() spacer.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Expanding ) self.clearButton = QAction( PixmapCache().getIcon( 'trash.png' ), 'Clear', self ) self.clearButton.triggered.connect( self.__clear ) # The toolbar self.toolbar = QToolBar( self ) self.toolbar.setOrientation( Qt.Vertical ) self.toolbar.setMovable( False ) self.toolbar.setAllowedAreas( Qt.RightToolBarArea ) self.toolbar.setIconSize( QSize( 16, 16 ) ) self.toolbar.setFixedWidth( 28 ) self.toolbar.setContentsMargins( 0, 0, 0, 0 ) self.toolbar.addAction( self.printPreviewButton ) self.toolbar.addAction( self.printButton ) self.toolbar.addWidget( spacer ) self.toolbar.addAction( self.clearButton ) self.__vLayout = QVBoxLayout() self.__vLayout.setContentsMargins( 5, 5, 5, 5 ) self.__vLayout.setSpacing( 0 ) self.__vLayout.setSizeConstraint( QLayout.SetFixedSize ) self.__bodyFrame = QFrame( self ) # self.__bodyFrame.setFrameShape( QFrame.StyledPanel ) self.__bodyFrame.setFrameShape( QFrame.NoFrame ) # self.__bodyFrame.setSizePolicy( QSizePolicy.Maximum, # QSizePolicy.Expanding ) self.__bodyFrame.setLayout( self.__vLayout ) self.bodyWidget = QScrollArea( self ) self.bodyWidget.setFocusPolicy( Qt.NoFocus ) self.bodyWidget.setWidget( self.__bodyFrame ) self.bodyWidget.hide() self.__hLayout = QHBoxLayout() self.__hLayout.setContentsMargins( 0, 0, 0, 0 ) self.__hLayout.setSpacing( 0 ) self.__hLayout.addWidget( self.toolbar ) self.__hLayout.addWidget( self.__noneLabel ) self.__hLayout.addWidget( self.bodyWidget ) self.setLayout( self.__hLayout ) return def __updateButtonsStatus( self ): " Updates the buttons status " self.printButton.setEnabled( self.__reportShown ) self.printPreviewButton.setEnabled( self.__reportShown ) self.clearButton.setEnabled( self.__reportShown ) return def __onPrint( self ): " Triggered when the print button is pressed " pass def __onPrintPreview( self ): " triggered when the print preview button is pressed " pass def setFocus( self ): " Overridden setFocus " self.__vLayout.setFocus() return def __clear( self ): " Clears the content of the vertical layout " if not self.__reportShown: return self.__removeAll() self.bodyWidget.hide() self.__noneLabel.show() self.__report = None self.__reportShown = False self.__updateButtonsStatus() self.resizeEvent() self.__updateTooltip() return def __removeAll( self ): " Removes all the items from the report " for item in self.__widgets: item.hide() self.__vLayout.removeWidget( item ) del item self.__widgets = [] return def __createScoreLabel( self, score, previousScore, showFileName, fileName ): " Creates the score label " txt = "Score: " + str( score ) if previousScore != "": txt += " / Previous score: " + str( previousScore ) if not showFileName: txt += " for " + os.path.basename( fileName ) scoreLabel = QLabel( txt ) scoreLabel.setFrameShape( QFrame.StyledPanel ) scoreLabel.setFont( self.__headerFont ) scoreLabel.setAutoFillBackground( True ) palette = scoreLabel.palette() if score < self.BadLimit: palette.setColor( QPalette.Background, QColor( 255, 127, 127 ) ) palette.setColor( QPalette.Foreground, QColor( 0, 0, 0 ) ) elif score > self.GoodLimit: palette.setColor( QPalette.Background, QColor( 220, 255, 220 ) ) palette.setColor( QPalette.Foreground, QColor( 0, 0, 0 ) ) else: palette.setColor( QPalette.Background, QColor( 255, 255, 127 ) ) palette.setColor( QPalette.Foreground, QColor( 0, 0, 0 ) ) scoreLabel.setPalette( palette ) return scoreLabel @staticmethod def __setTableHeight( table ): " Auxiliary function to set the table height " # Height - it is ugly and approximate however I am tired of # calculating the proper height. Why is this so hard, huh? lastRowHeight = table.itemDelegate().lastHeight height = lastRowHeight * ( table.topLevelItemCount() + 1 ) + 10 table.setFixedHeight( height ) return @staticmethod def __shouldShowFileName( messages ): " Decides if the file name column should be supressed " if len( messages ) == 0: return False firstName = messages[ 0 ].fileName for index in range( 1, len( messages ) ): if firstName != messages[ index ].fileName: return True return False def __addErrorsTable( self, messages, showFileName ): " Creates the messages table " errTable = QTreeWidget( self.bodyWidget ) errTable.setAlternatingRowColors( True ) errTable.setRootIsDecorated( False ) errTable.setItemsExpandable( False ) errTable.setSortingEnabled( True ) errTable.setItemDelegate( NoOutlineHeightDelegate( 4 ) ) errTable.setUniformRowHeights( True ) errTable.itemActivated.connect( self.__errorActivated ) headerLabels = [ "File name", "Line", "Message ID", "Object", "Message" ] errTable.setHeaderLabels( headerLabels ) for item in messages: if item.position is None: lineNumber = str( item.lineNumber ) else: lineNumber = str( item.lineNumber ) + ":" + str( item.position ) values = [ item.fileName, lineNumber, item.messageID, item.objectName, item.message ] errTable.addTopLevelItem( ErrorTableItem( values, 1 ) ) # Hide the file name column if required if not showFileName: errTable.setColumnHidden( 0, True ) # Resizing errTable.header().resizeSections( QHeaderView.ResizeToContents ) errTable.header().setStretchLastSection( True ) # Sort indicator if showFileName: sortIndex = 0 # By file names else: sortIndex = 1 # By line number because this is from the same file errTable.header().setSortIndicator( sortIndex, Qt.AscendingOrder ) errTable.sortItems( sortIndex, errTable.header().sortIndicatorOrder() ) # Height self.__setTableHeight( errTable ) self.__vLayout.addWidget( errTable ) self.__widgets.append( errTable ) return def __addSimilarity( self, similarity, titleText ): " Adds a similarity " # Label title = QLabel( titleText ) title.setFont( self.__headerFont ) self.__vLayout.addWidget( title ) self.__widgets.append( title ) # List of files simTable = QTreeWidget( self.bodyWidget ) simTable.setAlternatingRowColors( True ) simTable.setRootIsDecorated( False ) simTable.setItemsExpandable( False ) simTable.setSortingEnabled( False ) simTable.setItemDelegate( NoOutlineHeightDelegate( 4 ) ) simTable.setUniformRowHeights( True ) simTable.itemActivated.connect( self.__similarityActivated ) simTable.setHeaderLabels( [ "File name", "Line" ] ) for item in similarity.files: values = [ item[ 0 ], str( item[ 1 ] ) ] simTable.addTopLevelItem( QTreeWidgetItem( values ) ) # Resizing simTable.header().resizeSections( QHeaderView.ResizeToContents ) simTable.header().setStretchLastSection( True ) # Height self.__setTableHeight( simTable ) self.__vLayout.addWidget( simTable ) self.__widgets.append( simTable ) # The fragment itself if len( similarity.fragment ) > 10: # Take first 9 lines text = "\n".join( similarity.fragment[ : 9 ] ) + "\n ..." toolTip = "\n".join( similarity.fragment ) else: text = "\n".join( similarity.fragment ) toolTip = "" fragmentLabel = QLabel( "<pre>" + self.__htmlEncode( text ) + "</pre>" ) if toolTip != "": fragmentLabel.setToolTip( "<pre>" + self.__htmlEncode( toolTip ) + "</pre>" ) palette = fragmentLabel.palette() palette.setColor( QPalette.Background, QColor( 250, 250, 175 ) ) palette.setColor( QPalette.Foreground, QColor( 0, 0, 0 ) ) fragmentLabel.setPalette( palette ) fragmentLabel.setFrameShape( QFrame.StyledPanel ) fragmentLabel.setAutoFillBackground( True ) labelFont = fragmentLabel.font() labelFont.setFamily( GlobalData().skin.baseMonoFontFace ) fragmentLabel.setFont( labelFont ) self.__vLayout.addWidget( fragmentLabel ) self.__widgets.append( fragmentLabel ) return @staticmethod def __htmlEncode( string ): " Encodes HTML " return string.replace( "&", "&" ) \ .replace( ">", ">" ) \ .replace( "<", "<" ) def __addSectionSpacer( self ): " Adds a fixed height spacer to the VBox layout " spacer = QWidget() spacer.setFixedHeight( 10 ) self.__vLayout.addWidget( spacer ) self.__widgets.append( spacer ) return def __addGenericTable( self, table ): " Adds a generic table to the report " theTable = QTreeWidget( self.bodyWidget ) theTable.setAlternatingRowColors( True ) theTable.setRootIsDecorated( False ) theTable.setItemsExpandable( False ) theTable.setSortingEnabled( False ) theTable.setItemDelegate( NoOutlineHeightDelegate( 4 ) ) theTable.setUniformRowHeights( True ) headerLabels = [] for index in range( 0, len( table.header ) ): headerLabels.append( table.header[ index ] ) theTable.setHeaderLabels( headerLabels ) for item in table.body: row = [] for index in range( 0, len( table.header ) ): row.append( item[ index ] ) theTable.addTopLevelItem( QTreeWidgetItem( row ) ) theTable.setFocusPolicy( Qt.NoFocus ) # Resizing theTable.header().resizeSections( QHeaderView.ResizeToContents ) theTable.header().setStretchLastSection( True ) # Height self.__setTableHeight( theTable ) self.__vLayout.addWidget( theTable ) self.__widgets.append( theTable ) return def __addGenericTableTitle( self, table ): " Adds a generic table title " tableTitle = QLabel( table.title ) tableTitle.setFont( self.__headerFont ) self.__vLayout.addWidget( tableTitle ) self.__widgets.append( tableTitle ) return def __updateTooltip( self ): " Generates a signal with appropriate string message " if not self.__reportShown: tooltip = "No results available" elif self.__reportOption == self.DirectoryFiles: tooltip = "Report generated for directory: " + \ self.__reportFileName elif self.__reportOption == self.ProjectFiles: tooltip = "Report generated for the whole project" elif self.__reportOption == self.SingleFile: tooltip = "Report generated for file: " + self.__reportFileName elif self.__reportOption == self.SingleBuffer: tooltip = "Report generated for unsaved file: " + \ self.__reportFileName else: tooltip = "" self.updatePylintTooltip.emit( tooltip ) return def showReport( self, lint, reportOption, fileName, uuid ): " Shows the pylint results " self.__removeAll() self.__noneLabel.hide() self.__report = lint self.__reportUUID = uuid self.__reportFileName = fileName self.__reportOption = reportOption showFileName = self.__shouldShowFileName( lint.errorMessages ) scoreLabel = self.__createScoreLabel( lint.score, lint.previousScore, showFileName, fileName ) self.__vLayout.addWidget( scoreLabel ) self.__widgets.append( scoreLabel ) if len( lint.errorMessages ) > 0: self.__addSectionSpacer() self.__addErrorsTable( lint.errorMessages, showFileName ) index = 0 for similarity in lint.similarities: self.__addSectionSpacer() self.__addSimilarity( similarity, "Similarity #" + str( index ) ) index += 1 for table in lint.tables: self.__addSectionSpacer() self.__addGenericTableTitle( table ) self.__addGenericTable( table ) self.bodyWidget.show() self.bodyWidget.ensureVisible( 0, 0, 0, 0 ) self.__reportShown = True self.__updateButtonsStatus() self.__updateTooltip() # It helps, but why do I have flickering? QApplication.processEvents() self.__resizeBodyFrame() return def __errorActivated( self, item, column ): " Handles the double click (or Enter) on the item " linePos = str( item.text( 1 ) ) if ":" in linePos: parts = linePos.split( ":" ) lineNumber = int( parts[ 0 ] ) pos = int( parts[ 1 ] ) else: lineNumber = int( linePos ) pos = 0 if self.__reportOption in [ self.SingleFile, self.DirectoryFiles, self.ProjectFiles ]: fileName = str( item.text( 0 ) ) else: # SingleBuffer if self.__reportFileName != "": if os.path.isabs( self.__reportFileName ): fileName = self.__reportFileName else: # Could be unsaved buffer, so try to search by the mainWindow = GlobalData().mainWindow widget = mainWindow.getWidgetByUUID( self.__reportUUID ) if widget is None: logging.error( "The unsaved buffer has been closed" ) return # The widget was found, so jump to the required editor = widget.getEditor() editor.gotoLine( lineNumber, pos ) editor.setFocus() return GlobalData().mainWindow.openFile( fileName, lineNumber, pos ) return def __resizeBodyFrame( self ): " Resizing the frame to occupy all available width " size = self.bodyWidget.maximumViewportSize() self.__bodyFrame.setMinimumWidth( size.width() - 16 ) self.__bodyFrame.setMinimumHeight( size.height() ) return def showEvent( self, showEv = None ): " Called when the widget is shown " self.__resizeBodyFrame() return def resizeEvent( self, resizeEv = None ): " Called when the main window gets resized " self.__resizeBodyFrame() return def onFileUpdated( self, fileName, uuid ): " Called when a buffer is saved or saved as " if not self.__reportShown: return if self.__reportUUID != uuid: return # Currently shown report is for the saved buffer # File name is expected being absolute self.__reportFileName = fileName self.updatePylintTooltip.emit( "Report generated for buffer saved as " + fileName ) return def __similarityActivated( self, item, column ): " Triggered when a similarity is activated " fileName = str( item.text( 0 ) ) lineNumber = int( item.text( 1 ) ) GlobalData().mainWindow.openFile( fileName, lineNumber ) return
class WRepositories(QWidget, Logger.ClassLogger): """ Repositories widget """ def __init__(self, parent=None): """ Constructs WRepositories widget @param parent: @type parent: """ QWidget.__init__(self, parent) self.localRepoPath = Settings.instance().readValue( key='Repositories/local-repo') self.localRepository = None self.localSaveOpen = None self.remoteRepository = None self.adaptersRemoteRepository = None self.createWidgets() self.createConnections() self.onResetRemote() def localRepoIsPresent(self): """ The local repository is configured ? """ if self.localRepoPath != "Undefined": if not os.path.exists(self.localRepoPath): self.localConfigured = "Undefined" self.testsTab.setTabEnabled(TAB_LOCAL_POS, False) else: self.localConfigured = self.localRepoPath self.testsTab.setTabEnabled(TAB_LOCAL_POS, True) else: self.localConfigured = self.localRepoPath self.testsTab.setTabEnabled(TAB_LOCAL_POS, False) def createWidgets(self): """ Create qt widgets QTabWidget: ________ ________ / \/ \___________ | | | | | | |_______________________________| """ self.line = QFrame() self.line.setGeometry(QRect(110, 221, 51, 20)) self.line.setFrameShape(QFrame.HLine) self.line.setFrameShadow(QFrame.Sunken) self.testsTab = QTabWidget() self.testsTab.setTabPosition(QTabWidget.North) self.testsTab.setStyleSheet( "QTabWidget { border: 0px; }") # remove 3D border # local repo self.localConfigured = self.localRepoPath self.localRepository = LocalRepository.Repository(parent=self) self.localRepository.deactive() self.localRepoIsPresent() self.localSaveOpen = LocalRepository.SaveOpenToRepoDialog(parent=self) # remote repo self.remoteRepository = RemoteTests.Repository(parent=self, projectSupport=True) if not RCI.instance().isAuthenticated(): self.remoteRepository.setNotConnected() self.remoteRepository.setEnabled(False) # adapters remote repo self.adaptersRemoteRepository = RemoteAdapters.Repository(parent=self) if not RCI.instance().isAuthenticated(): self.adaptersRemoteRepository.setNotConnected() self.adaptersRemoteRepository.setEnabled(False) # libraries adapters remote repo self.librariesRemoteRepository = RemoteLibraries.Repository( parent=self) if not RCI.instance().isAuthenticated(): self.librariesRemoteRepository.setNotConnected() self.librariesRemoteRepository.setEnabled(False) self.testsTab.addTab(self.localRepository, QIcon(":/repository-tests.png"), self.tr("Local Tests")) self.testsTab.addTab(self.remoteRepository, QIcon(":/repository-tests.png"), self.tr("Remote Tests")) self.testsTab.setTabEnabled(TAB_LOCAL_POS, False) self.testsTab.setTabEnabled(TAB_REMOTE_POS, False) self.connectorsTab = QTabWidget() self.connectorsTab.setTabPosition(QTabWidget.North) self.connectorsTab.setStyleSheet( "QTabWidget { border: 0px; }") # remove 3D border self.connectorsTab.addTab(self.adaptersRemoteRepository, QIcon(":/repository-adapters.png"), self.tr("Adapters")) self.connectorsTab.addTab(self.librariesRemoteRepository, QIcon(":/repository-libraries.png"), self.tr("Libraries")) self.connectorsTab.setTabEnabled(TAB_ADAPTER_POS, False) self.connectorsTab.setTabEnabled(TAB_LIBRARY_POS, False) self.title = QLabel(self.tr("Repositories")) font = QFont() font.setBold(True) self.title.setFont(font) self.labelHelp = QLabel( self.tr( "Drag and drop your selected file in the workspace to open it." )) self.labelHelp.setEnabled(False) font = QFont() font.setItalic(True) self.labelHelp.setFont(font) layout = QVBoxLayout() layout.addWidget(self.title) layout.addWidget(self.labelHelp) self.mainTab = QTabWidget() self.mainTab.setEnabled(False) self.mainTab.setTabPosition(QTabWidget.North) self.mainTab.setMinimumWidth(300) self.mainTab.addTab(self.testsTab, QIcon(":/test-description.png"), "Tests Listing") self.mainTab.addTab(self.connectorsTab, QIcon(":/adapters.png"), "Modules Listing") layout.addWidget(self.mainTab) layout.addWidget(self.line) layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) # set the default tab defaultTab = Settings.instance().readValue( key='Repositories/default-repo-test') if int(defaultTab) == TAB_LOCAL_POS or int( defaultTab) == TAB_REMOTE_POS: self.mainTab.setCurrentIndex(MAIN_TAB_TEST) self.testsTab.setCurrentIndex(int(defaultTab)) else: self.mainTab.setCurrentIndex(MAIN_TAB_DEV) self.connectorsTab.setCurrentIndex(int(defaultTab) - 2) def hideWidgetsHeader(self): """ Hide the widget header """ self.line.hide() self.title.hide() self.labelHelp.hide() def showWidgetsHeader(self): """ Show the widget header """ self.line.show() self.title.show() self.labelHelp.show() def createConnections(self): """ Create qt connections """ pass def initLocalRepo(self): """ Initialize the local repository """ if self.localConfigured != "Undefined": self.localRepository.active() def cleanLocalRepo(self): """ Cleanup the local repository """ self.localRepository.deactive() def local(self): """ Returns the local repository widget @return: LocalRepository.Repository @rtype: QWidget """ return self.localRepository def localDialogSave(self): """ Return the save/open dialog """ return self.localSaveOpen def remote(self): """ Returns the remote repository widget @return: RemoteRepository.Repository @rtype: QWidget """ return self.remoteRepository def remoteAdapter(self): """ Returns the remote repository widget @return: RemoteRepository.Repository @rtype: QWidget """ return self.adaptersRemoteRepository def remoteLibrary(self): """ Returns the remote repository widget @return: RemoteRepository.Repository @rtype: QWidget """ return self.librariesRemoteRepository def decodeData(self, b64data): """ Decode data """ data_json = '' try: data_decoded = base64.b64decode(b64data) except Exception as e: self.error('unable to decode from base64 structure: %s' % str(e)) else: try: data_uncompressed = zlib.decompress(data_decoded) except Exception as e: self.error('unable to decompress: %s' % str(e)) else: try: if sys.version_info > (3, ): data_json = json.loads( data_uncompressed.decode('utf-8')) else: data_json = json.loads(data_uncompressed) except Exception as e: self.error('unable to decode from json structure: %s' % str(e)) return data_json # functions for remote repository def onLoadRemote(self, data): """ Called on load remote actions """ self.mainTab.setEnabled(True) self.labelHelp.setEnabled(True) # if UCI.RIGHTS_TESTER in RCI.instance().userRights: # self.remoteRepository.setConnected() # self.remoteRepository.setEnabled(True) # self.localRepository.setEnabled(True) # self.testsTab.setTabEnabled( TAB_REMOTE_POS, True ) # if self.localConfigured != "Undefined": # self.testsTab.setTabEnabled( TAB_LOCAL_POS, True ) # else: # self.testsTab.setTabEnabled( TAB_LOCAL_POS, False ) # self.connectorsTab.setTabEnabled( TAB_LIBRARY_POS, False ) # self.connectorsTab.setTabEnabled( TAB_ADAPTER_POS, False ) # defaultTab = Settings.instance().readValue( key = 'Repositories/default-repo-test' ) # if int(defaultTab) == TAB_LOCAL_POS or int(defaultTab) == TAB_REMOTE_POS: # self.mainTab.setCurrentIndex(MAIN_TAB_TEST) # self.testsTab.setCurrentIndex(int(defaultTab)) # else: # self.mainTab.setCurrentIndex(MAIN_TAB_DEV) # self.connectorsTab.setCurrentIndex(int(defaultTab)-2) # self.remoteRepository.defaultActions() # self.remoteRepository.initialize(listing= data['repo'] ) # self.remoteRepository.initializeProjects( projects=data['projects'], # defaultProject=data['default-project'] ) # if UCI.RIGHTS_TESTER in RCI.instance().userRights: # self.connectorsTab.setTabEnabled( TAB_ADAPTER_POS, True ) # self.connectorsTab.setTabEnabled( TAB_LIBRARY_POS, True ) # if UCI.RIGHTS_TESTER in RCI.instance().userRights: # exception if the developer if also a tester # defaultTab = Settings.instance().readValue( key = 'Repositories/default-repo-test' ) # if int(defaultTab) == TAB_LOCAL_POS or int(defaultTab) == TAB_REMOTE_POS: # self.mainTab.setCurrentIndex(MAIN_TAB_TEST) # self.testsTab.setCurrentIndex(int(defaultTab)) # else: # self.mainTab.setCurrentIndex(MAIN_TAB_DEV) # self.connectorsTab.setCurrentIndex(int(defaultTab)-2) # else: # defaultTab = Settings.instance().readValue( key = 'Repositories/default-repo-dev' ) # if int(defaultTab) == TAB_LOCAL_POS or int(defaultTab) == TAB_REMOTE_POS: # self.mainTab.setCurrentIndex(MAIN_TAB_TEST) # self.testsTab.setCurrentIndex(int(defaultTab)) # else: # self.mainTab.setCurrentIndex(MAIN_TAB_DEV) # self.connectorsTab.setCurrentIndex(int(defaultTab)-2) # self.adaptersRemoteRepository.setConnected() # self.adaptersRemoteRepository.setEnabled(True) # self.adaptersRemoteRepository.defaultActions() # self.adaptersRemoteRepository.initialize(listing=data['repo-adp'] ) # self.librariesRemoteRepository.setConnected() # self.librariesRemoteRepository.setEnabled(True) # self.librariesRemoteRepository.defaultActions() # self.librariesRemoteRepository.initialize( listing=data['repo-lib-adp'] ) # if UCI.RIGHTS_ADMIN in RCI.instance().userRights: self.remoteRepository.setConnected() self.remoteRepository.setEnabled(True) self.localRepository.setEnabled(True) self.testsTab.setTabEnabled(TAB_REMOTE_POS, True) if self.localConfigured != "Undefined": self.testsTab.setTabEnabled(TAB_LOCAL_POS, True) else: self.testsTab.setTabEnabled(TAB_LOCAL_POS, False) self.connectorsTab.setTabEnabled(TAB_ADAPTER_POS, True) self.connectorsTab.setTabEnabled(TAB_LIBRARY_POS, True) defaultTab = Settings.instance().readValue( key='Repositories/default-repo-test') if int(defaultTab) == TAB_LOCAL_POS or int( defaultTab) == TAB_REMOTE_POS: self.mainTab.setCurrentIndex(MAIN_TAB_TEST) self.testsTab.setCurrentIndex(int(defaultTab)) else: self.mainTab.setCurrentIndex(MAIN_TAB_DEV) self.connectorsTab.setCurrentIndex(int(defaultTab) - 2) self.remoteRepository.defaultActions() if self.remoteRepository.initializeProjects( projects=data['projects'], defaultProject=data['default-project']): self.remoteRepository.initialize(listing=data['repo']) self.adaptersRemoteRepository.setConnected() self.adaptersRemoteRepository.setEnabled(True) self.adaptersRemoteRepository.defaultActions() self.adaptersRemoteRepository.initialize(listing=data['repo-adp']) self.librariesRemoteRepository.setConnected() self.librariesRemoteRepository.setEnabled(True) self.librariesRemoteRepository.defaultActions() self.librariesRemoteRepository.initialize(listing=data['repo-lib-adp']) def onResetRemote(self): """ Called on reset remote actions """ self.mainTab.setEnabled(False) self.labelHelp.setEnabled(False) self.remoteRepository.setNotConnected() self.remoteRepository.wrepository.clear() self.remoteRepository.setEnabled(False) self.localRepository.setEnabled(False) self.localRepository.defaultActions() self.adaptersRemoteRepository.setNotConnected() self.adaptersRemoteRepository.wrepository.clear() self.adaptersRemoteRepository.setEnabled(False) self.librariesRemoteRepository.setNotConnected() self.librariesRemoteRepository.wrepository.clear() self.librariesRemoteRepository.setEnabled(False) self.testsTab.setTabEnabled(TAB_REMOTE_POS, False) self.connectorsTab.setTabEnabled(TAB_ADAPTER_POS, False) self.testsTab.setTabEnabled(TAB_LOCAL_POS, False) self.connectorsTab.setTabEnabled(TAB_LIBRARY_POS, False) defaultTab = Settings.instance().readValue( key='Repositories/default-repo-test') if int(defaultTab) == TAB_LOCAL_POS or int( defaultTab) == TAB_REMOTE_POS: self.mainTab.setCurrentIndex(MAIN_TAB_TEST) self.testsTab.setCurrentIndex(int(defaultTab)) else: self.mainTab.setCurrentIndex(MAIN_TAB_DEV) self.connectorsTab.setCurrentIndex(int(defaultTab) - 2) def onRefreshRemoteTests(self, data, projectId, forSaveAs=False): """ """ self.remoteRepository.defaultActions() if forSaveAs: self.remoteRepository.initializeSaveAs(listing=data, reloadItems=True) else: # update default project projectName = self.remoteRepository.getProjectName(projectId) self.remoteRepository.setDefaultProject(projectName=projectName) # reconstruct self.remoteRepository.initialize(listing=data) def onRefreshRemoteAdapters(self, data): """ """ self.adaptersRemoteRepository.defaultActions() self.adaptersRemoteRepository.initialize(listing=data) def onRefreshRemoteLibraries(self, data): """ """ self.librariesRemoteRepository.defaultActions() self.librariesRemoteRepository.initialize(listing=data)
def create_rows(self, layout): play_button_group = QButtonGroup(self) old_play_button_group = QButtonGroup(self) for num, (source, dest, text, dl_fname, dl_hash, extras, icon)\ in enumerate(self.list, 3): tt_text = self.build_text_help_label(text, source, extras) ico_label = QLabel('', self) ico_label.setToolTip(tt_text) if icon: ico_label.setPixmap(QPixmap.fromImage(icon)) layout.addWidget(ico_label, num, 0) tt_label = QLabel(text, self) tt_label.setToolTip(tt_text) layout.addWidget(tt_label, num, 1) if self.hide_text: tt_label.hide() # Play button. t_play_button = QPushButton(self) play_button_group.addButton(t_play_button, num - 3) t_play_button.setToolTip(self.play_help) t_play_button.setIcon(QIcon(os.path.join(icons_dir, 'play.png'))) layout.addWidget(t_play_button, num, self.play_column) if self.note[dest]: t_play_old_button = QPushButton(self) old_play_button_group.addButton(t_play_old_button, num - 3) t_play_old_button.setIcon( QIcon(os.path.join(icons_dir, 'play.png'))) if not self.hide_text: t_play_old_button.setToolTip(self.note[dest]) else: t_play_old_button.setToolTip(self.play_old_help_short) layout.addWidget(t_play_old_button, num, self.play_old_column) else: dummy_label = QLabel('', self) dummy_label.setToolTip(self.play_old_empty_line_help) layout.addWidget(dummy_label, num, self.play_old_column) # The group where we later look what to do: t_button_group = QButtonGroup(self) t_button_group.setExclusive(True) # Now the four buttons t_add_button = QPushButton(self) t_add_button.setCheckable(True) t_add_button.setChecked(True) t_add_button.setFlat(True) t_add_button.setToolTip(self.add_help_text_short) t_add_button.setIcon(QIcon(os.path.join(icons_dir, 'add.png'))) layout.addWidget(t_add_button, num, self.add_column) t_button_group.addButton(t_add_button, action['add']) t_keep_button = QPushButton(self) t_keep_button.setCheckable(True) t_keep_button.setFlat(True) t_keep_button.setToolTip(self.keep_help_text_short) t_keep_button.setIcon(QIcon(os.path.join(icons_dir, 'keep.png'))) layout.addWidget(t_keep_button, num, self.keep_column) t_button_group.addButton(t_keep_button, action['keep']) t_delete_button = QPushButton(self) t_delete_button.setCheckable(True) t_delete_button.setFlat(True) t_delete_button.setToolTip(self.delete_help_text_short) t_delete_button.setIcon(QIcon(os.path.join(icons_dir, 'delete.png'))) layout.addWidget(t_delete_button, num, self.delete_column) t_button_group.addButton(t_delete_button, action['delete']) t_blacklist_button = QPushButton(self) t_blacklist_button.setCheckable(True) t_blacklist_button.setFlat(True) t_blacklist_button.setToolTip(self.blacklist_help_text_short) t_blacklist_button.setIcon(QIcon(os.path.join(icons_dir, 'blacklist.png'))) if self.show_skull_and_bones: layout.addWidget( t_blacklist_button, num, self.blacklist_column) else: t_blacklist_button.hide() t_button_group.addButton(t_blacklist_button, action['blacklist']) self.buttons_groups.append(t_button_group) play_button_group.buttonClicked.connect( lambda button: play(self.list[play_button_group.id(button)][3])) old_play_button_group.buttonClicked.connect( lambda button: playFromText( self.note[self.list[old_play_button_group.id(button)][1]]))
class Metadata(QWidget): def __init__(self): QWidget.__init__(self) self.tabs = QTabWidget() self.nometa = QLabel("No EXIF metadata found") self.nometa.setAlignment(Qt.AlignCenter) self.box = QHBoxLayout() self.setLayout(self.box) self.box.addWidget(self.tabs) self.box.addWidget(self.nometa) self.nometa.hide() self.tabs.show() self.tabs.setTabPosition(QTabWidget.East) def process(self, node): for idx in xrange(0, self.tabs.count()): widget = self.tabs.widget(idx) del widget self.tabs.clear() self.node = node file = self.node.open() tags = EXIF.process_file(file) if len(tags) == 0: self.nometa.setSizePolicy(self.tabs.sizePolicy()) self.tabs.hide() self.nometa.show() else: self.tabs.show() self.nometa.hide() sortedTags = {} for tag in tags.keys(): if tag not in ('JPEGThumbnail', 'TIFFThumbnail', 'Filename', 'EXIF MakerNote'): spaceidx = tag.find(" ") ifd = tag[:spaceidx].strip() if ifd == "Image": ifd = "IFD 0 (Image)" if ifd == "Thumbnail": ifd = "IFD 1 (Thumbnail)" key = tag[spaceidx:].strip() try: val = str(tags[tag]) except: val = "cannot be decoded" if ifd not in sortedTags.keys(): sortedTags[ifd] = [] sortedTags[ifd].append((key, val)) for ifd in sortedTags.keys(): table = QTableWidget(len(sortedTags[ifd]), 2) table.setShowGrid(False) table.setAlternatingRowColors(True) table.verticalHeader().hide() table.horizontalHeader().setClickable(False) table.horizontalHeader().setStretchLastSection(True) table.setHorizontalHeaderLabels(["Tag", "Value"]) table.setSelectionBehavior(QAbstractItemView.SelectRows) self.tabs.addTab(table, ifd) row = 0 for res in sortedTags[ifd]: key = QTableWidgetItem(res[0]) key.setFlags(Qt.ItemIsSelectable|Qt.ItemIsEnabled) val = QTableWidgetItem(res[1]) val.setFlags(Qt.ItemIsSelectable|Qt.ItemIsEnabled) table.setItem(row, 0, key) table.setItem(row, 1, val) row += 1 if 'JPEGThumbnail' in tags.keys(): label = QLabel() img = QImage() img.loadFromData(tags['JPEGThumbnail']) label.setPixmap(QPixmap.fromImage(img)) label.setAlignment(Qt.AlignCenter) self.tabs.addTab(label, "Embedded Thumbnail") if 'TIFFThumbnail' in tags.keys(): label = QLabel() img = QImage() img.loadFromData(tags['TIFFThumbnail']) label.setPixmap(QPixmap.fromImage(img)) label.setAlignment(Qt.AlignCenter) self.tabs.addTab(label, "Embedded Thumbnail") file.close()
class CreerSuite(MyMiniFrame): def __init__(self, parent): MyMiniFrame.__init__(self, parent, u"Représenter une suite") ##self.SetExtraStyle(wx.WS_EX_BLOCK_EVENTS ) self.parent = parent self._param_ = self.parent._param_ ##p = self.panel = QWidget(self) self.sizer = sizer = QVBoxLayout() sizer.addWidget(QLabel(u"Choisissez le mode de génération de la suite :")) self.mode = QComboBox() self.mode.addItems([u"u(n+1)=f(u(n))", u"u(n)=f(n)"]) self.mode.setCurrentIndex(0) self.mode.currentIndexChanged.connect(self.EvtChoixMode) sizer.addWidget(self.mode) f = QHBoxLayout() f.addWidget(QLabel(u"Choisissez la fonction f :")) self.fonction = QComboBox() self.fonction.addItems(["Y" + str(i+1) for i in xrange(self.parent.nombre_courbes)]) self.fonction.setCurrentIndex(0) self.fonction.currentIndexChanged.connect(self.EvtChoixFonction) f.addWidget(self.fonction) sizer.addLayout(f) start = QHBoxLayout() start.addWidget(QLabel(u"Commencer pour n =")) self.n0 = QSpinBox() self.n0.setRange(0, 1000000) self.n0.setValue(0) start.addWidget(self.n0) sizer.addLayout(start) terme = QHBoxLayout() self.label_init = QLabel(u"Terme initial :") terme.addWidget(self.label_init) self.un0 = QLineEdit("1") self.un0.setMinimumWidth(100) terme.addWidget(self.un0) sizer.addLayout(terme) ligne = QFrame() ligne.setFrameStyle(QFrame.HLine|QFrame.Raised) ##sizer.addWidget(wx.StaticLine(p, -1, style=wx.LI_HORIZONTAL), 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) nbr = QHBoxLayout() nbr.addWidget(QLabel(u"Construire les")) self.termes = QSpinBox() self.termes.setRange(0, 100) self.termes.setValue(5) nbr.addWidget(self.termes) nbr.addWidget(QLabel(u"premiers termes.")) sizer.addLayout(nbr) ligne = QFrame() ligne.setFrameStyle(QFrame.HLine|QFrame.Raised) sizer.addWidget(ligne) #p.SetSizer(sizer) boutons = QHBoxLayout() fermer = QPushButton(u"Fermer") boutons.addWidget(fermer) lancer = QPushButton(u"Créer") boutons.addWidget(lancer) fermer.clicked.connect(self.close) lancer.clicked.connect(self.Creer) sizer.addLayout(boutons) self.setLayout(sizer) ##self.SetClientSize(p.GetSize()) def Creer(self): ## self.parent.creer_feuille() # nouvelle feuille de travail # style des lignes : style, epaisseur = self._param_.style_suites_recurrentes kw_lignes = {"style": style, "epaisseur": epaisseur} # Les suites s'enregistrent auprès du module traceur # if not hasattr(self.parent, "suites"): # self.parent.suites = {} objets = self.parent.feuille_actuelle.objets i = self.fonction.currentIndex() nom_courbe = 'Cf' + str(i + 1) if objets.has_key(nom_courbe): courbe = objets[nom_courbe] fonction = courbe.fonction elif self.parent.boites[i].text(): self.parent.valider(i=i) courbe = objets[nom_courbe] fonction = courbe.fonction else: # TODO: afficher un vrai message d'erreur raise KeyError, "courbe inexistante : %s" %nom_courbe if self.mode.currentIndex() == 0: # cas des suites définies par récurrence u0 = eval_safe(self.un0.text()) n0 = self.n0.value() d = objets.suiteDroited = Droite(Point(0, 0), Point(1, 1)) d.label("$y\ =\ x$") M = objets.suitePointM0 = Point(u0, 0) M.label("$u_%s$" %(n0)) # self.parent.suites["u"] = [d, M] for i in xrange(self.termes.value() - 1): # (Attention, ça ne va pas marcher pour les fonctions définies par morceau) u1 = fonction(u0) N = Point(u0, u1, visible=self._param_.afficher_points_de_construction) N.etiquette.visible = False s = Segment(M, N, **kw_lignes) P = Point(0, u1) P.label("$u_%s$" %(i + n0 + 1)) t = Segment(N, P, **kw_lignes) Q = Point(u1, u1, visible = self._param_.afficher_points_de_construction) Q.etiquette.visible = False r = Segment(P, Q, **kw_lignes) M = Point(u1, 0) M.label("$u_%s$" %(i + n0 + 1)) #self.parent.suites[u"u"].append([M, N, P, s, t]) setattr(objets, "SuitePointN" + str(i), N) setattr(objets, "suitePointP" + str(i), P) setattr(objets, "suitePointQ" + str(i), Q) setattr(objets, "suiteSegments" + str(i), s) setattr(objets, "suiteSegmentt" + str(i), t) setattr(objets, "suiteSegmentr" + str(i), r) setattr(objets, "suitePointM" + str(i + 1), M) a = Segment(Q, M, **kw_lignes) setattr(objets, "suiteSegmenta" + str(i), a) u0 = u1 self.parent.canvas.zoom_auto() else: # suites définies explicitement n0 = self.n0.text() # self.parent.suites[u"u"] = [] for i in xrange(n0, n0 + self.termes.text()): yi = fonction(i) M = Point(i, 0) M.label(str(i)) N = Point(i, yi) N.etiquette.visible = False P = Point(0, yi) P.label("$u_%s$" %i) s = Segment(M, N, **kw_lignes) t = Segment(N, P, **kw_lignes) setattr(objets, "suitePointM" + str(i), M) setattr(objets, "suitePointN" + str(i), N) setattr(objets, "suitePointP" + str(i), P) setattr(objets, "suiteSegments" + str(i), s) setattr(objets, "suiteSegmentt" + str(i), t) self.parent.canvas.zoom_auto() def EvtChoixMode(self, index): if index == 1: self.label_init.hide() self.un0.hide() else: self.un0.show() self.label_init.show() def EvtChoixFonction(self, index): for i in xrange(self.parent.nombre_courbes): self.parent.boites[i].setChecked(i==index)
class ReactionProfile(QWidget): def __init__(self, reaction, readonly): super(ReactionProfile, self).__init__() self._painter = QPainter() self._canshowreaction = True self._IsReadOnly = readonly # Show labels checkbox widget self._showlabels = QCheckBox("Show data", self) self._showlabels.setChecked(False) self._showlabels.setGeometry(0, 0, 80, 20) self._showlabels.clicked.connect(self.update) # The buttons if self._IsReadOnly: self._CurrentReaction = copy.deepcopy(reaction) else: self._CurrentReaction = reaction self._rcolbtn = QPushButton("Set reactant colour", self) self._rcolbtn.setGeometry(140, 60, 110, 30) self._rcolbtn.clicked.connect(self.SetReactantColour) self._pcolbtn = QPushButton("Set product colour", self) self._pcolbtn.setGeometry(350, 60, 110, 30) self._pcolbtn.clicked.connect(self.SetProductColour) self._clonebtn = QPushButton("Compare reaction", self) self._clonebtn.setGeometry(10, 310, 120, 30) self._clonebtn.clicked.connect(self.Clone) self._concbtn = QPushButton("Concentration graphs", self) self._concbtn.setGeometry(10, 100, 120, 30) self._concbtn.clicked.connect(self.MakeConcGraphs) self._ratebtn = QPushButton("Rate graphs", self) self._ratebtn.setGeometry(10, 130, 120, 30) self._ratebtn.clicked.connect(self.MakeRateGraphs) self._getkcbtn = QPushButton("Calculate Kc", self) self._getkcbtn.setGeometry(10, 180, 120, 30) self._getkcbtn.clicked.connect(self.GetKc) self._workingbtn = QPushButton("Show working", self) self._workingbtn.setGeometry(10, 225, 120, 30) self._workingbtn.clicked.connect(self.ShowWorking) self._startanim = QPushButton("Start animation", self) self._startanim.setGeometry(10, 260, 120, 30) self._startanim.clicked.connect(self.StartAnimation) # The labels self._catalabel = QLabel("", self) self._catalabel.setGeometry(250, 60, 100, 40) self._catalabel.setAlignment(Qt.AlignCenter) self._kclabel = QLabel(self) self._kclabel.setGeometry(20, 205, 140, 20) self._volumelabel = QLabel(self) self._volumelabel.setGeometry(200, 317, 140, 20) # Set up reactant and product labels formulafont = QFont() formulafont.setBold(True) formulafont.setPointSize(12) self._rpalette = QPalette() self._ppalette = QPalette() self._reactantlabel = QLabel("", self) self._reactantlabel.setGeometry(0, 20, 268, 32) self._reactantlabel.setAlignment(Qt.AlignRight | Qt.AlignVCenter) self._reactantlabel.setFont(formulafont) self._reactantlabel.setPalette(self._rpalette) self._reactantlabel.show() self._productlabel = QLabel("", self) self._productlabel.setGeometry(332, 20, 268, 32) self._productlabel.setAlignment(Qt.AlignVCenter) self._productlabel.setFont(formulafont) self._productlabel.setPalette(self._ppalette) self._productlabel.show() # Other properties self._Squares = [] for x in range(100): self._Squares.append(Square(200+((x % 10) * 20), 120 + ((x // 10) * 20), self._CurrentReaction)) self._timer = QTimer(self) self._timer.setInterval(30) self._timer.setSingleShot(False) self._timer.timeout.connect(self.ContinueAnimation) self._no_of_anim_updates = 0 self._ExtraWindows = [] self._kcdifference = "" self._rflipchance = 0 self._pflipchance = 0 self._graphs = None def paintEvent(self, e): reactantside = "" productside = "" for x in range(len(self._CurrentReaction.GetReactants())): reactant = self._CurrentReaction.GetReactants()[x] if reactant.GetUsed(): if x > 0: reactantside += " + " reactantside += reactant.GetFormulaForLabels() for x in range(len(self._CurrentReaction.GetProducts())): product = self._CurrentReaction.GetProducts()[x] if product.GetUsed(): if x > 0: productside += " + " productside += product.GetFormulaForLabels() self._rpalette.setColor(QPalette.WindowText, self._CurrentReaction.GetReactantColour()) self._ppalette.setColor(QPalette.WindowText, self._CurrentReaction.GetProductColour()) self._reactantlabel.setPalette(self._rpalette) self._productlabel.setPalette(self._ppalette) self._painter.begin(self) self._painter.setFont(QFont("Arial", 20, 50, False)) self._painter.setPen(QPen(self._CurrentReaction.GetReactantColour())) if self._CurrentReaction.GetCatalyst().GetUsed(): self._catalabel.setText("Catalyst: "+ self._CurrentReaction.GetCatalyst().GetFormulaForLabels()+"<br>Moles: "+ str(self._CurrentReaction.GetCatalyst().GetInitialMoles())+"<br>Strength: "+ self._CurrentReaction.GetCatalyst().GetEfficacyAsString()) self._catalabel.show() else: self._catalabel.hide() self._reactantlabel.setText(reactantside) self._productlabel.setText(productside) target = QRectF(278, 20, 44, 32) arrows = QPixmap("assets/double arrow h.png") portion = QRectF(10, 0, 44, 32) self._painter.drawPixmap(target, arrows, portion) self._painter.setPen(QPen(self._CurrentReaction.GetProductColour())) self._painter.setPen(QPen(QColor(0, 0, 0, 255))) self._painter.setFont(QFont("Arial", 8, 50, False)) self._volumelabel.setText("Vessel volume: "+str(self._CurrentReaction.GetVolume())+" dm<sup>3</sup>") self._painter.drawText(200, 340, "Vessel temperature: "+str(self._CurrentReaction.GetTemperature())+" K") if self._CurrentReaction.GetEndothermic(): self._painter.drawText(200, 350, "Reaction is endothermic") else: self._painter.drawText(200, 350, "Reaction is exothermic") if self._showlabels.isChecked(): if self._kcdifference == "": self._kclabel.show() else: self._kclabel.hide() self._painter.drawText(420, 330, self._kcdifference) else: self._kclabel.hide() for x in self._Squares: x.Draw(self._painter) self._painter.end() def SetReaction(self, reaction): if self._IsReadOnly: self._CurrentReaction = copy.deepcopy(reaction) else: self._CurrentReaction = reaction self.update() def GetReaction(self): return self._CurrentReaction def MakeConcGraphs(self): gwg = GraphWindowGroup(GraphWindow(self._CurrentReaction, "Concentration", self, False), GraphWindow(self.parent().parent().parent().GetComparingReaction(), "Concentration", self, False), self) gwg.setGeometry(0, 400, 800, 320) self._ExtraWindows.append(gwg) self._ExtraWindows[-1].show() def MakeRateGraphs(self): gwg = GraphWindowGroup(GraphWindow(self._CurrentReaction, "Rate", self, False), GraphWindow(self.parent().parent().parent().GetComparingReaction(), "Rate", self, False), self) gwg.setGeometry(420, 400, 800, 320) self._ExtraWindows.append(gwg) self._ExtraWindows[-1].show() def SetReactantColour(self): picker = QColorDialog() picker.exec_() if picker.selectedColor() is not None: self._CurrentReaction.SetReactantColour(picker.selectedColor()) def SetProductColour(self): picker = QColorDialog() picker.exec_() if picker.selectedColor() is not None: self._CurrentReaction.SetProductColour(picker.selectedColor()) def GetKc(self): kc = self._CurrentReaction.GetKc() newkc = "K<sub>c</sub>" x = 2 while x in range(len(kc)): if kc[x] == "^": x += 1 newkc += "<sup>" newkc += kc[x] newkc += "</sup>" else: newkc += kc[x] x += 1 self._kclabel.setText(newkc) self.update() def ShowWorking(self): getcontext().prec = 3 working = QPlainTextEdit() working.setWindowTitle("Kc calculation") reactants = [] products = [] for x in self._CurrentReaction.GetReactants(): if x.GetUsed(): reactants.append(x) for x in self._CurrentReaction.GetProducts(): if x.GetUsed(): products.append(x) working.appendPlainText("Concentration = moles / volume") volume = self._CurrentReaction.GetVolume() working.appendPlainText("Volume = "+str(volume)+" dm^3") pvalues = [] rvalues = [] for x in products: working.appendPlainText("Concentration of "+x.GetFormula()+" = "+str(Decimal(x.GetConcentration(volume)) + Decimal(0.0))+" mol dm^-3") pvalues.append(x.GetConcentration(volume)) pvalues.append(x.GetSRatio()) for x in reactants: working.appendPlainText("Concentration of "+x.GetFormula()+" = "+str(Decimal(x.GetConcentration(volume)) + Decimal(0.0))+" mol dm^-3") rvalues.append(x.GetConcentration(volume)) rvalues.append(x.GetSRatio()) kcvalue = "Value of Kc =" x = 0 while x < len(pvalues): kcvalue += " ("+str(Decimal(pvalues[x]) + Decimal(0.0))+")^" x += 1 kcvalue += str(pvalues[x]) x += 1 kcvalue += " /" x = 0 while x < len(rvalues): kcvalue += " ("+str(Decimal(rvalues[x]) + Decimal(0.0))+")^" x += 1 kcvalue += str(rvalues[x]) x += 1 working.appendPlainText(kcvalue) rproductsum = 0 for x in reactants: rproductsum += x.GetSRatio() pproductsum = 0 for x in products: pproductsum += x.GetSRatio() working.appendPlainText("There are "+str(len(reactants))+" reactants, with units mol dm^-3.") working.appendPlainText("The product of these units is mol^"+str(rproductsum)+" dm^"+str(rproductsum * -3)+".") working.appendPlainText("There are "+str(len(products))+" products, with units mol dm^-3.") working.appendPlainText("The product of these units is mol^"+str(pproductsum)+" dm^"+str(pproductsum * -3)+".") working.appendPlainText("The product units must be divided by the reactant units, so") working.appendPlainText(self._CurrentReaction.GetKc()) self._ExtraWindows.append(working) working.show() def StartAnimation(self): self._no_of_anim_updates = 0 reactants = [] for x in self._CurrentReaction.GetReactants(): if x.GetUsed(): reactants.append(x) products = [] for x in self._CurrentReaction.GetProducts(): if x.GetUsed(): products.append(x) self._eqmratio = self.GetRPRatio(reactants, products) self._rflipchance = int(self._eqmratio * 100) # self._pflipchance = int((1 / self._eqmratio) * 100) self._pflipchance = int((1 - self._eqmratio) * 100) if self._CurrentReaction.GetCatalyst().GetUsed(): efficacy = self._CurrentReaction.GetCatalyst().GetEfficacy() self._rflipchance /= efficacy self._pflipchance /= efficacy flipchancechangefromcata = 2.0 * (self._CurrentReaction.GetCatalyst().GetInitialMoles() / 100) if efficacy > 1: flipchancechangefromcata *= -1 self._rflipchance = int(self._rflipchance + flipchancechangefromcata) self._pflipchance = int(self._pflipchance + flipchancechangefromcata) for x in self._Squares: x.Reset() self._timer.start() def ContinueAnimation(self): self._no_of_anim_updates += 1 reactantsquares = 0 for x in self._Squares: if x.GetIsReactant(): reactantsquares += 1 print("Reactant squares: "+str(reactantsquares)) # currentratio = reactantsquares / (101 - reactantsquares) currentratio = reactantsquares / 100 newrflipchance = self._rflipchance newpflipchance = self._pflipchance if currentratio < int(self._eqmratio * 100): newrflipchance -= currentratio * 0.2 newpflipchance += currentratio * 0.2 elif currentratio > int(self._eqmratio * 100): newrflipchance += currentratio * 0.2 newpflipchance -= currentratio * 0.2 for x in self._Squares: x.Flip(newrflipchance, newpflipchance) self.update() for x in self._ExtraWindows: if type(x) == GraphWindowGroup: x.update() if self._no_of_anim_updates > 1000: self._timer.stop() def RemoveMe(self, qwidg): self._ExtraWindows.remove(qwidg) def Clone(self): self.parent().parent().parent().SetComparingReaction(self._CurrentReaction) def SetKcDifference(self, string): self._kcdifference = string def PrintGraph(self, painter, graphof): GraphWindow(self._CurrentReaction, graphof, self, True).render(painter) def GetRPRatio(self, reactants, products): # volume = self._CurrentReaction.GetVolume() # arc = 0 # for x in reactants: # arc += x.GetConcentration(volume) # arc /= len(reactants) # apc = 0 # for x in products: # apc += x.GetConcentration(volume) # apc /= len(products) # return arc / apc rm = 0 for x in reactants: rm += x.GetInitialMoles() pm = 0 for x in products: pm += x.GetInitialMoles() return rm / (rm + pm) def GetAnimUpdates(self): return self._no_of_anim_updates
class LdapWidget(DirectoryWidget): def __init__(self, config, specific_config, mainwindow, parent=None): assert config is not None assert specific_config is not None DirectoryWidget.__init__(self, config, specific_config, mainwindow, parent) self.buildInterface(config) self.updateView(self.specific_config) def buildInterface(self, config): #<server uri> self.uri = QLineEdit() self.texts.add(self.uri) self.connect(self.uri, SIGNAL('textChanged(QString)'), self.setUri) self.connect(self.uri, SIGNAL('textChanged(QString)'), self.signalModified) self.connect(self.uri, SIGNAL('textEdited(QString)'), self.helpURI) self.connect(self.uri, SIGNAL('editingFinished()'), self.noHelpURI) self.connect(self.uri, SIGNAL('editingFinished()'), self.updateUri) self.form.addRow(tr('LDAP Server(s) uri'), self.uri) self.uri.setToolTip(help_uri_tooltip) self.connect(self.uri, SIGNAL('returnPressed()'), self.signalModified) self.uri_message_area = MessageArea() self.empty_uri_label = QLabel() self.form.addRow(self.empty_uri_label, self.uri_message_area) self.empty_uri_label.hide() self.uri_message_area.hide() self.uri_message_area.setMessage(help_uri_title, help_uri_message_area) self.numeric_uri_warning = MessageArea() empty = QLabel() self.form.addRow(empty, self.numeric_uri_warning) empty.hide() self.numeric_uri_warning.hide() self.numeric_uri_warning.warning(numeric_warning_title, numeric_warning) self.numeric_uri_warning.setWidth(60) #</server uri> #<other fields> for args in self._genTextFieldsData(): text_input = self.addTextInput(*args[1:]) setattr(self, args[0], text_input) self.connect(text_input, SIGNAL('editingFinished(QString)'), self.valid) #</other fields> self.ssl_box = self.mkSslBox() self.connect(self.ssl_box, SIGNAL('toggled(bool)'), self.toggleSsl) self.form.addRow(self.ssl_box) self.form.addRow(separator()) test_widget = QPushButton(tr("Test this configuration")) self.form.addRow("", test_widget) test_widget.connect(test_widget, SIGNAL('clicked()'), self.test_ldap) def _genTextFieldsData(self): return ( ('dn_users', tr('LDAP DN for users'), self.setDnUsers), ('dn_groups', tr('LDAP DN for groups'), self.setDnGroups), ('user', tr('DN used to log in on the LDAP server'), self.setUser), ('password', tr('Password used to log in on the LDAP server'), self.setPassword, False) ) def test_ldap(self): dc, base, uri, filter, password = self.specific_config.generateTest() if uri is None or uri == '': QMessageBox.critical( self, "Missing data", "Please fill URI field" ) return if dc is None: dc == '' filter, ok = QInputDialog.getText( self, tr("LDAP Filter"), tr("Please enter a filter:"), QLineEdit.Normal, filter ) if not ok: return async = self.mainwindow.client.async() async.call( 'nuauth', 'testLDAP', dc, base, uri, unicode(filter), password, callback = self.success_test, errback = self.error_test ) def success_test(self, result): ans_no = tr("OK") ans_yes = tr("Show the server's answer") show_details = QMessageBox.question( self, tr('LDAP test results'), tr('LDAP test completed without error'), ans_no, ans_yes ) if show_details == 0: return title = tr('LDAP test results') QMessageBox.information( self, title, '<span><h2>%s</h2><pre>%s</pre></span>' % (title, unicode(result)) ) def error_test(self, result): basic_text = tr('LDAP test completed with an error') formatted_text = u"""\ <span> %s <pre> %s </pre> </span> """ % (basic_text, unicode(result)) QMessageBox.warning( self, tr('LDAP test results'), formatted_text ) def helpURI(self, text): self.uri_message_area.show() def noHelpURI(self): self.uri_message_area.hide() def toggleSsl(self, value): if value: self.selectCustomOrNupki(NUPKI) else: self.specific_config.custom_or_nupki = SSL_DISABLED self.signalModified() def setUri(self, uris_text): self.specific_config.setUri(self.readString(uris_text)) self.signalModified() self.numeric_uri_warning.setVisible(ip_in_ldapuri(self.specific_config.uri)) def setUser(self, user): self.specific_config.user = self.readString(user) def setPassword(self, password): self.specific_config.password = self.readString(password) def setDnUsers(self, dn): self.specific_config.dn_users = self.readString(dn) def setDnGroups(self, dn): self.specific_config.dn_groups = self.readString(dn) def mkSslBox(self): group = QGroupBox(tr("Check server certificate")) group.setCheckable(True) box = QVBoxLayout(group) #id 0 nupki = QRadioButton(tr("Upload certificate")) #id 1 custom = QRadioButton(tr("Use an internal PKI")) hbox = QHBoxLayout() box.addLayout(hbox) self.nupki_or_custom = QButtonGroup() self.connect(self.nupki_or_custom, SIGNAL('buttonClicked(int)'), self.toggleCustomOrNupki) for index, radio in enumerate((custom, nupki)): hbox.addWidget(radio) self.nupki_or_custom.addButton(radio, index) self.file_selector_widget = QWidget() vbox = QVBoxLayout(self.file_selector_widget) selector_label = QLabel(tr("Manually uploaded LDAP certificate")) vbox.addWidget(selector_label) add_cert_trigger = AddButton(text=tr("Upload a certificate")) vbox.addWidget(add_cert_trigger) vbox.addWidget(separator()) self.has_cert_message = QLabel( tr("There is no manually uploaded server certificate") ) self.del_cert = RemButton( tr("Delete certificate file from server") ) vbox.addWidget(self.has_cert_message) vbox.addWidget(self.del_cert) self.connect(add_cert_trigger, SIGNAL('clicked()'), self.upload_server_cert) self.connect(self.del_cert, SIGNAL('clicked()'), self.delete_server_cert) self.nupki_message = MessageArea() self.nupki_message.setMessage(tr("Warning"), tr( "There is no server certificate in the internal PKI.<br/>" "Please import or generate one using an internal PKI." ) ) for anti_button, widget in ((custom, self.nupki_message), (nupki, self.file_selector_widget)): box.addWidget(widget) self.connect(anti_button, SIGNAL('toggled(bool)'), widget.setVisible) self.selectCustomOrNupki(CUSTOM) return group def upload_server_cert(self): dialog = UploadDialog( selector_label=tr("LDAP certificate"), filter=tr("Certificate file (*.crt *.pem *)") ) accepted = dialog.exec_() if accepted != QDialog.Accepted: return filename = dialog.filename if not filename: return with open(filename, 'rb') as fd: content = fd.read() content = encodeFileContent(content) self.mainwindow.addToInfoArea(tr('Uploading of a certificate file for the ldap server')) async = self.mainwindow.client.async() async.call("nuauth", "upload_ldap_server_cert", content, callback = self.success_upload, errback = self.error_upload ) def success_upload(self, value): self.mainwindow.addToInfoArea(tr('[LDAP server cert upload] Success!')) self.specific_config.server_cert_set = True self.setServerCert() self.signalModified() def error_upload(self, value): self.mainwindow.addToInfoArea(tr('[LDAP server cert upload] Error!'), COLOR_ERROR) self.mainwindow.addToInfoArea(tr('[LDAP server cert upload] %s') % value, COLOR_ERROR) def setServerCert(self): if self.specific_config.server_cert_set: self.del_cert.show() self.has_cert_message.hide() else: self.del_cert.hide() self.has_cert_message.show() def delete_server_cert(self): confirm_box = QMessageBox(self) confirm_box.setText( tr( "Please confirm the deletion of the " "manually uploaded LDAP server certificate." ) ) confirm_box.setInformativeText( tr("Do you really want to delete the certificate file?") ) confirm_box.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel) confirm_box.setDefaultButton(QMessageBox.Cancel) confirm = confirm_box.exec_() if confirm != QMessageBox.Ok: return async = self.mainwindow.client.async() async.call("nuauth", "delete_ldap_server_cert", callback = self.success_delete, errback = self.error_delete ) def success_delete(self, value): self.mainwindow.addToInfoArea(tr('[LDAP server cert deletion] Success!')) self.specific_config.server_cert_set = False self.setServerCert() self.signalModified() def error_delete(self, value): self.mainwindow.addToInfoArea(tr('[LDAP server cert deletion] Error!'), COLOR_ERROR) self.mainwindow.addToInfoArea(tr('[LDAP server cert deletion] %s') % value, COLOR_ERROR) def toggleCustomOrNupki(self, id): if id == 0: self.specific_config.custom_or_nupki = NUPKI else: self.specific_config.custom_or_nupki = CUSTOM self.signalModified() def selectCustomOrNupki(self, custom_or_nupki): if custom_or_nupki == CUSTOM: self.file_selector_widget.setEnabled(True) self.nupki_message.hide() id = 1 else: custom_or_nupki = NUPKI self.file_selector_widget.hide() id = 0 self.nupki_or_custom.button(id).setChecked(True) def setSslData(self, config): ssl_enabled = (SSL_DISABLED != config.custom_or_nupki) self.ssl_box.setChecked(ssl_enabled) if ssl_enabled: self.selectCustomOrNupki(config.custom_or_nupki) def updateUri(self, config=None): if config is None: config = self.specific_config self.setText(self.uri, config.uri) def updateView(self, config=None): if config is None: config = self.specific_config self.updateUri(config=config) self.setSslData(config) #never copy this one: self.setDefaultText(self.dn_users, self.specific_config.dn_users) self.setDefaultText(self.dn_groups, self.specific_config.dn_groups) self.setDefaultText(self.user, config.user) self.setDefaultText(self.password, config.password) self.setServerCert()
class LaserRangeFinder(PluginBase): def __init__(self, *args): PluginBase.__init__(self, BrickletLaserRangeFinder, *args) self.lrf = self.device self.cbe_distance = CallbackEmulator(self.lrf.get_distance, self.cb_distance, self.increase_error_count) self.cbe_velocity = CallbackEmulator(self.lrf.get_velocity, self.cb_velocity, self.increase_error_count) self.current_distance = None # int, cm self.current_velocity = None # float, m/s plots_distance = [('Distance', Qt.red, lambda: self.current_distance, format_distance)] plots_velocity = [('Velocity', Qt.red, lambda: self.current_velocity, '{:.2f} m/s'.format)] self.plot_widget_distance = PlotWidget('Distance [cm]', plots_distance) self.plot_widget_velocity = PlotWidget('Velocity [m/s]', plots_velocity) self.mode_label = QLabel('Mode:') self.mode_combo = QComboBox() self.mode_combo.addItem("Distance: 1cm resolution, 40m max") self.mode_combo.addItem("Velocity: 0.10 m/s resolution, 12.70m/s max") self.mode_combo.addItem("Velocity: 0.25 m/s resolution, 31.75m/s max") self.mode_combo.addItem("Velocity: 0.50 m/s resolution, 63.50m/s max") self.mode_combo.addItem("Velocity: 1.00 m/s resolution, 127.00m/s max") self.mode_combo.currentIndexChanged.connect(self.mode_changed) self.mode_combo.hide() self.label_average_distance = QLabel('Moving Average for Distance:') self.spin_average_distance = QSpinBox() self.spin_average_distance.setMinimum(0) self.spin_average_distance.setMaximum(50) self.spin_average_distance.setSingleStep(1) self.spin_average_distance.setValue(10) self.spin_average_distance.editingFinished.connect( self.spin_average_finished) self.label_average_velocity = QLabel('Moving Average for Velocity:') self.spin_average_velocity = QSpinBox() self.spin_average_velocity.setMinimum(0) self.spin_average_velocity.setMaximum(50) self.spin_average_velocity.setSingleStep(1) self.spin_average_velocity.setValue(10) self.spin_average_velocity.editingFinished.connect( self.spin_average_finished) self.enable_laser = QCheckBox("Enable Laser") self.enable_laser.stateChanged.connect(self.enable_laser_changed) self.label_acquisition_count = QLabel('Acquisition Count:') self.spin_acquisition_count = QSpinBox() self.spin_acquisition_count.setMinimum(1) self.spin_acquisition_count.setMaximum(255) self.spin_acquisition_count.setSingleStep(1) self.spin_acquisition_count.setValue(128) self.enable_qick_termination = QCheckBox("Quick Termination") self.label_threshold = QLabel('Threshold:') self.threshold = QCheckBox("Automatic Threshold") self.spin_threshold = QSpinBox() self.spin_threshold.setMinimum(1) self.spin_threshold.setMaximum(255) self.spin_threshold.setSingleStep(1) self.spin_threshold.setValue(1) self.label_frequency = QLabel('Frequency [Hz]:') self.frequency = QCheckBox( "Automatic Frequency (Disable for Velocity)") self.spin_frequency = QSpinBox() self.spin_frequency.setMinimum(10) self.spin_frequency.setMaximum(500) self.spin_frequency.setSingleStep(1) self.spin_frequency.setValue(10) self.spin_acquisition_count.editingFinished.connect( self.configuration_changed) self.enable_qick_termination.stateChanged.connect( self.configuration_changed) self.spin_threshold.editingFinished.connect(self.configuration_changed) self.threshold.stateChanged.connect(self.configuration_changed) self.spin_frequency.editingFinished.connect(self.configuration_changed) self.frequency.stateChanged.connect(self.configuration_changed) layout_h1 = QHBoxLayout() layout_h1.addWidget(self.plot_widget_distance) layout_h1.addWidget(self.plot_widget_velocity) layout_h2 = QHBoxLayout() layout_h2.addWidget(self.mode_label) layout_h2.addWidget(self.mode_combo) layout_h2.addWidget(self.label_average_distance) layout_h2.addWidget(self.spin_average_distance) layout_h2.addWidget(self.label_average_velocity) layout_h2.addWidget(self.spin_average_velocity) layout_h2.addStretch() layout_h2.addWidget(self.enable_laser) layout_h3 = QHBoxLayout() layout_h3.addWidget(self.label_frequency) layout_h3.addWidget(self.spin_frequency) layout_h3.addWidget(self.frequency) layout_h3.addStretch() layout_h3.addWidget(self.enable_qick_termination) layout_h4 = QHBoxLayout() layout_h4.addWidget(self.label_threshold) layout_h4.addWidget(self.spin_threshold) layout_h4.addWidget(self.threshold) layout_h4.addStretch() layout_h4.addWidget(self.label_acquisition_count) layout_h4.addWidget(self.spin_acquisition_count) self.widgets_distance = [ self.plot_widget_distance, self.spin_average_distance, self.label_average_distance ] self.widgets_velocity = [ self.plot_widget_velocity, self.spin_average_velocity, self.label_average_velocity ] for w in self.widgets_distance: w.hide() for w in self.widgets_velocity: w.hide() line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) layout = QVBoxLayout(self) layout.addLayout(layout_h1) layout.addWidget(line) layout.addLayout(layout_h2) layout.addLayout(layout_h3) layout.addLayout(layout_h4) self.has_sensor_hardware_version_api = self.firmware_version >= (2, 0, 3) self.has_configuration_api = self.firmware_version >= (2, 0, 3) def start(self): if self.has_sensor_hardware_version_api: async_call(self.lrf.get_sensor_hardware_version, None, self.get_sensor_hardware_version_async, self.increase_error_count) else: self.get_sensor_hardware_version_async(1) if self.has_configuration_api: async_call(self.lrf.get_configuration, None, self.get_configuration_async, self.increase_error_count) async_call(self.lrf.get_mode, None, self.get_mode_async, self.increase_error_count) async_call(self.lrf.is_laser_enabled, None, self.is_laser_enabled_async, self.increase_error_count) async_call(self.lrf.get_moving_average, None, self.get_moving_average_async, self.increase_error_count) async_call(self.lrf.get_distance, None, self.cb_distance, self.increase_error_count) async_call(self.lrf.get_velocity, None, self.cb_velocity, self.increase_error_count) self.cbe_distance.set_period(25) self.cbe_velocity.set_period(25) self.plot_widget_distance.stop = False self.plot_widget_velocity.stop = False def stop(self): self.cbe_distance.set_period(0) self.cbe_velocity.set_period(0) self.plot_widget_distance.stop = True self.plot_widget_velocity.stop = True def destroy(self): pass @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickletLaserRangeFinder.DEVICE_IDENTIFIER def is_laser_enabled_async(self, enabled): if enabled: self.enable_laser.setChecked(True) else: self.enable_laser.setChecked(False) def enable_laser_changed(self, state): if state == Qt.Checked: self.lrf.enable_laser() else: self.lrf.disable_laser() def mode_changed(self, value): if value < 0 or value > 4: return self.lrf.set_mode(value) if value == 0: for w in self.widgets_velocity: w.hide() for w in self.widgets_distance: w.show() else: for w in self.widgets_distance: w.hide() for w in self.widgets_velocity: w.show() def cb_distance(self, distance): self.current_distance = distance def cb_velocity(self, velocity): self.current_velocity = velocity / 100.0 def configuration_changed(self): acquisition_count = self.spin_acquisition_count.value() enable_quick_termination = self.enable_qick_termination.isChecked() if self.threshold.isChecked(): threshold = 0 else: threshold = self.spin_threshold.value() if self.frequency.isChecked(): frequency = 0 for w in self.widgets_velocity: w.hide() else: frequency = self.spin_frequency.value() for w in self.widgets_velocity: w.show() self.spin_threshold.setDisabled(threshold == 0) self.spin_frequency.setDisabled(frequency == 0) self.lrf.set_configuration(acquisition_count, enable_quick_termination, threshold, frequency) def get_configuration_async(self, conf): self.spin_acquisition_count.blockSignals(True) self.spin_acquisition_count.setValue(conf.acquisition_count) self.spin_acquisition_count.blockSignals(False) self.enable_qick_termination.blockSignals(True) self.enable_qick_termination.setChecked(conf.enable_quick_termination) self.enable_qick_termination.blockSignals(False) self.spin_threshold.blockSignals(True) self.spin_threshold.setValue(conf.threshold_value) self.spin_threshold.setDisabled(conf.threshold_value == 0) self.spin_threshold.blockSignals(False) self.spin_frequency.blockSignals(True) self.spin_frequency.setValue(conf.measurement_frequency) self.spin_frequency.setDisabled(conf.measurement_frequency == 0) self.spin_frequency.blockSignals(False) self.threshold.blockSignals(True) self.threshold.setChecked(conf.threshold_value == 0) self.threshold.blockSignals(False) self.frequency.blockSignals(True) self.frequency.setChecked(conf.measurement_frequency == 0) self.frequency.blockSignals(False) self.configuration_changed() def get_sensor_hardware_version_async(self, value): if value == 1: self.mode_combo.show() self.mode_label.show() self.label_acquisition_count.hide() self.spin_acquisition_count.hide() self.enable_qick_termination.hide() self.label_threshold.hide() self.spin_threshold.hide() self.threshold.hide() self.label_frequency.hide() self.spin_frequency.hide() self.frequency.hide() else: self.mode_combo.hide() self.mode_label.hide() self.label_acquisition_count.show() self.spin_acquisition_count.show() self.enable_qick_termination.show() self.label_threshold.show() self.spin_threshold.show() self.threshold.show() self.label_frequency.show() self.spin_frequency.show() self.frequency.show() for w in self.widgets_distance: w.show() for w in self.widgets_velocity: w.show() def get_mode_async(self, value): self.mode_combo.setCurrentIndex(value) self.mode_changed(value) def get_moving_average_async(self, avg): self.spin_average_distance.setValue(avg.distance_average_length) self.spin_average_velocity.setValue(avg.velocity_average_length) def spin_average_finished(self): self.lrf.set_moving_average(self.spin_average_distance.value(), self.spin_average_velocity.value())
class WFramework(QWidget, Logger.ClassLogger): """ Framework widget """ # action, description, misc, parameters AddStep = pyqtSignal(str, str, str, dict) UpdateStep = pyqtSignal(str, str, str, dict) CancelEdit = pyqtSignal() def __init__(self, parent): """ Constructor """ QWidget.__init__(self) self.createActions() self.createWidgets() self.createToolbar() self.createConnections() def createActions(self): """ Create qt actions """ self.addAction = QPushButton(QIcon(":/add_black.png"), '&Add Action', self) self.addAction.setMinimumHeight(40) self.addAction.setMaximumWidth(200) self.cancelAction = QtHelper.createAction(self, "&Cancel", self.cancelStep, icon=QIcon(":/undo.png"), tip = 'Cancel update') self.cancelAction.setEnabled(False) self.optionsAction = QtHelper.createAction(self, "&", self.openOptions, icon=QIcon(":/recorder-basic-small.png"), tip = 'Framework options') def openOptions(self): """ Open options dialog """ if self.optionsDialog.exec_() == QDialog.Accepted: pass def createWidgets(self): """ Create all qt widgets """ self.optionsDialog = OptionsDialog(self) self.validatorUpper = ValidatorUpper(self) self.validatorAll = ValidatorAll(self) self.validatorInt = QIntValidator(self) font = QFont() font.setBold(True) self.actionsComboBox = QComboBox(self) self.actionsComboBox.setMinimumHeight(40) for i in xrange(len(GuiSteps.ACTION_FRAMEWORK_DESCR)): if not len( GuiSteps.ACTION_FRAMEWORK_DESCR[i] ): self.actionsComboBox.insertSeparator(i+1) else: el = GuiSteps.ACTION_FRAMEWORK_DESCR[i].keys() self.actionsComboBox.addItem( list(el)[0] ) self.labelActionDescr = QLabel(self) self.labelActionDescr.setText( "%s\n" % GuiSteps.ACTION_FRAMEWORK_DESCR[0][GuiSteps.FRAMEWORK_INFO]) self.labelActionDescr.setWordWrap(True) self.labelActionDescr.hide() self.descriptionLine = QLineEdit(self) self.descriptionLine.hide() actionLayout2 = QGridLayout() self.createWidgetGetText() self.createWidgetGetWait() self.createWidgetCacheSet() self.createWidgetCheckString() self.createWidgetGetAsk() actionLayout2.addWidget( self.setCacheGroup , 0, 0) actionLayout2.addWidget( self.getCheckGroup , 1, 0) actionLayout2.addWidget( self.getTextGroup , 2, 0) actionLayout2.addWidget( self.getWaitGroup , 3, 0) actionLayout2.addWidget( self.getAskGroup , 4, 0) labelAct = QLabel( self.tr("Action: ") ) labelAct.setFont( font) self.arrowLabel = QLabel("") self.arrowLabel.setPixmap(QPixmap(":/arrow-right.png").scaledToWidth(32)) self.arrowLabel2 = QLabel("") self.arrowLabel2.setPixmap(QPixmap(":/arrow-right.png").scaledToWidth(32)) layoutFinal = QHBoxLayout() layoutFinal.addWidget( labelAct ) layoutFinal.addWidget(self.actionsComboBox) layoutFinal.addWidget( self.arrowLabel ) layoutFinal.addLayout( actionLayout2 ) layoutFinal.addWidget( self.arrowLabel2 ) layoutFinal.addWidget(self.addAction) layoutFinal.addStretch(1) self.setLayout(layoutFinal) def createToolbar(self): """ Create toolbar """ pass def createWidgetCheckString(self): """ Create widget to check string """ self.getCheckGroup = QGroupBox(self.tr("")) # check in ? self.checkInTextLine = QLineEdit(self) self.checkInTextLine.setMinimumWidth(300) self.checkInTextCombo = QComboBox(self) self.checkInTextCombo.addItems( [ "CACHE" ] ) # operator self.checkComboBox = QComboBox(self) self.checkComboBox.addItems( [ GuiSteps.OP_CONTAINS, GuiSteps.OP_NOTCONTAINS, GuiSteps.OP_REGEXP, GuiSteps.OP_NOTREGEXP, GuiSteps.OP_STARTSWITH, GuiSteps.OP_NOTSTARTSWITH, GuiSteps.OP_ENDSWITH, GuiSteps.OP_NOTENDSWITH ] ) # check what ? self.checkOutTextLine = QLineEdit(self) self.checkOutTextLine.setMinimumWidth(300) self.checkOutTextCombo = QComboBox(self) self.checkOutTextCombo.addItems( LIST_TYPES ) # final layout mainChecklayout = QGridLayout() mainChecklayout.addWidget( QLabel( self.tr("Checking from:") ), 0, 0 ) mainChecklayout.addWidget( self.checkInTextCombo, 0, 1 ) mainChecklayout.addWidget( self.checkInTextLine, 0, 2 ) mainChecklayout.addWidget( QLabel( self.tr("If:") ), 1, 0 ) mainChecklayout.addWidget( self.checkComboBox, 1, 1 ) mainChecklayout.addWidget( QLabel( self.tr("The Value:") ), 2, 0 ) mainChecklayout.addWidget( self.checkOutTextCombo, 2, 1 ) mainChecklayout.addWidget( self.checkOutTextLine, 2, 2 ) self.getCheckGroup.setLayout(mainChecklayout) self.getCheckGroup.hide() def createWidgetGetText(self): """ Create text widget """ self.getTextGroup = QGroupBox(self.tr("")) self.basicTextLine = QLineEdit(self) self.basicTextLine.setMinimumWidth(300) self.basicTextCombo = QComboBox(self) self.basicTextCombo.addItems( LIST_TYPES ) mainTextlayout = QGridLayout() mainTextlayout.addWidget( QLabel( self.tr("Value:") ), 0, 0 ) mainTextlayout.addWidget( self.basicTextCombo, 0, 1 ) mainTextlayout.addWidget( self.basicTextLine, 0, 2 ) self.getTextGroup.setLayout(mainTextlayout) def createWidgetGetAsk(self): """ Create ask widget """ # ask self.getAskGroup = QGroupBox(self.tr("")) self.askTextLine = QLineEdit(self) self.askTextLine.setMinimumWidth(300) self.askTextCombo = QComboBox(self) self.askTextCombo.addItems( LIST_TYPES ) self.askTextCacheLine = QLineEdit(self) self.askTextCacheLine.setMinimumWidth(300) self.askTextCacheCombo = QComboBox(self) self.askTextCacheCombo.addItems( [ "CACHE" ] ) mainAsklayout = QGridLayout() mainAsklayout.addWidget( QLabel( self.tr("User input prompt:") ), 0, 0 ) mainAsklayout.addWidget( self.askTextCombo, 0, 1 ) mainAsklayout.addWidget( self.askTextLine, 0, 2 ) mainAsklayout.addWidget( QLabel( self.tr("And save response in:") ), 1, 0 ) mainAsklayout.addWidget( self.askTextCacheCombo, 1, 1 ) mainAsklayout.addWidget( self.askTextCacheLine, 1, 2 ) self.getAskGroup.setLayout(mainAsklayout) self.getAskGroup.hide() def createWidgetGetWait(self): """ Create wait text widget """ self.getWaitGroup = QGroupBox(self.tr("")) self.valueWaitLine = QLineEdit(self) self.valueWaitLine.setMinimumWidth(300) self.valueWaitLine.setValidator(self.validatorInt) self.valueWaitCombo = QComboBox(self) self.valueWaitCombo.addItems( LIST_TYPES ) mainTextlayout = QGridLayout() mainTextlayout.addWidget( QLabel( self.tr("Value (in seconds):") ), 0, 0 ) mainTextlayout.addWidget( self.valueWaitCombo, 0, 1 ) mainTextlayout.addWidget( self.valueWaitLine, 0, 2 ) self.getWaitGroup.setLayout(mainTextlayout) self.getWaitGroup.hide() def createWidgetCacheSet(self): """ Create cache widget """ self.setCacheGroup = QGroupBox(self.tr("")) setCacheLayout = QGridLayout() self.cacheKeyName = QLineEdit(self) self.cacheKeyName.setMinimumWidth(300) setCacheLayout.addWidget( QLabel( self.tr("Key name:") ) , 0, 1) setCacheLayout.addWidget( self.cacheKeyName , 0, 2) self.setCacheGroup.setLayout(setCacheLayout) self.setCacheGroup.hide() def createConnections(self): """ Createa qt connections """ self.actionsComboBox.currentIndexChanged.connect(self.onActionChanged) self.addAction.clicked.connect(self.addStep) self.basicTextCombo.currentIndexChanged.connect(self.onBasicTextTypeChanged) self.valueWaitCombo.currentIndexChanged.connect(self.onValueWaitTypeChanged) self.checkOutTextCombo.currentIndexChanged.connect(self.onCheckOutTextTypeChanged) self.askTextCombo.currentIndexChanged.connect(self.onAskTextTypeChanged) def onAskTextTypeChanged(self): """ On ask type changed """ if self.askTextCombo.currentText() in [ "TEXT", "CACHE" ]: self.askTextLine.setValidator(self.validatorAll) if self.askTextCombo.currentText() == "ALIAS": self.askTextLine.setText( self.askTextLine.text().upper() ) self.askTextLine.setValidator(self.validatorUpper) def onCheckOutTextTypeChanged(self): """ On check out type changed """ if self.checkOutTextCombo.currentText() in [ "TEXT", "CACHE" ]: self.checkOutTextLine.setValidator(self.validatorAll) if self.checkOutTextCombo.currentText() == "ALIAS": self.checkOutTextLine.setText( self.checkOutTextLine.text().upper() ) self.checkOutTextLine.setValidator(self.validatorUpper) def onValueWaitTypeChanged(self): """ On value wait changed """ if self.valueWaitCombo.currentText() in [ "TEXT" ]: self.valueWaitLine.setText( "0" ) self.valueWaitLine.setValidator(self.validatorInt) if self.valueWaitCombo.currentText() in [ "CACHE" ]: self.valueWaitLine.setValidator(self.validatorAll) if self.valueWaitCombo.currentText() == "ALIAS": self.valueWaitLine.setText( self.valueWaitLine.text().upper() ) self.valueWaitLine.setValidator(self.validatorUpper) def onBasicTextTypeChanged(self): """ On basic text changed """ if self.basicTextCombo.currentText() in [ "TEXT", "CACHE" ]: self.basicTextLine.setValidator(self.validatorAll) if self.basicTextCombo.currentText() == "ALIAS": self.basicTextLine.setText( self.basicTextLine.text().upper() ) self.basicTextLine.setValidator(self.validatorUpper) def pluginDataAccessor(self): """ Return data for plugins """ return { "data": "" } def onPluginImport(self, dataJson): """ On call from plugin """ pass def onRadioAskChanged(self, button): """ On radio ask changed """ if button.text() == 'From alias parameter': self.askTextLine.setText( self.askTextLine.text().upper() ) self.askTextLine.setValidator(self.validAskUpper) else: self.askTextLine.setValidator(self.validAskAll) def onActionChanged(self): """ On action changed """ descr = 'No description available!' i = 0 for el in GuiSteps.ACTION_FRAMEWORK_DESCR: if isinstance(el, dict): if self.actionsComboBox.currentText() in el: descr = GuiSteps.ACTION_FRAMEWORK_DESCR[i][self.actionsComboBox.currentText()] break i += 1 self.labelActionDescr.setText( "%s\n" % descr ) if self.actionsComboBox.currentText() in [ GuiSteps.FRAMEWORK_INFO, GuiSteps.FRAMEWORK_WARNING ]: self.getTextGroup.show() self.getWaitGroup.hide() self.setCacheGroup.hide() self.getCheckGroup.hide() self.getAskGroup.hide() self.arrowLabel.show() self.arrowLabel2.show() elif self.actionsComboBox.currentText() in [ GuiSteps.FRAMEWORK_WAIT ]: self.getWaitGroup.show() self.getTextGroup.hide() self.setCacheGroup.hide() self.getCheckGroup.hide() self.getAskGroup.hide() self.arrowLabel.show() self.arrowLabel2.show() elif self.actionsComboBox.currentText() in [ GuiSteps.FRAMEWORK_CACHE_SET ]: self.getTextGroup.show() self.getWaitGroup.hide() self.setCacheGroup.show() self.getCheckGroup.hide() self.getAskGroup.hide() self.arrowLabel.show() self.arrowLabel2.show() elif self.actionsComboBox.currentText() in [ GuiSteps.FRAMEWORK_CHECK_STRING ]: self.getCheckGroup.show() self.getTextGroup.hide() self.getWaitGroup.hide() self.setCacheGroup.hide() self.getAskGroup.hide() self.arrowLabel.show() self.arrowLabel2.show() elif self.actionsComboBox.currentText() in [ GuiSteps.FRAMEWORK_INTERACT ]: self.getCheckGroup.hide() self.getTextGroup.hide() self.getWaitGroup.hide() self.setCacheGroup.hide() self.getAskGroup.show() self.arrowLabel.show() self.arrowLabel2.show() elif self.actionsComboBox.currentText() in [ GuiSteps.FRAMEWORK_USERCODE, GuiSteps.FRAMEWORK_CACHE_RESET ]: self.getCheckGroup.hide() self.getTextGroup.hide() self.getWaitGroup.hide() self.setCacheGroup.hide() self.getAskGroup.hide() self.arrowLabel.hide() self.arrowLabel2.show() else: self.getTextGroup.hide() self.getWaitGroup.hide() self.setCacheGroup.hide() self.getCheckGroup.hide() self.getAskGroup.hide() self.arrowLabel.hide() self.arrowLabel2.hide() def addStep(self): """ Add step """ action = self.actionsComboBox.currentText() descr = self.descriptionLine.text() descr = unicode(descr).replace('"', '') signal = self.AddStep if self.cancelAction.isEnabled(): signal = self.UpdateStep if action in [ GuiSteps.FRAMEWORK_INFO, GuiSteps.FRAMEWORK_WARNING ]: fromCache = False if self.basicTextCombo.currentText() == "CACHE": fromCache = True fromAlias = False if self.basicTextCombo.currentText() == "ALIAS": fromAlias = True newText = self.basicTextLine.text() if not len(newText): QMessageBox.warning(self, "Assistant" , "Please to set a value!") else: parameters = { 'text': newText, 'from-cache': fromCache, 'from-alias': fromAlias } signal.emit( str(action), unicode(descr), EMPTY_VALUE, parameters ) elif action in [ GuiSteps.FRAMEWORK_INTERACT ]: # read text from cache, alias or not ? fromCache = False if self.askTextCombo.currentText() == "CACHE": fromCache = True fromAlias = False if self.askTextCombo.currentText() == "ALIAS": fromAlias = True askText = self.askTextLine.text() if not len(askText): QMessageBox.warning(self, "Assistant" , "Please to set question to ask!") else: saveAskText = self.askTextCacheLine.text() if not len(saveAskText): QMessageBox.warning(self, "Assistant" , "Please to set key destination cache!") else: parameters = { 'key': saveAskText, 'value': askText, 'from-cache': fromCache, 'from-alias': fromAlias } signal.emit( str(action), unicode(descr), EMPTY_VALUE, parameters ) elif action in [ GuiSteps.FRAMEWORK_CHECK_STRING ]: fromCache = False if self.checkOutTextCombo.currentText() == "CACHE": fromCache = True fromAlias = False if self.checkOutTextCombo.currentText() == "ALIAS": fromAlias = True inText = self.checkInTextLine.text() if not len(inText): QMessageBox.warning(self, "Assistant" , "Please to set a cache key value!") else: outText = self.checkOutTextLine.text() if not len(outText): QMessageBox.warning(self, "Assistant" , "Please to set a value!") else: op = self.checkComboBox.currentText() parameters = { 'key': inText, 'value': outText, 'from-cache': fromCache, 'from-alias': fromAlias, "operator": op } signal.emit( str(action), unicode(descr), EMPTY_VALUE, parameters ) elif action in [ GuiSteps.FRAMEWORK_WAIT ]: fromCache = False if self.valueWaitCombo.currentText() == "CACHE": fromCache = True fromAlias = False if self.valueWaitCombo.currentText() == "ALIAS": fromAlias = True miscStr = self.valueWaitLine.text() if not len(miscStr): QMessageBox.warning(self, "Assistant" , "Please to set a value!") else: parameters = {'from-cache': fromCache, 'from-alias': fromAlias} signal.emit( str(action), unicode(descr), miscStr, parameters ) elif action in [ GuiSteps.FRAMEWORK_CACHE_SET ]: fromCache = False if self.basicTextCombo.currentText() == "CACHE": fromCache = True fromAlias = False if self.basicTextCombo.currentText() == "ALIAS": fromAlias = True newText = self.basicTextLine.text() if not len(newText): QMessageBox.warning(self, "Assistant" , "Please to set a text value!") else: miscStr = self.cacheKeyName.text() if not len(miscStr): QMessageBox.warning(self, "Assistant" , "Please to set a key name!") else: parameters = { 'key': miscStr, 'value': newText, 'from-cache': fromCache, 'from-alias': fromAlias } signal.emit( str(action), unicode(descr), EMPTY_VALUE, parameters ) else: signal.emit( str(action), unicode(descr), EMPTY_VALUE, {} ) def cancelStep(self): """ Cancel step """ self.addAction.setText( "&Add" ) buttonFont = QFont() buttonFont.setBold(False) self.addAction.setFont(buttonFont) self.cancelAction.setEnabled(False) self.CancelEdit.emit() def finalizeUpdate(self): """ Finalize update """ self.addAction.setText( "&Add Action" ) buttonFont = QFont() buttonFont.setBold(False) self.addAction.setFont(buttonFont) self.cancelAction.setEnabled(False) def editStep(self, stepData): """ Edit step """ self.addAction.setText( "&Update" ) buttonFont = QFont() buttonFont.setBold(True) self.addAction.setFont(buttonFont) self.cancelAction.setEnabled(True) # set the current value for actions combo for i in xrange(self.actionsComboBox.count()): item_text = self.actionsComboBox.itemText(i) if unicode(stepData["action"]) == unicode(item_text): self.actionsComboBox.setCurrentIndex(i) break # and then refresh options self.onActionChanged() # finally fill all fields self.descriptionLine.setText( stepData["description"] ) if self.actionsComboBox.currentText() in [ GuiSteps.FRAMEWORK_INFO, GuiSteps.FRAMEWORK_WARNING ] : self.basicTextLine.setText ( stepData["parameters"]["text"] ) if stepData["parameters"]["from-cache"]: self.basicTextLine.setValidator(self.validatorAll) self.basicTextCombo.setCurrentIndex(INDEX_CACHE) elif stepData["parameters"]["from-alias"]: self.basicTextLine.setValidator(self.validatorUpper) self.basicTextCombo.setCurrentIndex(INDEX_ALIAS) else: self.basicTextLine.setValidator(self.validatorAll) self.basicTextCombo.setCurrentIndex(INDEX_TEXT) if self.actionsComboBox.currentText() in [ GuiSteps.FRAMEWORK_WAIT ]: self.valueWaitLine.setText ( stepData["misc"] ) if stepData["parameters"]["from-cache"]: self.valueWaitLine.setValidator(self.validatorAll) self.valueWaitCombo.setCurrentIndex(INDEX_CACHE) elif stepData["parameters"]["from-alias"]: self.valueWaitLine.setValidator(self.validatorUpper) self.valueWaitCombo.setCurrentIndex(INDEX_ALIAS) else: self.valueWaitLine.setValidator(self.validatorInt) self.valueWaitCombo.setCurrentIndex(INDEX_TEXT) if self.actionsComboBox.currentText() in [ GuiSteps.FRAMEWORK_CACHE_SET ]: self.basicTextLine.setText ( stepData["parameters"]["value"] ) if stepData["parameters"]["from-cache"]: self.basicTextLine.setValidator(self.validatorAll) self.basicTextCombo.setCurrentIndex(INDEX_CACHE) elif stepData["parameters"]["from-alias"]: self.basicTextLine.setValidator(self.validatorUpper) self.basicTextCombo.setCurrentIndex(INDEX_ALIAS) else: self.basicTextLine.setValidator(self.validatorAll) self.basicTextCombo.setCurrentIndex(INDEX_TEXT) self.cacheKeyName.setText( stepData["parameters"]["key"] ) if self.actionsComboBox.currentText() in [ GuiSteps.FRAMEWORK_CHECK_STRING ]: self.checkOutTextLine.setText ( stepData["parameters"]["value"] ) if stepData["parameters"]["from-cache"]: self.checkOutTextLine.setValidator(self.validatorAll) self.checkOutTextCombo.setCurrentIndex(INDEX_CACHE) elif stepData["parameters"]["from-alias"]: self.checkOutTextLine.setValidator(self.validatorUpper) self.checkOutTextCombo.setCurrentIndex(INDEX_ALIAS) else: self.checkOutTextLine.setValidator(self.validatorAll) self.checkOutTextCombo.setCurrentIndex(INDEX_TEXT) self.checkInTextLine.setText ( stepData["parameters"]["key"] ) for i in xrange(self.checkComboBox.count()): item_text = self.checkComboBox.itemText(i) if unicode(stepData["parameters"]["operator"]) == unicode(item_text): self.checkComboBox.setCurrentIndex(i) break if self.actionsComboBox.currentText() in [ GuiSteps.FRAMEWORK_INTERACT ]: self.askTextLine.setText ( stepData["parameters"]["value"] ) if stepData["parameters"]["from-cache"]: self.askTextLine.setValidator(self.validatorAll) self.askTextCombo.setCurrentIndex(INDEX_CACHE) elif stepData["parameters"]["from-alias"]: self.askTextLine.setValidator(self.validatorUpper) self.askTextCombo.setCurrentIndex(INDEX_ALIAS) else: self.askTextLine.setValidator(self.validatorAll) self.askTextCombo.setCurrentIndex(INDEX_TEXT) self.askTextCacheLine.setText ( stepData["parameters"]["key"] ) def getTimeout(self): """ Return timeout """ return self.optionsDialog.timeoutLine.text() def setTimeout(self, timeout): """ Set the timeout """ return self.optionsDialog.timeoutLine.setText(timeout)
class RunDialog(QDialog): def __init__(self, run_model, parent): QDialog.__init__(self, parent) self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) self.setWindowFlags(self.windowFlags() & ~Qt.WindowCloseButtonHint) self.setModal(True) self.setWindowModality(Qt.WindowModal) self.setWindowTitle("Simulations") assert isinstance(run_model, BaseRunModel) self._run_model = run_model layout = QVBoxLayout() layout.setSizeConstraint(QLayout.SetFixedSize) self.simulations_tracker = SimulationsTracker() states = self.simulations_tracker.getStates() self.total_progress = SimpleProgress() layout.addWidget(self.total_progress) status_layout = QHBoxLayout() status_layout.addStretch() self.__status_label = QLabel() status_layout.addWidget(self.__status_label) status_layout.addStretch() layout.addLayout(status_layout) self.progress = Progress() self.progress.setIndeterminateColor(self.total_progress.color) for state in states: self.progress.addState(state.state, QColor(*state.color), 100.0 * state.count / state.total_count) layout.addWidget(self.progress) self.detailed_progress = None legend_layout = QHBoxLayout() self.legends = {} for state in states: self.legends[state] = Legend("%s (%d/%d)", QColor(*state.color)) self.legends[state].updateLegend(state.name, 0, 0) legend_layout.addWidget(self.legends[state]) layout.addLayout(legend_layout) self.running_time = QLabel("") ert = None if isinstance(run_model, BaseRunModel): ert = run_model.ert() self.plot_tool = PlotTool() self.plot_tool.setParent(None) self.plot_button = QPushButton(self.plot_tool.getName()) self.plot_button.clicked.connect(self.plot_tool.trigger) self.plot_button.setEnabled(ert is not None) self.kill_button = QPushButton("Kill simulations") self.done_button = QPushButton("Done") self.done_button.setHidden(True) self.restart_button = QPushButton("Restart") self.restart_button.setHidden(True) self.show_details_button = QPushButton("Details") self.realizations_view = QListView() self.realizations_view.setModel( QStandardItemModel(self.realizations_view)) self.realizations_view.setVisible(False) button_layout = QHBoxLayout() size = 20 spin_movie = resourceMovie("ide/loading.gif") spin_movie.setSpeed(60) spin_movie.setScaledSize(QSize(size, size)) spin_movie.start() self.processing_animation = QLabel() self.processing_animation.setMaximumSize(QSize(size, size)) self.processing_animation.setMinimumSize(QSize(size, size)) self.processing_animation.setMovie(spin_movie) button_layout.addWidget(self.processing_animation) button_layout.addWidget(self.running_time) button_layout.addStretch() button_layout.addWidget(self.show_details_button) button_layout.addWidget(self.plot_button) button_layout.addWidget(self.kill_button) button_layout.addWidget(self.done_button) button_layout.addWidget(self.restart_button) layout.addStretch() layout.addLayout(button_layout) layout.addWidget(self.realizations_view) self.setLayout(layout) self.kill_button.clicked.connect(self.killJobs) self.done_button.clicked.connect(self.accept) self.restart_button.clicked.connect(self.restart_failed_realizations) self.show_details_button.clicked.connect(self.show_detailed_progress) self.__updating = False self.__update_queued = False self.__simulation_started = False self.__update_timer = QTimer(self) self.__update_timer.setInterval(500) self.__update_timer.timeout.connect(self.updateRunStatus) self._simulations_argments = {} def startSimulation(self, arguments): self._simulations_argments = arguments if not 'prev_successful_realizations' in self._simulations_argments: self._simulations_argments['prev_successful_realizations'] = 0 self._run_model.reset() def run(): self._run_model.startSimulations(self._simulations_argments) simulation_thread = Thread(name="ert_gui_simulation_thread") simulation_thread.setDaemon(True) simulation_thread.run = run simulation_thread.start() self.__update_timer.start() def checkIfRunFinished(self): if self._run_model.isFinished(): self.update_realizations_view() self.hideKillAndShowDone() if self._run_model.hasRunFailed(): error = self._run_model.getFailMessage() QMessageBox.critical( self, "Simulations failed!", "The simulation failed with the following error:\n\n%s" % error) self.reject() def updateRunStatus(self): self.checkIfRunFinished() self.total_progress.setProgress(self._run_model.getProgress()) self.__status_label.setText(self._run_model.getPhaseName()) states = self.simulations_tracker.getStates() if self._run_model.isIndeterminate(): self.progress.setIndeterminate(True) for state in states: self.legends[state].updateLegend(state.name, 0, 0) else: if self.detailed_progress: self.detailed_progress.set_progress( *self._run_model.getDetailedProgress()) self.progress.setIndeterminate(False) total_count = self._run_model.getQueueSize() queue_status = self._run_model.getQueueStatus() for state in states: state.count = 0 state.total_count = total_count for state in states: for queue_state in queue_status: if queue_state in state.state: state.count += queue_status[queue_state] self.progress.updateState( state.state, 100.0 * state.count / state.total_count) self.legends[state].updateLegend(state.name, state.count, state.total_count) self.setRunningTime() def setRunningTime(self): days = 0 hours = 0 minutes = 0 seconds = self._run_model.getRunningTime() if seconds >= 60: minutes, seconds = divmod(seconds, 60) if minutes >= 60: hours, minutes = divmod(minutes, 60) if hours >= 24: days, hours = divmod(hours, 24) if days > 0: self.running_time.setText( "Running time: %d days %d hours %d minutes %d seconds" % (days, hours, minutes, seconds)) elif hours > 0: self.running_time.setText( "Running time: %d hours %d minutes %d seconds" % (hours, minutes, seconds)) elif minutes > 0: self.running_time.setText("Running time: %d minutes %d seconds" % (minutes, seconds)) else: self.running_time.setText("Running time: %d seconds" % seconds) def killJobs(self): kill_job = QMessageBox.question( self, "Kill simulations?", "Are you sure you want to kill the currently running simulations?", QMessageBox.Yes | QMessageBox.No) if kill_job == QMessageBox.Yes: if self._run_model.killAllSimulations(): self.reject() def hideKillAndShowDone(self): self.__update_timer.stop() self.processing_animation.hide() self.kill_button.setHidden(True) self.done_button.setHidden(False) self.realizations_view.setVisible(True) self.restart_button.setVisible(self.has_failed_realizations()) self.restart_button.setEnabled(self._run_model.support_restart) def has_failed_realizations(self): completed = self._run_model.completed_realizations_mask initial = self._run_model.initial_realizations_mask for (index, successful) in enumerate(completed): if initial[index] and not successful: return True return False def count_successful_realizations(self): """ Counts the realizations completed in the prevoius ensemble run :return: """ completed = self._run_model.completed_realizations_mask return completed.count(True) def create_mask_from_failed_realizations(self): """ Creates a BoolVector mask representing the failed realizations :return: Type BoolVector """ completed = self._run_model.completed_realizations_mask initial = self._run_model.initial_realizations_mask inverted_mask = BoolVector(default_value=False) for (index, successful) in enumerate(completed): inverted_mask[index] = initial[index] and not successful return inverted_mask def restart_failed_realizations(self): msg = QMessageBox(self) msg.setIcon(QMessageBox.Information) msg.setText( "Note that workflows will only be executed on the restarted realizations and that this might have unexpected consequences." ) msg.setWindowTitle("Restart Failed Realizations") msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel) result = msg.exec_() if result == QMessageBox.Ok: active_realizations = self.create_mask_from_failed_realizations() self._simulations_argments[ 'active_realizations'] = active_realizations self._simulations_argments[ 'prev_successful_realizations'] += self.count_successful_realizations( ) self.startSimulation(self._simulations_argments) def update_realizations_view(self): completed = self._run_model.completed_realizations_mask for (index, successful) in enumerate(completed): items = self.realizations_view.model().findItems(str(index)) if not items: item = QStandardItem(str(index)) self.realizations_view.model().appendRow(item) else: item = items[0] item.setCheckState(successful or item.checkState()) def show_detailed_progress(self): if not self.detailed_progress: self.detailed_progress = DetailedProgressDialog( self, self.simulations_tracker.getStates()) self.detailed_progress.set_progress( *self._run_model.getDetailedProgress()) self.detailed_progress.show()
class WDocumentProperties(QWidget, Logger.ClassLogger): """ Document properties widget """ RefreshLocalRepository = pyqtSignal() def __init__(self, parent=None, iRepo=None, lRepo=None, rRepo=None): """ Widget document properties @param parent: @type parent: / Description \_/ Parameters \_ / Probes \___ | | | | | ____________________________________________| """ QWidget.__init__(self, parent) self.descrs = None self.parameters = None self.probes = None self.agents = None self.steps = None self.adapters = None self.libraries = None self.parametersTab = None self.currentDoc = None self.currentTab = None self.iRepo = iRepo self.lRepo = lRepo # local repo dialog self.rRepo = rRepo # remote repo dialog self.wdoc = None self.createActions() self.createWidgets() self.createConnections() self.initToolbarParameters() def createWidgets(self): """ Create qt widgets QTabWidget / QWidget \/ QWidget \_________________ | | | ______________________________________| """ self.steps = Steps.StepsQWidget(self) self.descrs = Descriptions.DescriptionsQWidget(self) self.parameters = Parameters.ParametersQWidget(self) self.parametersOutput = Parameters.ParametersQWidget(self, forParamsOutput=True) self.probes = Probes.ProbesQWidget(self) self.agents = Agents.AgentsQWidget(self) self.adapters = Adapters.AdaptersQWidget(self, testParams=self, testDescrs=self.descrs) self.libraries = Libraries.LibrariesQWidget(self, testParams=self, testDescrs=self.descrs) self.parametersTab = QTabWidget() self.parametersTab.setTabPosition(QTabWidget.North) self.parametersTab.setStyleSheet("QTabWidget { border: 0px; }") # remove 3D border self.parametersTab.addTab(self.descrs, QIcon(":/test-config.png"), "Description") self.parametersTab.addTab(self.steps, QIcon(":/run-state.png"), "Steps") self.paramsTab = QTabWidget() self.paramsTab.setStyleSheet("QTabWidget { border: 0px; }") # remove 3D border self.paramsTab.setTabPosition(QTabWidget.North) self.paramsTab.addTab(self.parameters, QIcon(":/test-input.png"), "Inputs") self.paramsTab.addTab(self.parametersOutput, QIcon(":/test-output.png"), "Outputs") self.paramsTab.addTab(self.adapters, QIcon(":/adapters.png"), "Adapters") self.paramsTab.addTab(self.libraries, QIcon(":/libraries.png"), "Libraries") self.miscsTab = QTabWidget() self.miscsTab.setStyleSheet("QTabWidget { border: 0px; }") # remove 3D border self.miscsTab.setTabPosition(QTabWidget.North) self.miscsTab.addTab(self.agents, QIcon(":/agent.png"), "Agents") self.miscsTab.addTab(self.probes, QIcon(":/probe.png"), "Probes") self.title = QLabel("Test Properties") font = QFont() font.setBold(True) self.title.setFont(font) self.labelHelp = QLabel("Prepare the test.") font = QFont() font.setItalic(True) self.labelHelp.setFont(font) self.mainTab = QTabWidget() self.mainTab.setTabPosition(QTabWidget.North) self.mainTab.addTab(self.parametersTab, QIcon(":/test-description.png"), "Test Design") self.mainTab.addTab(self.paramsTab, QIcon(":/repository.png"), "Test Data") self.mainTab.addTab(self.miscsTab, QIcon(":/server-config.png"), "Miscellaneous") if Settings.instance().readValue( key = 'TestProperties/inputs-default-tab' ) == "True": self.mainTab.setCurrentIndex(1) self.paramsTab.setCurrentIndex(TAB_INPUTS) layout = QVBoxLayout() layout.addWidget( self.title ) layout.addWidget( self.labelHelp ) layout.addWidget(self.mainTab) layout.setContentsMargins(0,0,0,0) self.setLayout(layout) def hideWidgetsHeader(self): """ Hide the title of the widget """ self.title.hide() self.labelHelp.hide() def showWidgetsHeader(self): """ Show widget header """ self.title.show() self.labelHelp.show() def createConnections(self): """ Create qt connections * DescriptionTableView <=> dataChanged * ParametersTableView <=> dataChanged * ProbesTableView <=> dataChanged """ self.descrs.table().DataChanged.connect(self.dataChanged) self.parameters.table().DataChanged.connect(self.dataChanged) if Settings.instance().readValue( key = 'TestProperties/parameters-rename-auto' ) == "True": self.parameters.table().NameParameterUpdated.connect(self.inputNameChanged) self.parameters.table().NbParameters.connect(self.onUpdateInputsNumber) self.parametersOutput.table().DataChanged.connect(self.dataChanged) if Settings.instance().readValue( key = 'TestProperties/parameters-rename-auto' ) == "True": self.parametersOutput.table().NameParameterUpdated.connect(self.outputNameChanged) self.parametersOutput.table().NbParameters.connect(self.onUpdateOutputsNumber) self.probes.table().DataChanged.connect(self.dataChanged) self.agents.table().DataChanged.connect(self.dataChanged) # to support test abstract self.steps.table().DataChanged.connect(self.dataChanged) self.adapters.table().DataChanged.connect(self.dataChanged) self.libraries.table().DataChanged.connect(self.dataChanged) def createActions (self): """ Actions defined: * import * export """ self.importAction = QtHelper.createAction(self, "&Import inputs", self.importInputs, icon = QIcon(":/tc-import.png"), tip = 'Import inputs from Test Config' ) self.exportAction = QtHelper.createAction(self, "&Export inputs", self.exportInputs, icon = QIcon(":/tc-export.png"), tip = 'Export inputs as Test Config' ) self.importOutputsAction = QtHelper.createAction(self, "&Import outputs", self.importOutputs, icon = QIcon(":/tc-import.png"), tip = 'Import outputs from Test Config' ) self.exportOutputsAction = QtHelper.createAction(self, "&Export outputs", self.exportOutputs, icon = QIcon(":/tc-export.png"), tip = 'Export outputs as Test Config' ) self.markUnusedAction = QtHelper.createAction(self, "&Mark unused inputs", self.markUnusedInputs, icon = QIcon(":/input-unused.png"), tip = 'Marks all unused inputs' ) self.markUnusedOutputsAction = QtHelper.createAction(self, "&Mark unused ouputs", self.markUnusedOutputs, icon = QIcon(":/input-unused.png"), tip = 'Marks all unused outputs' ) def onUpdateInputsNumber(self, nbParams): """ On update the number of inputs in the tabulation name """ self.paramsTab.setTabText(0, "Inputs (%s)" % nbParams ) def onUpdateOutputsNumber(self, nbParams): """ On update the number of outputs in the tabulation name """ self.paramsTab.setTabText(1, "Outputs (%s)" % nbParams ) def initToolbarParameters(self): """ Init toolbar parameters """ self.parameters.toolbar().addSeparator() self.parameters.toolbar().addAction(self.markUnusedAction) self.parameters.toolbar().addSeparator() self.parameters.toolbar().addAction(self.importAction) self.parameters.toolbar().addAction(self.exportAction) self.parametersOutput.toolbar().addSeparator() self.parametersOutput.toolbar().addAction(self.markUnusedOutputsAction) self.parametersOutput.toolbar().addSeparator() self.parametersOutput.toolbar().addAction(self.importOutputsAction) self.parametersOutput.toolbar().addAction(self.exportOutputsAction) def setDocument(self, wdoc): """ Save the address to the document """ self.wdoc = wdoc def enableMarkUnused(self): """ Active the button mark inputs as unused """ self.markUnusedAction.setEnabled(True) self.markUnusedOutputsAction.setEnabled(True) def disableMarkUnused(self): """ Disable the mark button """ self.markUnusedAction.setEnabled(False) self.markUnusedOutputsAction.setEnabled(False) def markUnusedInputs(self): """ Mark all inputs unused """ if self.wdoc is None: return editorExec = None editorSrc = None if isinstance(self.wdoc, TestUnit.WTestUnit): editorSrc = self.wdoc.srcEditor if isinstance(self.wdoc, TestSuite.WTestSuite): editorSrc = self.wdoc.srcEditor editorExec = self.wdoc.execEditor self.parameters.markUnusedInputs(editorSrc=editorSrc, editorExec=editorExec) def markUnusedOutputs(self): """ Mark all outputs unused """ if self.wdoc is None: return editorExec = None editorSrc = None if isinstance(self.wdoc, TestUnit.WTestUnit): editorSrc = self.wdoc.srcEditor if isinstance(self.wdoc, TestSuite.WTestSuite): editorSrc = self.wdoc.srcEditor editorExec = self.wdoc.execEditor self.parameters.markUnusedOutputs(editorSrc=editorSrc, editorExec=editorExec) def addNew(self): """ Add item on parameters or probes """ self.currentTab.insertItem() def delSelection(self): """ Delete selected item on parameters or probes """ self.currentTab.removeItem() def exportOutputs (self): """ Export all outputs """ return self.export(inputs=False) def exportInputs (self): """ Export all inputs """ return self.export(inputs=True) def export (self, inputs): """ Export test config, dispatch to local, remote or other """ ret = False self.localConfigured = Settings.instance().readValue( key = 'Repositories/local-repo' ) # first in local repo if configured if self.localConfigured != "Undefined": buttons = QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel answer = QMessageBox.question(self, Settings.instance().readValue( key = 'Common/name' ), self.tr("Export to local repository") , buttons) if answer == QMessageBox.Yes: ret = self.saveToLocal(inputs=inputs) elif answer == QMessageBox.No: if RCI.instance().isAuthenticated: # no then perhaps in remo repo if connected? ret = self.saveToRemote(inputs=inputs) else: QMessageBox.warning(self, "Save" , "Connect to the test center first!") # not configured then in remo repo if connected ? elif RCI.instance().isAuthenticated: ret = self.saveToRemote(inputs=inputs) else: QMessageBox.warning(self, "Save" , "Connect to the test center first!") return ret def splitFileName(self, fileName): """ Split the filename """ tmp = str(fileName).rsplit("/", 1) path = tmp[0] filename = tmp[1] return (path, filename) def saveToLocal(self, inputs=True): """ Export test config to local repository """ ret = False dialog = self.lRepo.SaveOpenToRepoDialog( parent=self, filename=DEFAULT_NAME ) # if dialog.exec_() == QDialog.Accepted: fileName = dialog.getSelection() path, filename = self.splitFileName(fileName=fileName) doc = TestConfig.WTestConfig(self, path = path, filename=filename, extension=self.rRepo.EXTENSION_TCX) if inputs: doc.dataModel.properties['properties']['parameters']['parameter'] = self.parameters.table().model.getData() else: doc.dataModel.properties['properties']['parameters']['parameter'] = self.parametersOutput.table().model.getData() ret = doc.write(force = True, fromExport=True) if ret: self.RefreshLocalRepository.emit() return ret def saveToRemote(self, inputs=True): """ Export test config to remote repository """ ret = False project = self.iRepo.remote().getCurrentProject() prjId = self.iRepo.remote().getProjectId(project=str(project)) self.iRepo.remote().saveAs.setFilename(filename=DEFAULT_NAME, project=project) dialog = self.iRepo.remote().saveAs if dialog.exec_() == QDialog.Accepted: fileName = dialog.getSelection() path, filename = self.splitFileName(fileName=fileName) doc = TestConfig.WTestConfig(self,path = path, filename=filename, extension=self.rRepo.EXTENSION_TCX, remoteFile=True) if inputs: doc.dataModel.properties['properties']['parameters']['parameter'] = self.parameters.table().model.getData() else: doc.dataModel.properties['properties']['parameters']['parameter'] = self.parametersOutput.table().model.getData() # rest call RCI.instance().uploadTestFile(filePath=doc.path, fileName=doc.filename, fileExtension=doc.extension, fileContent=doc.getraw_encoded(), projectId=int(prjId), updateMode=False, closeTabAfter=False) ret = True return ret def saveToAnywhere (self, inputs=True): """ Save test config to anywhere Deprecated function """ fileName = QFileDialog.getSaveFileName(self, "Export Test Config", "", "*.%s" % self.rRepo.EXTENSION_TCX ) if fileName.isEmpty(): return config = FileModelTestConfig.DataModel() if inputs: config.properties['properties']['parameters']['parameter'] = self.parameters.table().model.getData() else: config.properties['properties']['parameters']['parameter'] = self.parametersOutput.table().model.getData() config.write( absPath=fileName ) del config def importOutputs(self): """ Import all outputs """ self.import__(inputs=False) def importInputs(self): """ Import all inputs """ self.import__(inputs=True) def import__(self, inputs): """ Import test config, dispatch to local, remote or other """ # import from local repo self.localConfigured = Settings.instance().readValue( key = 'Repositories/local-repo' ) if self.localConfigured != "Undefined": buttons = QMessageBox.Yes | QMessageBox.No answer = QMessageBox.question(self, Settings.instance().readValue( key = 'Common/name' ), self.tr("Import Test Config from local repository") , buttons) if answer == QMessageBox.Yes: self.loadFromLocal(inputs=inputs) # load local test config file else: if RCI.instance().isAuthenticated: # no then perhaps in remo repo if connected? self.loadFromRemote(inputs=inputs) # load remote test config file else: QMessageBox.warning(self, "Save" , "Connect to the test center first!") # import from remote repo elif RCI.instance().isAuthenticated: # no then perhaps in remo repo if connected? self.loadFromRemote(inputs=inputs) # load remote test config file else: QMessageBox.warning(self, "Save" , "Connect to the test center first!") def loadFromRemote(self, inputs=True): """ Load test config from remote repository """ project = self.iRepo.remote().getCurrentProject() prjId = self.iRepo.remote().getProjectId(project=str(project)) self.iRepo.remote().saveAs.getFilename(type=self.rRepo.EXTENSION_TCX, project=project) dialog = self.iRepo.remote().saveAs if dialog.exec_() == QDialog.Accepted: if inputs: RCI.instance().openFileTests(projectId=int(prjId), filePath=dialog.getSelection(), ignoreLock=False, readOnly=False, customParam=None, actionId=UCI.ACTION_IMPORT_INPUTS, destinationId=UCI.FOR_DEST_ALL) else: RCI.instance().openFileTests(projectId=int(prjId), filePath=dialog.getSelection(), ignoreLock=False, readOnly=False, customParam=None, actionId=UCI.ACTION_IMPORT_OUTPUTS, destinationId=UCI.FOR_DEST_ALL) def loadFromLocal(self, inputs=True): """ Load test config from local repository """ dialog = self.lRepo.SaveOpenToRepoDialog( self , "", type = self.lRepo.MODE_OPEN, typeFile=self.lRepo.EXTENSION_TCX ) dialog.hideFiles(hideTsx=True, hideTpx=True, hideTcx=False, hideTdx=True) if dialog.exec_() == QDialog.Accepted: self.loadFromAnywhere(pathFilename=dialog.getSelection(), inputs=inputs) def loadFromAnywhere (self, pathFilename=None, inputs=True): """ Load test config from anywhere Deprecated function @param pathFilename: @type pathFilename: """ if pathFilename is None: fileName = QFileDialog.getOpenFileName(self, self.tr("Import File"), "", "Tcx Config Files (*.%s)" % self.rRepo.EXTENSION_TCX ) # new in v18 to support qt5 if QtHelper.IS_QT5: _fileName, _type = fileName else: _fileName = fileName # end of new if _fileName.isEmpty(): return if not ( str(_fileName).endswith( self.rRepo.EXTENSION_TCX ) ): QMessageBox.critical(self, "Open Failed" , "File not supported") return else: _fileName=pathFilename config = FileModelTestConfig.DataModel() res = config.load( absPath = _fileName ) if not res: QMessageBox.critical(self, "Open Failed" , "Corrupted file") return if inputs: self.parameters.table().loadData( data = config.properties['properties']['parameters'] ) self.currentDoc.dataModel.properties['properties']['inputs-parameters'] = config.properties['properties']['parameters'] else: self.parametersOutput.table().loadData( data = config.properties['properties']['parameters'] ) self.currentDoc.dataModel.properties['properties']['outputs-parameters'] = config.properties['properties']['parameters'] self.currentDoc.setModify() del config def addRemoteTestConfigToTestsuite(self, data, inputs=True): """ Add remote test config to a test @param data: @type data: """ path_file, name_file, ext_file, encoded_data, project = data content = base64.b64decode(encoded_data) config = FileModelTestConfig.DataModel() res = config.load( rawData=content ) if not res: QMessageBox.critical(self, "Open Failed" , "Corrupted file") return if inputs: self.parameters.table().loadData( data = config.properties['properties']['parameters'] ) self.currentDoc.dataModel.properties['properties']['inputs-parameters'] = config.properties['properties']['parameters'] else: self.parametersOutput.table().loadData( data = config.properties['properties']['parameters'] ) self.currentDoc.dataModel.properties['properties']['outputs-parameters'] = config.properties['properties']['parameters'] self.currentDoc.setModify() del config def dataChanged (self): """ Called when data on all table view changed On description """ if self.currentDoc is not None: if isinstance(self.currentDoc, self.lRepo.TestPlan.WTestPlan): self.currentDoc.updateStatsTestPlan() self.currentDoc.setModify() def clear (self): """ Clear contents """ self.descrs.clear() self.descrs.table().defaultActions() self.parameters.clear() self.parametersOutput.clear() self.probes.clear() self.agents.clear() self.steps.clear() self.adapters.clear() self.libraries.clear() def addDescriptions (self, wdoc): """ Add description @param wdoc: @type wdoc: """ if isinstance(wdoc, TestData.WTestData): self.descrs.table().setDatasetView() else: self.descrs.table().setDefaultView() if type(wdoc) == dict: if not 'descriptions' in wdoc: wdoc['descriptions'] = { 'description': [ { 'key': 'author', 'value': '' }, { 'key': 'date', 'value': '' }, { 'key': 'summary', 'value': '' } ] } self.descrs.table().loadData( data = wdoc['descriptions'] ) else: self.currentDoc = wdoc data = wdoc.dataModel.properties['properties']['descriptions'] self.descrs.table().loadData( data = data ) self.descrs.table().setWdoc( wdoc=wdoc ) def addAgents (self, wdoc): """ Add agents @param wdoc: @type wdoc: """ if type(wdoc) == dict: self.agents.table().loadData( data = wdoc['agents'] ) else: self.currentDoc = wdoc data = wdoc.dataModel.properties['properties']['agents'] self.agents.table().loadData( data = data ) def addParameters (self, wdoc): """ Add parameters @param wdoc: @type wdoc: """ if isinstance(wdoc, TestData.WTestData): self.parameters.table().setDatasetView() else: self.parameters.table().setDefaultView() if type(wdoc) == dict: self.parameters.table().loadData( data = wdoc['inputs-parameters'] ) else: self.currentDoc = wdoc data = wdoc.dataModel.properties['properties']['inputs-parameters'] self.parameters.table().loadData( data = data ) def addParametersOutput (self, wdoc): """ Add parameters @param wdoc: @type wdoc: """ if isinstance(wdoc, TestData.WTestData): self.parametersOutput.table().setDatasetView() else: self.parametersOutput.table().setDefaultView() if type(wdoc) == dict: self.parametersOutput.table().loadData( data = wdoc['outputs-parameters'] ) else: self.currentDoc = wdoc data = wdoc.dataModel.properties['properties']['outputs-parameters'] self.parametersOutput.table().loadData( data = data ) def addProbes (self, wdoc): """ Add probes @param wdoc: @type wdoc: """ if type(wdoc) == dict: self.probes.table().loadData( data = wdoc['probes'] ) else: self.currentDoc = wdoc data = wdoc.dataModel.properties['properties']['probes'] self.probes.table().loadData(data = data) def addSteps (self, wdoc): """ Add steps @param wdoc: @type wdoc: """ self.steps.table().setSteps(steps=wdoc.dataModel.steps['steps']['step'] ) def addAdapters (self, wdoc): """ Add adapters @param wdoc: @type wdoc: """ self.adapters.table().setAdapters(adapters=wdoc.dataModel.adapters['adapters']['adapter'] ) def addLibraries (self, wdoc): """ Add libraries @param wdoc: @type wdoc: """ self.libraries.table().setLibraries(libraries=wdoc.dataModel.libraries['libraries']['library'] ) def disableOutputParameters(self): """ Disable output parameters tabulation """ self.parametersOutput.clear() self.paramsTab.setTabEnabled(TAB_OUTPUTS, False) def enableOutputParameters(self): """ Enable output parameters tabulation """ self.paramsTab.setTabEnabled(TAB_OUTPUTS, True) def disableAgents(self): """ Disable agents tabulation """ self.agents.clear() self.miscsTab.setTabEnabled(TAB_AGENTS, False) def enableAgents(self): """ Enable agents tabulation """ self.miscsTab.setTabEnabled(TAB_AGENTS, True) def disableProbes(self): """ Disable probes tabulation """ self.probes.clear() self.miscsTab.setTabEnabled(TAB_PROBES, False) def enableProbes(self): """ Enable probes tabulation """ self.miscsTab.setTabEnabled(TAB_PROBES, True) def disableSteps(self): """ Disable steps tabulation """ self.steps.clear() self.parametersTab.setTabEnabled(TAB_STEPS, False) def enableSteps(self): """ Enable steps tabulation """ self.parametersTab.setTabEnabled(TAB_STEPS, True) def disableAdapters(self): """ Disable adapters tabulation """ self.adapters.clear() self.paramsTab.setTabEnabled(TAB_ADAPTERS, False) def enableAdapters(self): """ Enable adapters tabulation """ self.paramsTab.setTabEnabled(TAB_ADAPTERS, True) def disableLibraries(self): """ Disable libraries tabulation """ self.libraries.clear() self.paramsTab.setTabEnabled(TAB_LIBRARIES, False) def enableLibraries(self): """ Enable libraries tabulation """ self.paramsTab.setTabEnabled(TAB_LIBRARIES, True) def inputNameChanged(self, oldName, newName): """ On input name changed """ if self.currentDoc is not None: if isinstance(self.currentDoc, TestUnit.WTestUnit): editor = self.currentDoc.srcEditor newText = editor.text().replace("input('%s')" % oldName, "input('%s')" % newName) editor.setText(newText) elif isinstance(self.currentDoc, TestSuite.WTestSuite): editorSrc = self.currentDoc.srcEditor editorExec = self.currentDoc.execEditor editorSrc.setText( editorSrc.text().replace("input('%s')" % oldName, "input('%s')" % newName) ) editorExec.setText( editorExec.text().replace("input('%s')" % oldName, "input('%s')" % newName) ) else: self.error('unknown file type') def outputNameChanged(self, oldName, newName): """ On output name changed """ if self.currentDoc is not None: if isinstance(self.currentDoc, TestUnit.WTestUnit): editor = self.currentDoc.srcEditor newText = editor.text().replace("output('%s')" % oldName, "output('%s')" % newName) editor.setText(newText) elif isinstance(self.currentDoc, TestSuite.WTestSuite): editorSrc = self.currentDoc.srcEditor editorExec = self.currentDoc.execEditor editorSrc.setText( editorSrc.text().replace("output('%s')" % oldName, "output('%s')" % newName) ) editorExec.setText( editorExec.text().replace("output('%s')" % oldName, "output('%s')" % newName) ) else: self.error('unknown file type')
def __init__(self, parent=None): QWidget.__init__(self, parent) self.clean_up_queue = [] self.summoner = SummonerData() self.summoner.getStaticData() ### Search Bar ### ################## #label self.search_label = QLabel(self) self.search_label.move(20, 15) self.search_label.resize(220, 25) self.search_label.setText('Enter summoner name(s):') self.search_label.setStyleSheet("QLabel {font:14pt}") #text field self.search_field = QLineEdit(self) self.search_field.move(260, 15) self.search_field.resize(250, 25) self.search_field.setPlaceholderText("ex: mcnuggets, teltor, ...") self.search_field.setFocusPolicy(Qt.ClickFocus) #search button self.search_button = QPushButton(self) self.search_button.move(520, 15) self.search_button.resize(150, 25) self.search_button.setText('Search Summoner') #region combobox self.region_list = QComboBox(self) self.region_list.move(680, 15) self.region_list.resize(75, 25) regions = ['NA', 'LAN', 'BR', 'LAS', 'EUW', 'EUNE', 'TR', 'RU', 'OCE'] self.region_list.addItems(regions) #error label self.error_label = QLabel(self) self.error_label.move(775, 15) self.error_label.resize(160, 25) self.error_label.setStyleSheet("QLabel {font:14pt}") ### Summoner Information ### ############################ #summoner Icon label self.icon_label = QLabel(self) self.icon_label.setScaledContents(True) self.icon_label.move(260, 50) self.icon_label.resize(110, 110) #name label self.name_label = QLabel(self) self.name_label.move(380, 50) self.name_label.resize(620, 50) self.name_label.setText('SUMMONER NAME') self.name_label.setStyleSheet("QLabel {font:32pt}") #rank label self.rank_label = QLabel(self) self.rank_label.move(380, 100) self.rank_label.resize(200, 60) self.rank_label.setText('summoner rank') self.rank_label.setStyleSheet("QLabel {font:18pt}") #miniseries labels self.series_labels = {} self.pixmap_win = QPixmap() self.pixmap_loss = QPixmap() self.pixmap_n = QPixmap() self.pixmap_win.load("./images/win.png") self.pixmap_loss.load("./images/loss.png") self.pixmap_n.load("./images/n.png") xPos = 600 for x in range(5): match_label = QLabel(self) match_label.move(xPos, 120) match_label.resize(35, 35) match_label.setScaledContents(True) match_label.hide() self.series_labels[x] = match_label xPos += 40 #mastery image labels print 'loading mastery images ...' self.ferocity_tree_images = self.getMasteryImages( self.summoner.ferocityMasteryTree()) self.cunning_tree_images = self.getMasteryImages( self.summoner.cunningMasteryTree()) self.resolve_tree_images = self.getMasteryImages( self.summoner.resolveMasteryTree()) print 'Done' #champion icon image labels print 'loading champion icon images ...' self.championIcons = self.getChampionIconImages( self.summoner.championList()) print 'Done' #overview widget self.overview_widget = QWidget() self.overview_menu = QTabWidget(self.overview_widget) self.overview_menu.resize(720, 270) #runes widget self.runes_widget = QWidget() self.runes_menu = QTabWidget(self.runes_widget) self.runes_menu.resize(720, 270) #masteries widget self.masteries_widget = QWidget() self.masteries_menu = QTabWidget(self.masteries_widget) self.masteries_menu.resize(720, 270) #summoner menu self.menu = QTabWidget(self) self.menu.move(260, 180) self.menu.resize(720, 300) self.menu.addTab(self.overview_widget, "Overview") self.menu.addTab(self.runes_widget, "Runes") self.menu.addTab(self.masteries_widget, "Masteries") self.menu.hide() #summoners buttons self.button_list = {} yPos = 150 for x in range(10): sum_button = QPushButton(self) sum_button.move(50, yPos) sum_button.resize(150, 25) sum_button.hide() self.button_list[x] = sum_button yPos += 25 ### Connecting Widgets ### ########################## self.connect(self.search_button, QtCore.SIGNAL("clicked()"), self.getData) self.connect(self.search_button, QtCore.SIGNAL("clicked()"), self.getRankedData) self.connect(self.button_list[0], QtCore.SIGNAL("clicked()"), lambda: self.displayData(str(self.button_list[0].text()))) self.connect(self.button_list[1], QtCore.SIGNAL("clicked()"), lambda: self.displayData(str(self.button_list[1].text()))) self.connect(self.button_list[2], QtCore.SIGNAL("clicked()"), lambda: self.displayData(str(self.button_list[2].text()))) self.connect(self.button_list[3], QtCore.SIGNAL("clicked()"), lambda: self.displayData(str(self.button_list[3].text()))) self.connect(self.button_list[4], QtCore.SIGNAL("clicked()"), lambda: self.displayData(str(self.button_list[4].text()))) self.connect(self.button_list[5], QtCore.SIGNAL("clicked()"), lambda: self.displayData(str(self.button_list[5].text()))) self.connect(self.button_list[6], QtCore.SIGNAL("clicked()"), lambda: self.displayData(str(self.button_list[6].text()))) self.connect(self.button_list[7], QtCore.SIGNAL("clicked()"), lambda: self.displayData(str(self.button_list[7].text()))) self.connect(self.button_list[8], QtCore.SIGNAL("clicked()"), lambda: self.displayData(str(self.button_list[8].text()))) self.connect(self.button_list[9], QtCore.SIGNAL("clicked()"), lambda: self.displayData(str(self.button_list[9].text()))) ### Window Configuration ### ############################ #window settings self.setGeometry(200, 150, 1000, 500) self.setMaximumSize(1000, 500) self.setWindowTitle('summoner App') self.show()
class FeatureFormWidget(Ui_Form, QWidget): # Raise the cancel event, takes a reason and a level canceled = pyqtSignal(str, int) featuresaved = pyqtSignal() featuredeleted = pyqtSignal() def __init__(self, parent=None): super(FeatureFormWidget, self).__init__(parent) self.setupUi(self) toolbar = QToolBar() size = QSize(48, 48) toolbar.setIconSize(size) style = Qt.ToolButtonTextUnderIcon toolbar.setToolButtonStyle(style) self.actionDelete = toolbar.addAction(QIcon(":/icons/delete"), "Delete") self.actionDelete.triggered.connect(self.delete_feature) label = '<b style="color:red">*</b> Required fields' self.missingfieldsLabel = QLabel(label) self.missingfieldsLabel.hide() self.missingfieldaction = toolbar.addWidget(self.missingfieldsLabel) titlespacer = QWidget() titlespacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) toolbar.addWidget(titlespacer) self.titlellabel = QLabel(label) self.titlellabel.setProperty("headerlabel", True) self.titlelabelaction = toolbar.addWidget(self.titlellabel) spacer = QWidget() spacer2 = QWidget() spacer2.setMinimumWidth(40) spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) spacer2.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) toolbar.addWidget(spacer) self.actionCancel = toolbar.addAction(QIcon(":/icons/cancel"), "Cancel") toolbar.addWidget(spacer2) self.actionSave = toolbar.addAction(QIcon(":/icons/save"), "Save") self.actionSave.triggered.connect(self.save_feature) self.layout().setContentsMargins(0, 3, 0, 3) self.layout().insertWidget(0, toolbar) self.actiontoolbar = QToolBar() self.actiontoolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.actiontoolbar.addWidget(spacer) self.layout().insertWidget(1, self.actiontoolbar) self.flickwidget = FlickCharm() self.flickwidget.activateOn(self.scrollArea) self.featureform = None self.values = {} self.config = {} self.feature = None def set_featureform(self, featureform): """ Note: There can only be one feature form. If you need to show another one make a new FeatureFormWidget """ self.featureform = featureform self.titlellabel.setText(self.featureform.windowTitle()) self.featureform.formvalidation.connect(self._update_validation) self.featureform.helprequest.connect( functools.partial(RoamEvents.helprequest.emit, self)) self.featureform.showlargewidget.connect(RoamEvents.show_widget.emit) self.featureform.enablesave.connect(self.actionSave.setEnabled) self.featureform.enablesave.connect(self.actionSave.setVisible) self.featureform.rejected.connect(self.canceled.emit) self.featureform.accepted.connect(self.featuresaved) actions = self.featureform.form_actions() if actions: for action in actions: self.actiontoolbar.addAction(action) else: self.actiontoolbar.hide() self.featureform.setContentsMargins(0, 0, 0, 0) self.featureformarea.layout().addWidget(self.featureform) def delete_feature(self): try: msg = self.featureform.deletemessage except AttributeError: msg = 'Do you really want to delete this feature?' box = DeleteFeatureDialog(msg) if not box.exec_(): return try: self.featureform.delete() except featureform.DeleteFeatureException as ex: RoamEvents.raisemessage(*ex.error) self.featureform.featuredeleted(self.feature) self.featuredeleted.emit() def feature_saved(self): self.featuresaved.emit() RoamEvents.featuresaved.emit() def save_feature(self): try: self.featureform.save() except featureform.MissingValuesException as ex: RoamEvents.raisemessage(*ex.error) return except featureform.FeatureSaveException as ex: RoamEvents.raisemessage(*ex.error) self.feature_saved() def set_config(self, config): self.config = config editmode = config['editmode'] allowsave = config.get('allowsave', True) self.feature = config.get('feature', None) tools = config.get('tools', []) candelete = True if tools: candelete = "delete" in tools self.featureform.feature = self.feature self.featureform.editingmode = editmode self.actionDelete.setVisible(editmode and candelete) self.actionSave.setEnabled(allowsave) def _update_validation(self, passed): # Show the error if there is missing fields self.missingfieldaction.setVisible(not passed) def bind_values(self, values): self.values = values self.featureform.bindvalues(values) def after_load(self): self.featureform.loaded() def before_load(self): self.featureform.load(self.config['feature'], self.config['layers'], self.values)
class Entity(QWidget): def __init__(self, base_image, parent=None): super().__init__(parent) self._base_label = QLabel(self) self._base_image = base_image self._decor_label = QLabel(self) self._decor_pixmap = None self.__pixmap = None """:type: PyQt4.QtGui.QPixmap""" self.__cord_x = 0 self.__cord_y = 0 self.__angle = 0 self.setAlignment(Qt.AlignCenter) self.updatePixmap() if _debugging: self.setStyleSheet("border: 1px solid black") @property def angle(self): return self.__angle @angle.setter def angle(self, angle): self.__angle = angle self.updatePixmap() @property def cord_x(self): return self.__cord_x @cord_x.setter def cord_x(self, cord): self.__cord_x = cord self.move(self.cord_x, self.cord_y) @property def cord_y(self): return self.__cord_y @cord_y.setter def cord_y(self, cord): self.__cord_y = cord self.move(self.cord_x, self.cord_y) def add_decoration(self, path): if path is None: self._decor_label.hide() else: self._decor_label = QLabel(self) self._decor_pixmap = QPixmap(path) self._decor_pixmap = self._decor_pixmap.scaled(self._decor_pixmap.width() * _SCALE, self._decor_pixmap.height() * _SCALE) self._decor_pixmap = self._decor_pixmap.transformed(QTransform().rotate(self.angle)) self._decor_label.setPixmap(self._decor_pixmap) def updatePixmap(self): path = _PATH + os.sep + "assets" + os.sep + self._base_image self.__pixmap = QPixmap(path) self.__pixmap = self.__pixmap.scaled(self.__pixmap.width()*_SCALE, self.__pixmap.height()*_SCALE) self.__pixmap = self.__pixmap.transformed(QTransform().rotate(self.angle)) self._base_label.setPixmap(self.__pixmap) self.setFixedSize(self.__pixmap.width(), self.__pixmap.height()) def setFixedSize(self, x, y): super().setFixedSize(x, y) self._base_label.setFixedSize(x, y) def setAlignment(self, alignment): self._base_label.setAlignment(alignment) self._decor_label.setAlignment(alignment)
class parcial(QWidget): def __init__(self): self.ingresar = QApplication(sys.argv) super(parcial, self).__init__(None) self.ingreso = QWidget() self.ingreso.resize(440, 320) self.ingreso.setWindowTitle('Autenticacion de Ingreso') self.sistema = QWidget() self.sistema.resize(480, 320) self.sistema.setWindowTitle('Identificador de Numeros Telefonicos') def inicio(self, u=0, c=0): self.imaje = QLabel(self.ingreso) self.imaje.setGeometry(10, 10, 225, 225) self.imaje.setPixmap(QPixmap(getcwd() + "/logo.gif")) self.u = QLabel('Nombre de Usuario:', self.ingreso) self.u.move(288, 162) self.c = QLabel('Clave:', self.ingreso) self.c.move(333, 202) self.m = QLabel('Usuario y(o) Clave Incorrecta', self.ingreso) self.m.move(250, 303) self.m.hide() self.User = QLineEdit(self.ingreso) self.User.setGeometry(280, 180, 140, 20) self.Pass = QLineEdit(self.ingreso) self.Pass.setGeometry(280, 220, 140, 20) self.entra = QPushButton('Entrar', self.ingreso) self.entra.setGeometry(320, 260, 60, 30) self.ingreso.connect(self.entra, SIGNAL('clicked()'), lambda: self.revisar(self.User, self.Pass)) self.ingreso.show() sys.exit(self.ingresar.exec_()) def revisar(self, user, passw, flag=0): u = user.text() c = passw.text() #print u+''+c login = open('login.txt', 'rU') for i in login: if i == u + ',' + c + '\n': flag = 1 self.m.hide() m = menu() m.exec_() if flag == 0: self.m.show() self.ingreso.update() login.close()
class ComponentSearchForm(): data_source = None related_mashups = None widget = None table = None add_btn = None graph_form = None highlighted_api = None highlighted_mashup = None def show_main_window(self): self.graph_form = matplotlibWidget() if self.widget: self.widget.destroy() self.widget = None; self.widget = QWidget() self.widget.setMinimumSize(800, 600) btn_api = QtGui.QPushButton("Recommend Modules", self.widget) btn_api.move(30, 20) btn_mashup = QtGui.QPushButton("Recommend Workflows", self.widget) btn_mashup.move(200, 20) self.textboxLabel = QLabel(self.widget) self.textboxLabel.setText("Describe your goals:") self.textboxLabel.move(35, 60) self.textboxLabel.show self.textbox = QTextEdit(self.widget) self.textbox.move(30, 80) self.textbox.setFixedWidth(300) self.textbox.setFixedHeight(28) btn_api.clicked.connect(self.api_button_clicked) btn_mashup.clicked.connect(self.mashups_button_clicked) self.table = QTableView(self.widget) self.table.clicked.connect(self.table_clicked) self.table.setMinimumSize(740, 500) self.table.resizeColumnsToContents() self.table.move(30, 120) self.widget.show() self.add_btn = QPushButton(self.widget) self.add_btn.clicked.connect(self.add_new_api) self.add_btn.setText("Add to Palette") self.add_btn.hide() self.add_btn.move(650, 20) self.recommendLabel = QLabel(self.widget) self.recommendLabel.setText("Also Used") self.recommendLabel.move(30, 95) self.recommendLabel.hide() self.switch_btn_apis = QPushButton(self.widget) self.switch_btn_apis.clicked.connect(self._show_related_apis) self.switch_btn_apis.setText("Related Mashup") self.switch_btn_apis.move(500, 20) self.switch_btn_apis.hide() self.switch_btn_mashups = QPushButton(self.widget) self.switch_btn_mashups.clicked.connect(self._show_related_mashups) self.switch_btn_mashups.setText("Related API") self.switch_btn_mashups.move(500, 20) self.switch_btn_mashups.hide() def __init__(self, parent=None): self.data_source = DataSource() def table_clicked(self): """ Click the table, the graph form may change according to the selection. """ model = self.table.selectionModel() indexes = model.selectedIndexes() for index in indexes: row = index.row() data = index.model().headerData(0,Qt.Horizontal).toString() newIndex = index.model().index(row, 0) if data == "API": api_id = get_api_full_name(newIndex.model().data(newIndex).toString()) api = self.data_source.api_by_id(api_id) print api mashups = self.data_source.mashups_by_api(api) apis = [] for mashup in mashups: apis.extend(self.data_source.apis_by_mashup(mashup)) self.graph_form.draw_apis(apis, api, self.highlighted_api) else: mashup_id = get_mashup_full_name(newIndex.model().data(newIndex).toString()) mashup = self.data_source.mashup_by_id(mashup_id) if not mashup: return apis = self.data_source.apis_by_mashup(mashup) mashups = [] if len(apis) > 0: mashups.extend(self.data_source.mashups_by_api(apis[0])) self.graph_form.draw_mashups(mashups, mashup, self.highlighted_mashup) return def _show_apis(self, apis, recommend=False): self.switch_btn_apis.hide() self.switch_btn_mashups.hide() self.recommendLabel.hide() row = 0 model = QStandardItemModel(len(apis), 4) model.setColumnCount(4) for api in apis: model.setData(model.index(row, 0), QVariant(get_api_name(api))) model.setData(model.index(row, 1), QVariant(api['protocols'])) model.setData(model.index(row, 2), QVariant(api['provider'])) model.setData(model.index(row, 3), QVariant(api['version'])) row += 1 model.setHeaderData(0, Qt.Horizontal, QVariant("Module")) model.setHeaderData(1, Qt.Horizontal, QVariant("Protocol")) model.setHeaderData(2, Qt.Horizontal, QVariant("Provider")) model.setHeaderData(3, Qt.Horizontal, QVariant("Version")) # model.setHeaderData(0, Qt.Horizontal, QVariant("API")) # model.setHeaderData(1, Qt.Horizontal, QVariant("Protocols")) # model.setHeaderData(2, Qt.Horizontal, QVariant("Provider")) # model.setHeaderData(3, Qt.Horizontal, QVariant("Version")) self.table.setModel(model) self.table.resizeColumnsToContents() if recommend: self.recommendLabel.show() self.add_btn.show() def _show_mashups(self, mashups): self.switch_btn_apis.hide() self.switch_btn_mashups.hide() self.recommendLabel.hide() row = 0 model = QStandardItemModel(len(mashups), 4) model.setColumnCount(4) for mashup in mashups: model.setData(model.index(row, 0), QVariant(get_mashup_name(mashup))) model.setData(model.index(row, 1), QVariant(mashup['title'])) model.setData(model.index(row, 2), QVariant(mashup['self'])) model.setData(model.index(row, 3), QVariant(mashup['description'])) row += 1 model.setHeaderData(0, Qt.Horizontal, QVariant("Workflow")) model.setHeaderData(1, Qt.Horizontal, QVariant("Short Description")) model.setHeaderData(2, Qt.Horizontal, QVariant("Provider")) model.setHeaderData(3, Qt.Horizontal, QVariant("Detailed Info")) # model.setHeaderData(0, Qt.Horizontal, QVariant("Info")) # model.setHeaderData(1, Qt.Horizontal, QVariant("Title")) # model.setHeaderData(2, Qt.Horizontal, QVariant("self")) # model.setHeaderData(3, Qt.Horizontal, QVariant("Description")) self.table.setModel(model) self.table.resizeColumnsToContents() self.add_btn.show() def api_button_clicked(self): """ Trigger to search APIs """ self.graph_form.draw_api() self.graph_form.show() apis = self.data_source.apis() key = str(self.textbox.toPlainText()) #Has key or not has key, it is different. if key: self.api_search_button_clicked() else: self._show_apis(apis) def mashups_button_clicked(self): """ Trigger to search mashups """ self.graph_form.draw_mashup() self.graph_form.show() key = str(self.textbox.toPlainText()) if key: self.mashup_search_button_clicked() else: self._show_mashups(self.data_source.mashups()) #Should probably refactor this into one method. def api_search_button_clicked(self): """ Search when no keyword """ self.highlighted_api = None self.highlighted_mashup = None key = str(self.textbox.toPlainText()) if key != "": apis = self.data_source.search_api(key) self._show_apis(apis) def mashup_search_button_clicked(self): """ Search when no keyword """ self.highlighted_api = None self.highlighted_mashup = None key = str(self.textbox.toPlainText()) if key != "": mashups = self.data_source.search_mashup(key) self._show_mashups(mashups) def add_new_api(self): """ Add new api to the modules package. """ apis = self.data_source.apis() model = self.table.selectionModel() indexes = model.selectedIndexes() for index in indexes: api = apis[index.row()] self._add_new_api(api) return def add_related_api(self): objs = [] for mashup in self.related_mashups: objs.append(mashup) for api in mashup["related_mashups"]: objs.append(api) model = self.table.selectionModel() indexes = model.selectedIndexes() for index in indexes: api = objs[index.row()] if api.get("protocols"): self._add_new_api(api) return def _show_related_mashups(self): self.switch_btn_apis.hide() self.switch_btn_mashups.hide() self.recommendLabel.hide() apis = [] objs = [] for mashup in self.related_mashups: apis.extend(mashup["related_mashups"]) for api in apis: objs.append(api) mashups = self.data_source.mashups_by_api(api) objs.extend(mashups) row = 0 model = QStandardItemModel(len(objs), 4) model.setColumnCount(4) for obj in objs: if obj.get('protocols'): model.setData(model.index(row, 0), QVariant(get_api_name(obj))) model.setData(model.index(row, 1), QVariant(obj['protocols'])) model.setData(model.index(row, 2), QVariant(obj['provider'])) else: model.setData(model.index(row, 3), QVariant(get_mashup_name(obj))) row += 1 model.setHeaderData(0, Qt.Horizontal, QVariant("API")) model.setHeaderData(1, Qt.Horizontal, QVariant("Protocols")) model.setHeaderData(2, Qt.Horizontal, QVariant("Provider")) model.setHeaderData(3, Qt.Horizontal, QVariant("Mashup")) self.table.setModel(model) self.table.resizeColumnsToContents() self.switch_btn_apis.show() def _show_related_apis(self): self.switch_btn_apis.hide() self.switch_btn_mashups.hide() self.recommendLabel.hide() row = 0 objs = [] for mashup in self.related_mashups: objs.append(mashup) for api in mashup["related_mashups"]: objs.append(api) #Combining similarity and related. similar_apis = self.data_source.search_api_similarity(self.highlighted_api) #return str(mashup['id'])[(len("http://www.programmableweb.com/mashup/")):] objs.append({'id': "http://www.programmableweb.com/mashup/Using-Similarity-Metric"}) objs.extend(similar_apis) #Combining similarity and related. model = QStandardItemModel(len(objs), 5) for obj in objs: if obj.get('protocols'): model.setData(model.index(row, 1), QVariant(get_api_name(obj))) model.setData(model.index(row, 2), QVariant(obj['protocols'])) model.setData(model.index(row, 3), QVariant(obj['provider'])) model.setData(model.index(row, 4), QVariant(obj['version'])) else: model.setData(model.index(row, 0), QVariant(get_mashup_name(obj))) row += 1 model.setHeaderData(0, Qt.Horizontal, QVariant("Mashup")) model.setHeaderData(1, Qt.Horizontal, QVariant("API")) model.setHeaderData(2, Qt.Horizontal, QVariant("Protocols")) model.setHeaderData(3, Qt.Horizontal, QVariant("Provider")) model.setHeaderData(4, Qt.Horizontal, QVariant("Version")) self.table.setModel(model) self.switch_btn_mashups.show() def _add_new_api(self, api): self.highlighted_api = api mashups = self.data_source.mashups_by_api(api) for mashup in mashups: mashup['related_mashups'] = (self.data_source.apis_by_mashup(mashup)) if len(mashups) > 0: self.related_mashups = mashups self._show_related_apis() manager = core.packagemanager.get_package_manager() reg = core.modules.module_registry.get_module_registry() package = manager.get_package("edu.cmu.sv.components", "1.0.0") core.modules.module_registry.set_current_package(package) if (api["protocols"] == "SOAP" and api["wsdl"] != ""): s = Service(api["wsdl"]) add_new_service(s, api["wsdl"]) else: new_module = vistrails_module.new_module(Module, get_api_name(api)) reg.add_module(new_module) reg.add_input_port(new_module, "value1", (core.modules.basic_modules.String, 'the first argument')) reg.add_input_port(new_module, "value2", (core.modules.basic_modules.String, 'the second argument')) reg.add_output_port(new_module, "value", (core.modules.basic_modules.String, 'the result'))
class RunDialog(QDialog): def __init__(self, run_model): QDialog.__init__(self) self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) self.setWindowFlags(self.windowFlags() & ~Qt.WindowCloseButtonHint) self.setModal(True) self.setWindowTitle("Simulations") assert isinstance(run_model, RunModelMixin) self.__run_model = run_model layout = QVBoxLayout() layout.setSizeConstraint(QLayout.SetFixedSize) self.simulations_tracker = SimulationsTracker() states = self.simulations_tracker.getList() self.total_progress = SimpleProgress() layout.addWidget(self.total_progress) status_layout = QHBoxLayout() status_layout.addStretch() self.__status_label = QLabel() status_layout.addWidget(self.__status_label) status_layout.addStretch() layout.addLayout(status_layout) self.progress = Progress() self.progress.setIndeterminateColor(self.total_progress.color) for state in states: self.progress.addState(state.state, QColor(*state.color), 100.0 * state.count / state.total_count) layout.addWidget(self.progress) legend_layout = QHBoxLayout() self.legends = {} for state in states: self.legends[state] = Legend("%s (%d/%d)", QColor(*state.color)) self.legends[state].updateLegend(state.name, 0, 0) legend_layout.addWidget(self.legends[state]) layout.addLayout(legend_layout) self.running_time = QLabel("") ert = None if isinstance(run_model, ErtConnector): ert = run_model.ert() self.plot_tool = PlotTool(ert) self.plot_tool.setParent(self) self.plot_button = QPushButton(self.plot_tool.getName()) self.plot_button.clicked.connect(self.plot_tool.trigger) self.plot_button.setEnabled(ert is not None) self.kill_button = QPushButton("Kill simulations") self.done_button = QPushButton("Done") self.done_button.setHidden(True) button_layout = QHBoxLayout() size = 20 spin_movie = util.resourceMovie("ide/loading.gif") spin_movie.setSpeed(60) spin_movie.setScaledSize(QSize(size, size)) spin_movie.start() self.processing_animation = QLabel() self.processing_animation.setMaximumSize(QSize(size, size)) self.processing_animation.setMinimumSize(QSize(size, size)) self.processing_animation.setMovie(spin_movie) button_layout.addWidget(self.processing_animation) button_layout.addWidget(self.running_time) button_layout.addStretch() button_layout.addWidget(self.plot_button) button_layout.addWidget(self.kill_button) button_layout.addWidget(self.done_button) layout.addStretch() layout.addLayout(button_layout) self.setLayout(layout) self.kill_button.clicked.connect(self.killJobs) self.done_button.clicked.connect(self.accept) self.__updating = False self.__update_queued = False self.__simulation_started = False self.__update_timer = QTimer(self) self.__update_timer.setInterval(500) self.__update_timer.timeout.connect(self.updateRunStatus) def startSimulation(self): self.__run_model.reset( ) simulation_thread = Thread(name="ert_gui_simulation_thread") simulation_thread.setDaemon(True) simulation_thread.run = self.__run_model.startSimulations simulation_thread.start() self.__update_timer.start() def checkIfRunFinished(self): if self.__run_model.isFinished(): self.hideKillAndShowDone() if self.__run_model.hasRunFailed(): error = self.__run_model.getFailMessage() QMessageBox.critical(self, "Simulations failed!", "The simulation failed with the following error:\n\n%s" % error) self.reject() def updateRunStatus(self): self.checkIfRunFinished() self.total_progress.setProgress(self.__run_model.getProgress()) self.__status_label.setText(self.__run_model.getPhaseName()) states = self.simulations_tracker.getList() if self.__run_model.isIndeterminate(): self.progress.setIndeterminate(True) for state in states: self.legends[state].updateLegend(state.name, 0, 0) else: self.progress.setIndeterminate(False) total_count = self.__run_model.getQueueSize() queue_status = self.__run_model.getQueueStatus() for state in states: state.count = 0 state.total_count = total_count for state in states: for queue_state in queue_status: if queue_state in state.state: state.count += queue_status[queue_state] self.progress.updateState(state.state, 100.0 * state.count / state.total_count) self.legends[state].updateLegend(state.name, state.count, state.total_count) self.setRunningTime() def setRunningTime(self): days = 0 hours = 0 minutes = 0 seconds = self.__run_model.getRunningTime() if seconds >= 60: minutes, seconds = divmod(seconds, 60) if minutes >= 60: hours, minutes = divmod(minutes, 60) if hours >= 24: days, hours = divmod(hours, 24) if days > 0: self.running_time.setText("Running time: %d days %d hours %d minutes %d seconds" % (days, hours, minutes, seconds)) elif hours > 0: self.running_time.setText("Running time: %d hours %d minutes %d seconds" % (hours, minutes, seconds)) elif minutes > 0: self.running_time.setText("Running time: %d minutes %d seconds" % (minutes, seconds)) else: self.running_time.setText("Running time: %d seconds" % seconds) def killJobs(self): kill_job = QMessageBox.question(self, "Kill simulations?", "Are you sure you want to kill the currently running simulations?", QMessageBox.Yes | QMessageBox.No ) if kill_job == QMessageBox.Yes: self.__run_model.killAllSimulations() self.reject() def hideKillAndShowDone(self): self.__update_timer.stop() self.processing_animation.hide() self.kill_button.setHidden(True) self.done_button.setHidden(False)
class RunWidget(QWidget): """Widget that show the execution output in the MiscContainer.""" def __init__(self): QWidget.__init__(self) vbox = QVBoxLayout(self) vbox.setSpacing(0) vbox.setContentsMargins(0, 0, 0, 0) self.output = OutputWidget(self) hbox = QHBoxLayout() self.input = QLineEdit() self.lblInput = QLabel(self.tr("Input:")) vbox.addWidget(self.output) hbox.addWidget(self.lblInput) hbox.addWidget(self.input) vbox.addLayout(hbox) #process self.currentProcess = None self.__preScriptExecuted = False self._proc = QProcess(self) self._preExecScriptProc = QProcess(self) self._postExecScriptProc = QProcess(self) self.connect(self._proc, SIGNAL("readyReadStandardOutput()"), self.output._refresh_output) self.connect(self._proc, SIGNAL("readyReadStandardError()"), self.output._refresh_error) self.connect(self._proc, SIGNAL("finished(int, QProcess::ExitStatus)"), self.finish_execution) self.connect(self._proc, SIGNAL("error(QProcess::ProcessError)"), self.process_error) self.connect(self.input, SIGNAL("returnPressed()"), self.insert_input) self.connect(self._preExecScriptProc, SIGNAL("finished(int, QProcess::ExitStatus)"), self.__main_execution) self.connect(self._preExecScriptProc, SIGNAL("readyReadStandardOutput()"), self.output._refresh_output) self.connect(self._preExecScriptProc, SIGNAL("readyReadStandardError()"), self.output._refresh_error) self.connect(self._postExecScriptProc, SIGNAL("finished(int, QProcess::ExitStatus)"), self.__post_execution_message) self.connect(self._postExecScriptProc, SIGNAL("readyReadStandardOutput()"), self.output._refresh_output) self.connect(self._postExecScriptProc, SIGNAL("readyReadStandardError()"), self.output._refresh_error) def process_error(self, error): """Listen to the error signals from the running process.""" self.lblInput.hide() self.input.hide() self._proc.kill() format_ = QTextCharFormat() format_.setAnchor(True) format_.setForeground(Qt.red) if error == 0: self.output.textCursor().insertText(self.tr('Failed to start'), format_) else: self.output.textCursor().insertText( self.tr('Error during execution, QProcess error: %d' % error), format_) def finish_execution(self, exitCode, exitStatus): """Print a message and hide the input line when the execution ends.""" self.lblInput.hide() self.input.hide() format_ = QTextCharFormat() format_.setAnchor(True) self.output.textCursor().insertText('\n\n') if exitStatus == QProcess.NormalExit: format_.setForeground(Qt.green) self.output.textCursor().insertText( self.tr("Execution Successful!"), format_) else: format_.setForeground(Qt.red) self.output.textCursor().insertText( self.tr("Execution Interrupted"), format_) self.output.textCursor().insertText('\n\n') self.__post_execution() def insert_input(self): """Take the user input and send it to the process.""" text = self.input.text() + '\n' self._proc.writeData(text) self.output.textCursor().insertText(text, self.output.plain_format) self.input.setText("") def start_process(self, fileName, pythonPath=False, PYTHONPATH=None, programParams='', preExec='', postExec=''): """Prepare the output widget and start the process.""" self.lblInput.show() self.input.show() self.fileName = fileName self.pythonPath = pythonPath # FIXME, this is python interpreter self.programParams = programParams self.preExec = preExec self.postExec = postExec self.PYTHONPATH = PYTHONPATH self.__pre_execution() def __main_execution(self): """Execute the project.""" self.output.setCurrentCharFormat(self.output.plain_format) message = '' if self.__preScriptExecuted: self.__preScriptExecuted = False message = self.tr( "Pre Execution Script Successfully executed.\n\n") self.output.setPlainText(message + 'Running: %s (%s)\n\n' % (self.fileName, unicode(time.ctime()))) self.output.moveCursor(QTextCursor.Down) self.output.moveCursor(QTextCursor.Down) self.output.moveCursor(QTextCursor.Down) #runner.run_code_from_file(fileName) if not self.pythonPath: self.pythonPath = settings.PYTHON_PATH #change the working directory to the fileName dir file_directory = file_manager.get_folder(self.fileName) self._proc.setWorkingDirectory(file_directory) #force python to unbuffer stdin and stdout options = ['-u'] + settings.EXECUTION_OPTIONS.split() self.currentProcess = self._proc if self.PYTHONPATH: envpaths = [path for path in self.PYTHONPATH.splitlines()] env = QProcessEnvironment() system_environemnt = self._proc.systemEnvironment() for e in system_environemnt: key, value = unicode(e).split('=', 1) env.insert(key, value) for path in envpaths: env.insert('PYTHONPATH', path) self._proc.setProcessEnvironment(env) self._proc.start(self.pythonPath, options + [self.fileName] + [p.strip() for p in self.programParams.split(',') if p]) def __pre_execution(self): """Execute a script before executing the project.""" filePreExec = QFile(self.preExec) if filePreExec.exists() and \ bool(QFile.ExeUser & filePreExec.permissions()): ext = file_manager.get_file_extension(self.preExec) if not self.pythonPath: self.pythonPath = settings.PYTHON_PATH self.currentProcess = self._preExecScriptProc self.__preScriptExecuted = True if ext == 'py': self._preExecScriptProc.start(self.pythonPath, [self.preExec]) else: self._preExecScriptProc.start(self.preExec) else: self.__main_execution() def __post_execution(self): """Execute a script after executing the project.""" filePostExec = QFile(self.postExec) if filePostExec.exists() and \ bool(QFile.ExeUser & filePostExec.permissions()): ext = file_manager.get_file_extension(self.postExec) if not self.pythonPath: self.pythonPath = settings.PYTHON_PATH self.currentProcess = self._postExecScriptProc if ext == 'py': self._postExecScriptProc.start(self.pythonPath, [self.postExec]) else: self._postExecScriptProc.start(self.postExec) def __post_execution_message(self): """Print post execution message.""" self.output.textCursor().insertText('\n\n') format_ = QTextCharFormat() format_.setAnchor(True) format_.setForeground(Qt.green) self.output.textCursor().insertText( self.tr("Post Execution Script Successfully executed."), format_) def kill_process(self): """Kill the running process.""" self._proc.kill()
class ActionBar(QFrame): """ SIGNALS: @changeCurrent(PyQt_PyObject) @runFile(QString) @reopenTab(QString) @recentTabsModified() """ def __init__(self, main_combo=False): super(ActionBar, self).__init__() self.setObjectName("actionbar") hbox = QHBoxLayout(self) hbox.setContentsMargins(1, 1, 1, 1) hbox.setSpacing(1) self.lbl_checks = QLabel('') self.lbl_checks.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.lbl_checks.setFixedWidth(48) self.lbl_checks.setVisible(False) hbox.addWidget(self.lbl_checks) self.combo = ComboFiles() self.combo.setIconSize(QSize(16, 16)) #model = QStandardItemModel() #self.combo.setModel(model) #self.combo.view().setDragDropMode(QAbstractItemView.InternalMove) self.combo.setMaximumWidth(300) self.combo.setObjectName("combotab") self.connect(self.combo, SIGNAL("currentIndexChanged(int)"), self.current_changed) self.combo.setToolTip(translations.TR_COMBO_FILE_TOOLTIP) self.combo.setContextMenuPolicy(Qt.CustomContextMenu) self.connect(self.combo, SIGNAL( "customContextMenuRequested(const QPoint &)"), self._context_menu_requested) hbox.addWidget(self.combo) self.symbols_combo = QComboBox() self.symbols_combo.setIconSize(QSize(16, 16)) self.symbols_combo.setObjectName("combo_symbols") self.connect(self.symbols_combo, SIGNAL("activated(int)"), self.current_symbol_changed) hbox.addWidget(self.symbols_combo) self.code_navigator = CodeNavigator() hbox.addWidget(self.code_navigator) self._pos_text = "Line: %d, Col: %d" self.lbl_position = QLabel(self._pos_text % (0, 0)) self.lbl_position.setObjectName("position") self.lbl_position.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) hbox.addWidget(self.lbl_position) self.btn_close = QPushButton( self.style().standardIcon(QStyle.SP_DialogCloseButton), '') self.btn_close.setIconSize(QSize(16, 16)) if main_combo: self.btn_close.setObjectName('navigation_button') self.btn_close.setToolTip(translations.TR_CLOSE_FILE) self.connect(self.btn_close, SIGNAL("clicked()"), self.about_to_close_file) else: self.btn_close.setObjectName('close_split') self.btn_close.setToolTip(translations.TR_CLOSE_SPLIT) self.connect(self.btn_close, SIGNAL("clicked()"), self.close_split) self.btn_close.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) hbox.addWidget(self.btn_close) def resizeEvent(self, event): super(ActionBar, self).resizeEvent(event) if event.size().width() < 350: self.symbols_combo.hide() self.code_navigator.hide() self.lbl_position.hide() else: self.symbols_combo.show() self.code_navigator.show() self.lbl_position.show() def add_item(self, text, neditable): """Add a new item to the combo and add the neditable data.""" self.combo.addItem(text, neditable) self.combo.setCurrentIndex(self.combo.count() - 1) def get_editables(self): editables = [] for index in range(self.combo.count()): neditable = self.combo.itemData(index) editables.append(neditable) return editables def add_symbols(self, symbols): """Add the symbols to the symbols's combo.""" self.symbols_combo.clear() for symbol in symbols: data = symbol[1] if data[1] == 'f': icon = QIcon(":img/function") else: icon = QIcon(":img/class") self.symbols_combo.addItem(icon, data[0]) def set_current_symbol(self, index): self.symbols_combo.setCurrentIndex(index) def update_item_icon(self, neditable, icon): index = self.combo.findData(neditable) self.combo.setItemIcon(index, icon) def update_item_text(self, neditable, text): index = self.combo.findData(neditable) self.combo.setItemText(index, text) def current_changed(self, index): """Change the current item in the combo.""" neditable = self.combo.itemData(index) self.emit(SIGNAL("changeCurrent(PyQt_PyObject, int)"), neditable, index) def current_symbol_changed(self, index): """Change the current symbol in the combo.""" self.emit(SIGNAL("goToSymbol(int)"), index) def update_line_col(self, line, col): """Update the line and column position.""" self.lbl_position.setText(self._pos_text % (line, col)) def _context_menu_requested(self, point): """Display context menu for the combo file.""" if self.combo.count() == 0: # If there is not an Editor opened, don't show the menu return menu = QMenu() actionAdd = menu.addAction(translations.TR_ADD_TO_PROJECT) actionRun = menu.addAction(translations.TR_RUN_FILE) menuSyntax = menu.addMenu(translations.TR_CHANGE_SYNTAX) self._create_menu_syntax(menuSyntax) menu.addSeparator() actionClose = menu.addAction(translations.TR_CLOSE_FILE) actionCloseAll = menu.addAction(translations.TR_CLOSE_ALL_FILES) actionCloseAllNotThis = menu.addAction( translations.TR_CLOSE_OTHER_FILES) menu.addSeparator() actionSplitH = menu.addAction(translations.TR_SPLIT_VERTICALLY) actionSplitV = menu.addAction(translations.TR_SPLIT_HORIZONTALLY) menu.addSeparator() actionCopyPath = menu.addAction( translations.TR_COPY_FILE_PATH_TO_CLIPBOARD) actionShowFileInExplorer = menu.addAction( translations.TR_SHOW_FILE_IN_EXPLORER) actionReopen = menu.addAction(translations.TR_REOPEN_FILE) actionUndock = menu.addAction(translations.TR_UNDOCK_EDITOR) if len(settings.LAST_OPENED_FILES) == 0: actionReopen.setEnabled(False) #Connect actions self.connect(actionSplitH, SIGNAL("triggered()"), lambda: self._split(False)) self.connect(actionSplitV, SIGNAL("triggered()"), lambda: self._split(True)) self.connect(actionRun, SIGNAL("triggered()"), self._run_this_file) self.connect(actionAdd, SIGNAL("triggered()"), self._add_to_project) self.connect(actionClose, SIGNAL("triggered()"), self.about_to_close_file) self.connect(actionCloseAllNotThis, SIGNAL("triggered()"), self._close_all_files_except_this) self.connect(actionCloseAll, SIGNAL("triggered()"), self._close_all_files) self.connect(actionCopyPath, SIGNAL("triggered()"), self._copy_file_location) self.connect(actionShowFileInExplorer, SIGNAL("triggered()"), self._show_file_in_explorer) self.connect(actionReopen, SIGNAL("triggered()"), self._reopen_last_tab) self.connect(actionUndock, SIGNAL("triggered()"), self._undock_editor) menu.exec_(QCursor.pos()) def _create_menu_syntax(self, menuSyntax): """Create Menu with the list of syntax supported.""" syntax = list(settings.SYNTAX.keys()) syntax.sort() for syn in syntax: menuSyntax.addAction(syn) self.connect(menuSyntax, SIGNAL("triggered(QAction*)"), self._reapply_syntax) def _reapply_syntax(self, syntaxAction): #TODO if [self.currentIndex(), syntaxAction] != self._resyntax: self._resyntax = [self.currentIndex(), syntaxAction] self.emit(SIGNAL("syntaxChanged(QWidget, QString)"), self.currentWidget(), syntaxAction.text()) def set_current_file(self, neditable): index = self.combo.findData(neditable) self.combo.setCurrentIndex(index) def set_current_by_index(self, index): self.combo.setCurrentIndex(index) def about_to_close_file(self, index=None): """Close the NFile object.""" if index is None: index = self.combo.currentIndex() neditable = self.combo.itemData(index) if neditable: neditable.nfile.close() def close_split(self): self.emit(SIGNAL("closeSplit()")) def close_file(self, neditable): """Receive the confirmation to close the file.""" index = self.combo.findData(neditable) self.combo.removeItem(index) return index def _run_this_file(self): """Execute the current file.""" neditable = self.combo.itemData(self.combo.currentIndex()) self.emit(SIGNAL("runFile(QString)"), neditable.file_path) def _add_to_project(self): """Emit a signal to let someone handle the inclusion of the file inside a project.""" neditable = self.combo.itemData(self.combo.currentIndex()) self.emit(SIGNAL("addToProject(QString)"), neditable.file_path) def _show_file_in_explorer(self): '''Triggered when the "Show File in Explorer" context menu action is selected. Emits the "showFileInExplorer(QString)" signal with the current file's full path as argument.''' neditable = self.combo.itemData(self.combo.currentIndex()) self.emit(SIGNAL("showFileInExplorer(QString)"), neditable.file_path) def _reopen_last_tab(self): self.emit(SIGNAL("reopenTab(QString)"), settings.LAST_OPENED_FILES.pop()) self.emit(SIGNAL("recentTabsModified()")) def _undock_editor(self): self.emit(SIGNAL("undockEditor()")) def _split(self, orientation): self.emit(SIGNAL("splitEditor(bool)"), orientation) def _copy_file_location(self): """Copy the path of the current opened file to the clipboard.""" neditable = self.combo.itemData(self.combo.currentIndex()) QApplication.clipboard().setText(neditable.file_path, QClipboard.Clipboard) def _close_all_files(self): """Close all the files opened.""" for i in range(self.combo.count()): self.about_to_close_file(0) def _close_all_files_except_this(self): """Close all the files except the current one.""" neditable = self.combo.itemData(self.combo.currentIndex()) for i in reversed(list(range(self.combo.count()))): ne = self.combo.itemData(i) if ne is not neditable: self.about_to_close_file(i)
class MuWizard(QWizard): def __init__(self, R=None, parent=None): QWizard.__init__(self, parent) self.R = R self.data = None self.addPage(self.introPage()) self.addPage(self.loadPage()) self.addPage(self.modelsPage()) self.addPage(self.resultsPage()) self.setWindowTitle('Wizard of muScale') self.setPixmap(QWizard.LogoPixmap, QPixmap(RES + ICONS + LOGO)) self.setStyleSheet('QWizard {' + GRADIENT +'}\ QPushButton {\ color: #333;\ border: 1px solid #555;\ border-radius: 11px;\ padding: 2px;\ background: qradialgradient(cx: 0.3, cy: -0.4,\ fx: 0.3, fy: -0.4,\ radius: 1.35, stop: 0 #fff, stop: 1 #888);\ min-width: 80px;}\ QPushButton:hover {\ color: #fff;\ background: qradialgradient(cx: 0.3, cy: -0.4,\ fx: 0.3, fy: -0.4,\ radius: 1.35, stop: 0 #fff, stop: 1 #bbb);}\ QPushButton:pressed {\ color: #800;\ background: qradialgradient(cx: 0.4, cy: -0.1,\ fx: 0.4, fy: -0.1,\ radius: 1.35, stop: 0 #fff, stop: 1 #ddd);}\ QPushButton:checked {\ background: qradialgradient(cx: 0.4, cy: -0.1,\ fx: 0.4, fy: -0.1,\ radius: 1.35, stop: 0 #fff, stop: 1 #ddd);}\ QComboBox {\ color: #333;\ border: 1px solid #555;\ border-radius: 11px;\ padding: 1px 18px 1px 3px;\ background: qradialgradient(cx: 0.3, cy: -0.4,\ fx: 0.3, fy: -0.4,\ radius: 1.35, stop: 0 #fff, stop: 1 #888);\ min-width: 20px;}\ QComboBox:hover {\ color: #fff;\ background: qradialgradient(cx: 0.3, cy: -0.4,\ fx: 0.3, fy: -0.4,\ radius: 1.35, stop: 0 #fff, stop: 1 #bbb);}\ QComboBox::down-arrow {\ image: url(' + RES + ICONS + ARROW_DOWN + ');}\ QComboBox::down-arrow:on {\ top: 1px;\ left: 1px;}\ QComboBox::drop-down {\ subcontrol-origin: padding;\ subcontrol-position: top right;\ width: 15px;\ border-left-width: 1px;\ border-left-color: darkgray;\ border-left-style: solid;\ border-top-right-radius: 3px;\ border-bottom-right-radius: 3px;}\ QToolButton {\ color: #333;\ border: 1px solid #555;\ border-radius: 11px;\ padding: 2px;\ background: qradialgradient(cx: 0.3, cy: -0.4,\ fx: 0.3, fy: -0.4,\ radius: 1.35, stop: 0 #fff, stop: 1 #888);\ min-width: 20px;}\ QToolButton:hover {\ color: #fff;\ background: qradialgradient(cx: 0.3, cy: -0.4,\ fx: 0.3, fy: -0.4,\ radius: 1.35, stop: 0 #fff, stop: 1 #bbb);}\ QToolButton:pressed {\ background: qradialgradient(cx: 0.4, cy: -0.1,\ fx: 0.4, fy: -0.1,\ radius: 1.35, stop: 0 #fff, stop: 1 #ddd);}\ QToolButton:checked {\ background: qradialgradient(cx: 0.4, cy: -0.1,\ fx: 0.4, fy: -0.1,\ radius: 1.35, stop: 0 #fff, stop: 1 #ddd);}') def introPage(self): intro = QWizardPage() intro.setTitle('Hello and welcome') label = QLabel('''This is a wizard. Now you're ready to forecast some time series! ''') label.setWordWrap(True) layout = QVBoxLayout() layout.addWidget(label) intro.setLayout(layout) return intro def loadPage(self): load = WizardPageEx('loadCheck') load.setTitle('Initial data') pathLbl = QLabel("<font style='color: gray'>Specify the file with time series to forecast:</font>") loadLbl = QLabel("<font style='color: gray'>Click</font>") loadLbl.setAlignment(Qt.AlignCenter) self.path = QLineEdit() self.path.setPlaceholderText('path to file') getPath = QToolButton() getPath.setText('...') self.resultLbl = QLabel() self.resultLbl.setAlignment(Qt.AlignCenter) self.resultLbl.hide() self.preview = QLabel() self.preview.setAlignment(Qt.AlignCenter) self.preview.setWordWrap(True) self.preview.hide() self.preview.setAttribute(Qt.WA_Hover) self.filter = Filter() self.preview.installEventFilter(self.filter) getPath.clicked.connect(self.loadData) layout = QGridLayout() layout.addWidget(pathLbl, 0, 0) layout.addWidget(loadLbl, 0, 1) layout.addWidget(self.path, 1, 0) layout.addWidget(getPath, 1, 1) layout.addWidget(self.resultLbl, 2, 0, 1, 2) layout.addWidget(self.preview, 3, 0, 1, 2) load.setLayout(layout) load.previewSeries = SeriesPreview() self.previewSeries = load.previewSeries # to be able to reference from class namespace self.loadCheck = load.check return load def modelsPage(self): models = WizardPageEx('modelCheck') models.setTitle('Forecast') lbl = QLabel("<font style='color: gray'>Forecast horizon:</font>") self.steps = QSpinBox() self.steps.setRange(MIN_FORECAST, MAX_FORECAST) self.steps.setValue(10) self.start = QPushButton('Forecast') self.start.clicked.connect(self.modelling) self.custom = QPushButton('Advanced') self.processing = QLabel() self.gifLoading = QMovie(RES + ICONS + PROGRESS, QByteArray(), self) self.gifLoading.setCacheMode(QMovie.CacheAll) self.gifLoading.setSpeed(100) self.processing.setMovie(self.gifLoading) self.processing.setAlignment(Qt.AlignCenter) self.processing.hide() self.status = QLabel() self.status.setAlignment(Qt.AlignCenter) self.status.hide() layout = QGridLayout() layout.addWidget(lbl, 0, 0) layout.addWidget(self.steps, 0, 1) layout.addWidget(self.start, 0, 2) layout.addWidget(self.custom, 0, 3) layout.addWidget(self.status, 1, 0, 1, 4) layout.addWidget(self.processing, 2, 0, 1, 4) models.setLayout(layout) self.customOpt = CustomOption() self.custom.clicked.connect(self.customOpt.show) self.modelCheck = models.check return models def resultsPage(self): results = QWizardPage() results.setFinalPage(True) results.setTitle('Results') self.graph = QLabel("<font style='font-size: 16px;'>Plot</font>") self.export = QLabel("<font style='font-size: 16px;'>Export</font>") self.showData = QLabel("<font style='font-size: 16px;'>Data</font>") self.plotResult = MplWidget(None) self.plotResult.canvas.fig.set_facecolor('white') self.resData = QLabel('') self.resData.setAlignment(Qt.AlignCenter) self.resData.setWordWrap(True) self.resData.hide() self.resFilter = ResFilter() self.resLayout = QVBoxLayout() self.resLayout.addWidget(self.export) self.resLayout.addWidget(self.graph) self.resLayout.addWidget(self.showData) self.resLayout.addWidget(self.plotResult) self.resLayout.addWidget(self.resData) self.plotResult.hide() for index in range(0, self.resLayout.count()): try: self.resLayout.itemAt(index).widget().setAlignment(Qt.AlignCenter) self.resLayout.itemAt(index).widget().setStyleSheet('QLabel { color: gray; }') self.resLayout.itemAt(index).widget().setAttribute(Qt.WA_Hover) self.resLayout.itemAt(index).widget().installEventFilter(self.resFilter) except Exception: pass self.resLayout.setAlignment(Qt.AlignCenter) self.resLayout.setSpacing(60) results.setLayout(self.resLayout) return results #---- actions ----# def loadData(self): fileName = unicode(QFileDialog.getOpenFileName(self, 'Open text file', RES)) if fileName: self.resultLbl.hide() self.preview.hide() if DataParser.istextfile(fileName): self.data = DataParser.getTimeSeriesFromTextData(data=open(fileName, 'r').read()) if len(self.data[0]) > DATA_LOW_LIMIT: self.resultLbl.setText("<font style='color: gray'>Success! Loaded<b> " + str(len(self.data[0])) + '</b> values, errors: <b>' + str( self.data[1]) + '</b></font>') self.resultLbl.show() self.path.setText(fileName) previewLength = 40 self.preview.setText("<font style='color: gray'><b>Preview:</b> "+ ' '.join( [str(e) for e in self.data[0][:previewLength]]) + "...</font>") self.previewSeries.updateData(self.data) self.preview.show() self.loadCheck.setChecked(True) else: self.resultLbl.setText("<font style='color: gray'>Not enough values to form data series.</font>") self.resultLbl.show() else: self.resultLbl.setText("<font style='color: gray'>Specified file is binary file!</font>") self.resultLbl.show() def modelling(self): self.processing.show() self.gifLoading.start() self.status.setText('') statusText = u"<font style='color: gray'>" # decomposition # if self.customOpt.options['enable']: self.signalEx = self.customOpt.options['signal'] self.wavelet = pywt.Wavelet(self.customOpt.options['wavelet']) wLevel = self.customOpt.options['lvls'] - 1 maxLevel = pywt.dwt_max_level(len(self.data[0]), self.wavelet) if wLevel > maxLevel: wLevel = maxLevel self.wInitialCoefficients = pywt.wavedec(self.data[0], self.wavelet, level=wLevel, mode=self.signalEx) self.wCoefficients = self.wInitialCoefficients else: self.signalEx = pywt.MODES.sp1 selected = select_wavelet(self.data[0], self.R) index = max(selected) self.wavelet = pywt.Wavelet(selected[index][1]) wLevel = calculate_suitable_lvl(self.data[0], self.wavelet, self.R, swt=False) self.wInitialCoefficients = pywt.wavedec(self.data[0], self.wavelet, level=wLevel, mode=self.signalEx) self.wCoefficients = self.wInitialCoefficients statusText += 'Wavelet: <b>' + self.wavelet.family_name + \ '</b> (' + self.wavelet.name + ', ' + self.wavelet.symmetry + ', orthogonal: ' + \ str(self.wavelet.orthogonal) + ')<br/>' statusText += 'Discrete Wavelet Transfom: <b>' + str(wLevel + 1) + ' levels</b><br/>' # models # options = {} options['multi'] = True options['fractal'] = False options['ljung'] = False self.models = auto_model(self.wCoefficients, self.R, options, self.data[0]) statusText += '<br/>Selected models:<br/>' for lvl, model in self.models.iteritems(): statusText += str(lvl) + '. <b>' + model.enumname.replace('_', ' ') + '</b><br/>' # forecasting # try: frequency = self.customOpt.options['frequency'] except Exception: frequency = 8 aic = False options['hw_gamma'] = True options['hw_model'] = 'additive' options['hw_period'] = frequency options['ar_aic'] = aic options['ar_method'] = 'burg' options['ar_order'] = 50 options['arima_auto'] = False options['arima_nons'] = True options['arima_nons_order'] = [6, 0, 9] options['arima_seas'] = True options['arima_seas_order'] = [9, 0, 1] options['lsf_aic'] = aic options['lsf_order'] = 30 options['ets_auto'] = aic options['ets_period'] = frequency options['sts_type'] = 'trend' options['append_fit'] = True self.multi_model_thread = MultiModelThread(self.models, self.wCoefficients, self.R, self.steps.value(), options,) self.multi_model_thread.done.connect(self.multiForecastFinished) self.multi_model_thread.start() statusText += '<br/>Forecasting...' self.status.setText(statusText) self.status.show() def multiForecastFinished(self, results): self.forecast = results self.gifLoading.stop() self.processing.hide() self.status.setText('<br/>'.join(str(self.status.text()).split('<br/>')[:-1]) + '<br/>Forecast complete.') self.modelCheck.setChecked(True) #---- results -----# def togglePlot(self): if self.plotResult.isVisible(): self.plotResult.hide() self.export.show() self.showData.show() self.resLayout.setSpacing(60) else: self.updateGraph() self.plotResult.show() self.export.hide() self.showData.hide() self.resLayout.setSpacing(5) def toggleData(self): if self.resData.isVisible(): self.export.show() self.graph.show() self.showData.show() self.resData.hide() self.resLayout.setSpacing(60) self.adjustSize() else: self.plotResult.hide() self.graph.hide() self.export.hide() self.showData.show() self.resData.show() self.resLayout.setSpacing(5) res = self.inverseWT() max = len(self.data[0]) - 1 resText = '<table border="0" align="center" style="border-style: groove;">' resText += '<tr><td align="center"><i>Initial</i></td><td align="center"><i>Forecast</i></td></tr>' resText += '<tr><td align="center">...</td><td></td></tr>' table = zip(self.data[0][max-10:max], res[max-10:max]) for i, j in table: resText += '<tr>' resText += '<td align="center">' + str(i) + '</td>' resText += '<td align="center">' + str(j) + '</td>' resText += '</tr>' for e in res[max+1:max+10]: resText += '<tr>' resText += '<td align="center"></td>' resText += '<td align="center">' + str(e) + '</td>' resText += '</tr>' resText += '<tr><td align="center"></td><td align="center">...</td></tr>' resText += '</table>' self.resData.setText(resText) self.adjustSize() def inverseWT(self): return pywt.waverec(update_dwt([e [1] for e in self.forecast], self.wavelet, self.signalEx), self.wavelet, mode=self.signalEx) def updateGraph(self): self.plotResult.updatePlot(self.inverseWT(), label='Simulation', color='r') self.plotResult.updatePlot(self.data[0], label='Time series', color='b') def exportToXls(self): # opening file dialog fileName = QFileDialog.getSaveFileName(self, 'Save as', RES, 'Microsoft Excel Spreadsheet (*.xls)') if fileName.count() > 0: try: COLUMN_WIDTH = 3000 alignment = Alignment() alignment.horizontal = Alignment.HORZ_CENTER alignment.vertical = Alignment.VERT_CENTER borders = Borders() borders.left = Borders.THIN borders.right = Borders.THIN borders.top = Borders.THIN borders.bottom = Borders.THIN style = XFStyle() style.alignment = alignment style.borders = borders font = Font() font.bold = True headerStyle = XFStyle() headerStyle.font = font separate = Borders() separate.left = Borders.THIN separate.right = Borders.DOUBLE separate.top = Borders.THIN separate.bottom = Borders.THIN separateStyle = XFStyle() separateStyle.borders = separate book = Workbook(encoding='utf-8') # modelling data dec_sheet = book.add_sheet('Data decomposition') # decomposition data # initial data column = 0 row = 0 dec_sheet.write(row, column, 'Time series', headerStyle) dec_sheet.col(column).width = COLUMN_WIDTH row += 1 for item in self.data[0]: dec_sheet.write(row, column, item, separateStyle) row += 1 # decomposition for lvl in self.wCoefficients: row = 0 column += 1 dec_sheet.write(row, column, 'Level' + str(column - 1), headerStyle) dec_sheet.col(column).width = COLUMN_WIDTH row += 1 for item in lvl: dec_sheet.write(row, column, item, style) row += 1 # decomposition graphs pass levels_sheet = book.add_sheet('Multiscale forecast') # levels data column = 0 for lvl in self.forecast: row = 0 levels_sheet.write(row, column, 'Level' + str(column), headerStyle) levels_sheet.col(column).width = COLUMN_WIDTH row += 1 for item in lvl[1]: levels_sheet.write(row, column, float(item), style) row += 1 column += 1 result_sheet = book.add_sheet('Results') # initial column = 0 row = 0 result_sheet.write(row, column, 'Initial data', headerStyle) result_sheet.col(column).width = COLUMN_WIDTH row += 1 for item in self.data[0]: result_sheet.write(row, column, item, separateStyle) row += 1 # forecast row = 0 column += 1 result_sheet.write(row, column, 'Forecast', headerStyle) result_sheet.col(column).width = COLUMN_WIDTH row += 1 for item in self.inverseWT(): result_sheet.write(row, column, item, style) row += 1 row = 0 column = 2 self.updateGraph() self.plotResult.saveFigure('forecast', format='bmp') result_sheet.insert_bitmap(RES + TEMP + 'forecast.bmp', row, column) # saving xls try: book.save(unicode(fileName)) except Exception: pass except Exception, e: pass
class RunWidget(QWidget): """Widget that show the execution output in the MiscContainer.""" def __init__(self): QWidget.__init__(self) vbox = QVBoxLayout(self) vbox.setSpacing(0) vbox.setContentsMargins(0, 0, 0, 0) self.output = OutputWidget(self) hbox = QHBoxLayout() self.input = QLineEdit() self.lblInput = QLabel(self.tr("Input:")) vbox.addWidget(self.output) hbox.addWidget(self.lblInput) hbox.addWidget(self.input) vbox.addLayout(hbox) #process self.currentProcess = None self.__preScriptExecuted = False self._proc = QProcess(self) self._preExecScriptProc = QProcess(self) self._postExecScriptProc = QProcess(self) self.connect(self._proc, SIGNAL("readyReadStandardOutput()"), self.output._refresh_output) self.connect(self._proc, SIGNAL("readyReadStandardError()"), self.output._refresh_error) self.connect(self._proc, SIGNAL("finished(int, QProcess::ExitStatus)"), self.finish_execution) self.connect(self._proc, SIGNAL("error(QProcess::ProcessError)"), self.process_error) self.connect(self.input, SIGNAL("returnPressed()"), self.insert_input) self.connect(self._preExecScriptProc, SIGNAL("finished(int, QProcess::ExitStatus)"), self.__main_execution) self.connect(self._preExecScriptProc, SIGNAL("readyReadStandardOutput()"), self.output._refresh_output) self.connect(self._preExecScriptProc, SIGNAL("readyReadStandardError()"), self.output._refresh_error) self.connect(self._postExecScriptProc, SIGNAL("finished(int, QProcess::ExitStatus)"), self.__post_execution_message) self.connect(self._postExecScriptProc, SIGNAL("readyReadStandardOutput()"), self.output._refresh_output) self.connect(self._postExecScriptProc, SIGNAL("readyReadStandardError()"), self.output._refresh_error) def process_error(self, error): """Listen to the error signals from the running process.""" self.lblInput.hide() self.input.hide() self._proc.kill() format_ = QTextCharFormat() format_.setAnchor(True) format_.setForeground(Qt.red) if error == 0: self.output.textCursor().insertText(self.tr('Failed to start'), format_) else: self.output.textCursor().insertText( self.tr('Error during execution, QProcess error: %d' % error), format_) def finish_execution(self, exitCode, exitStatus): """Print a message and hide the input line when the execution ends.""" self.lblInput.hide() self.input.hide() format_ = QTextCharFormat() format_.setAnchor(True) self.output.textCursor().insertText('\n\n') if exitStatus == QProcess.NormalExit: format_.setForeground(Qt.green) self.output.textCursor().insertText( self.tr("Execution Successful!"), format_) else: format_.setForeground(Qt.red) self.output.textCursor().insertText( self.tr("Execution Interrupted"), format_) self.output.textCursor().insertText('\n\n') self.__post_execution() def insert_input(self): """Take the user input and send it to the process.""" text = self.input.text() + '\n' self._proc.writeData(text) self.output.textCursor().insertText(text, self.output.plain_format) self.input.setText("") def start_process(self, fileName, pythonPath=False, PYTHONPATH=None, programParams='', preExec='', postExec=''): """Prepare the output widget and start the process.""" self.lblInput.show() self.input.show() self.fileName = fileName self.pythonPath = pythonPath # FIXME, this is python interpreter self.programParams = programParams self.preExec = preExec self.postExec = postExec self.PYTHONPATH = PYTHONPATH self.__pre_execution() def __main_execution(self): """Execute the project.""" self.output.setCurrentCharFormat(self.output.plain_format) message = '' if self.__preScriptExecuted: self.__preScriptExecuted = False message = self.tr( "Pre Execution Script Successfully executed.\n\n") self.output.setPlainText(message + 'Running: %s (%s)\n\n' % (self.fileName, time.ctime())) self.output.moveCursor(QTextCursor.Down) self.output.moveCursor(QTextCursor.Down) self.output.moveCursor(QTextCursor.Down) #runner.run_code_from_file(fileName) if not self.pythonPath: self.pythonPath = settings.PYTHON_PATH #change the working directory to the fileName dir file_directory = file_manager.get_folder(self.fileName) self._proc.setWorkingDirectory(file_directory) #force python to unbuffer stdin and stdout options = ['-u'] + settings.EXECUTION_OPTIONS.split() self.currentProcess = self._proc if self.PYTHONPATH: envpaths = [path for path in self.PYTHONPATH.splitlines()] env = QProcessEnvironment() system_environemnt = self._proc.systemEnvironment() for e in system_environemnt: key, value = e.split('=', 1) env.insert(key, value) for path in envpaths: env.insert('PYTHONPATH', path) self._proc.setProcessEnvironment(env) self._proc.start(self.pythonPath, options + [self.fileName] + [p.strip() for p in self.programParams.split(',') if p]) def __pre_execution(self): """Execute a script before executing the project.""" filePreExec = QFile(self.preExec) if filePreExec.exists() and \ bool(QFile.ExeUser & filePreExec.permissions()): ext = file_manager.get_file_extension(self.preExec) if not self.pythonPath: self.pythonPath = settings.PYTHON_PATH self.currentProcess = self._preExecScriptProc self.__preScriptExecuted = True if ext == 'py': self._preExecScriptProc.start(self.pythonPath, [self.preExec]) else: self._preExecScriptProc.start(self.preExec) else: self.__main_execution() def __post_execution(self): """Execute a script after executing the project.""" filePostExec = QFile(self.postExec) if filePostExec.exists() and \ bool(QFile.ExeUser & filePostExec.permissions()): ext = file_manager.get_file_extension(self.postExec) if not self.pythonPath: self.pythonPath = settings.PYTHON_PATH self.currentProcess = self._postExecScriptProc if ext == 'py': self._postExecScriptProc.start(self.pythonPath, [self.postExec]) else: self._postExecScriptProc.start(self.postExec) def __post_execution_message(self): """Print post execution message.""" self.output.textCursor().insertText('\n\n') format_ = QTextCharFormat() format_.setAnchor(True) format_.setForeground(Qt.green) self.output.textCursor().insertText( self.tr("Post Execution Script Successfully executed."), format_) def kill_process(self): """Kill the running process.""" self._proc.kill()
class preferencesDialog(QDialog): newMailerMessage = QtCore.Signal(str, str) def __init__(self, parent): QDialog.__init__(self, parent) self.tmpPref = {} self.tmpPref['pref'] = copy.deepcopy(self.parent().prm['pref']) self.currLocale = self.parent().prm['currentLocale'] self.currLocale.setNumberOptions(self.currLocale.OmitGroupSeparator | self.currLocale.RejectGroupSeparator) self.audioManager = parent.audioManager self.mailer = emailSender(self) self.newMailerMessage.connect(self.popMailerMessage) self.tabWidget = QTabWidget() self.tabWidget.currentChanged.connect(self.tabChanged) self.appPrefWidget = QWidget() self.soundPrefWidget = QWidget() self.notificationPrefWidget = QWidget() self.eegPrefWidget = QWidget() #the gui widget for these are in an external dialog self.wavsPref = {} self.wavsPref['endMessageFiles'] = self.tmpPref['pref']['general']['endMessageFiles'] self.wavsPref['endMessageFilesUse'] = self.tmpPref['pref']['general']['endMessageFilesUse'] self.wavsPref['endMessageFilesID'] = self.tmpPref['pref']['general']['endMessageFilesID'] self.wavsPref['endMessageLevels'] = self.tmpPref['pref']['general']['endMessageLevels'] #GENERAL PREF appPrefGrid = QGridLayout() n = 0 self.languageChooserLabel = QLabel(self.tr('Language (requires restart):')) appPrefGrid.addWidget(self.languageChooserLabel, n, 0) self.languageChooser = QComboBox() self.languageChooser.addItems(self.parent().prm['appData']['available_languages']) self.languageChooser.setCurrentIndex(self.languageChooser.findText(self.tmpPref['pref']['language'])) self.languageChooser.currentIndexChanged[int].connect(self.onLanguageChooserChange) appPrefGrid.addWidget(self.languageChooser, n, 1) n = n+1 self.countryChooserLabel = QLabel(self.tr('Country (requires restart):')) appPrefGrid.addWidget(self.countryChooserLabel, n, 0) self.countryChooser = QComboBox() self.countryChooser.addItems(self.parent().prm['appData']['available_countries'][self.tmpPref['pref']['language']]) self.countryChooser.setCurrentIndex(self.countryChooser.findText(self.tmpPref['pref']['country'])) appPrefGrid.addWidget(self.countryChooser, n, 1) n = n+1 self.responseBoxLanguageChooserLabel = QLabel(self.tr('Response Box Language (requires restart):')) appPrefGrid.addWidget(self.responseBoxLanguageChooserLabel, n, 0) self.responseBoxLanguageChooser = QComboBox() self.responseBoxLanguageChooser.addItems(self.parent().prm['appData']['available_languages']) self.responseBoxLanguageChooser.setCurrentIndex(self.responseBoxLanguageChooser.findText(self.tmpPref['pref']['responseBoxLanguage'])) self.responseBoxLanguageChooser.currentIndexChanged[int].connect(self.onResponseBoxLanguageChooserChange) appPrefGrid.addWidget(self.responseBoxLanguageChooser, n, 1) n = n+1 self.responseBoxCountryChooserLabel = QLabel(self.tr('Response Box Country (requires restart):')) appPrefGrid.addWidget(self.responseBoxCountryChooserLabel, n, 0) self.responseBoxCountryChooser = QComboBox() self.responseBoxCountryChooser.addItems(self.parent().prm['appData']['available_countries'][self.tmpPref['pref']['responseBoxLanguage']]) self.responseBoxCountryChooser.setCurrentIndex(self.responseBoxCountryChooser.findText(self.tmpPref['pref']['responseBoxCountry'])) appPrefGrid.addWidget(self.responseBoxCountryChooser, n, 1) n = n+1 self.csvSeparatorLabel = QLabel(self.tr('csv separator:')) appPrefGrid.addWidget(self.csvSeparatorLabel, n, 0) self.csvSeparatorWidget = QLineEdit(self.tmpPref['pref']["general"]["csvSeparator"]) appPrefGrid.addWidget(self.csvSeparatorWidget, n, 1) n = n+1 self.listenerNameWarnCheckBox = QCheckBox(self.tr('Warn if listener name missing')) self.listenerNameWarnCheckBox.setChecked(self.tmpPref["pref"]["general"]["listenerNameWarn"]) appPrefGrid.addWidget(self.listenerNameWarnCheckBox, n, 0) n = n+1 self.sessionLabelWarnCheckBox = QCheckBox(self.tr('Warn if session label missing')) self.sessionLabelWarnCheckBox.setChecked(self.tmpPref["pref"]["general"]["sessionLabelWarn"]) appPrefGrid.addWidget(self.sessionLabelWarnCheckBox, n, 0) n = n+1 self.dpCorrCheckBox = QCheckBox(self.tr('d-prime correction')) self.dpCorrCheckBox.setChecked(self.tmpPref['pref']['general']['dprimeCorrection']) self.dpCorrCheckBox.setWhatsThis(self.tr("If checked, when automatically processing result files, convert hit rates of 0 and 1 to 1/2N and 1-1/(2N) respectively, where N is the number of trials, to avoid infinite values of d'")) appPrefGrid.addWidget(self.dpCorrCheckBox, n, 0) n = n+1 self.recursionLimitLabel = QLabel(self.tr('Max Recursion Depth (requires restart):')) appPrefGrid.addWidget(self.recursionLimitLabel, n, 0) self.recursionLimitWidget = QLineEdit(self.currLocale.toString(self.tmpPref["pref"]["general"]["maxRecursionDepth"])) self.recursionLimitWidget.setValidator(QIntValidator(self)) appPrefGrid.addWidget(self.recursionLimitWidget, n, 1) n = n+1 n = n+1 self.startupCommandLabel = QLabel(self.tr('Execute command at startup:')) appPrefGrid.addWidget(self.startupCommandLabel, n, 0) self.startupCommandWidget = QLineEdit(self.tmpPref["pref"]["general"]["startupCommand"]) appPrefGrid.addWidget(self.startupCommandWidget, n, 1) n = n+1 self.appPrefWidget.setLayout(appPrefGrid) self.appPrefWidget.layout().setSizeConstraint(QLayout.SetFixedSize) #SOUND PREF soundPrefGrid = QGridLayout() n = 0 self.playChooser = QComboBox() self.playChooser.addItems(self.parent().prm['appData']['available_play_commands']) self.playChooser.setCurrentIndex(self.playChooser.findText(self.tmpPref['pref']['sound']['playCommandType'])) self.playChooser.currentIndexChanged[int].connect(self.onPlayChooserChange) self.playChooserLabel = QLabel(self.tr('Play Command:')) soundPrefGrid.addWidget(self.playChooserLabel, 0, 0) soundPrefGrid.addWidget(self.playChooser, 0, 1) n = n+1 self.playCommandLabel = QLabel(self.tr('Command:')) soundPrefGrid.addWidget(self.playCommandLabel, n, 0) self.playCommandWidget = QLineEdit(self.tmpPref['pref']['sound']['playCommand']) if self.playChooser.currentText() != self.tr('custom'): self.playCommandWidget.setReadOnly(True) soundPrefGrid.addWidget(self.playCommandWidget, n, 1) n = n+1 foo = self.playChooser.currentText() if foo != self.tr('custom'): self.playCommandLabel.hide() self.playCommandWidget.hide() #if alsaaudio is selected, provide device list chooser if self.parent().prm["appData"]["alsaaudioAvailable"] == True: self.alsaaudioPlaybackCardList = self.listAlsaaudioPlaybackCards() self.alsaaudioDeviceLabel = QLabel(self.tr('Device:')) soundPrefGrid.addWidget(self.alsaaudioDeviceLabel, n, 0) self.alsaaudioDeviceChooser = QComboBox() self.alsaaudioDeviceChooser.addItems(self.alsaaudioPlaybackCardList) self.alsaaudioDeviceChooser.setCurrentIndex(self.alsaaudioDeviceChooser.findText(self.tmpPref["pref"]["sound"]["alsaaudioDevice"])) soundPrefGrid.addWidget(self.alsaaudioDeviceChooser, n, 1) n = n+1 if self.tmpPref['pref']['sound']['playCommandType'] != "alsaaudio": self.alsaaudioDeviceLabel.hide() self.alsaaudioDeviceChooser.hide() #if pyaudio is selected, provide device list chooser if self.parent().prm["appData"]["pyaudioAvailable"] == True: self.listPyaudioPlaybackDevices() self.pyaudioDeviceLabel = QLabel(self.tr('Device:')) soundPrefGrid.addWidget(self.pyaudioDeviceLabel, n, 0) self.pyaudioDeviceChooser = QComboBox() self.pyaudioDeviceChooser.addItems(self.pyaudioDeviceListName) try: self.pyaudioDeviceChooser.setCurrentIndex(self.pyaudioDeviceListIdx.index(self.tmpPref["pref"]["sound"]["pyaudioDevice"])) except: self.tmpPref["pref"]["sound"]["pyaudioDevice"] = self.pyaudioDeviceListIdx[0] self.parent().prm["pref"]["sound"]["pyaudioDevice"] = self.pyaudioDeviceListIdx[0] self.pyaudioDeviceChooser.setCurrentIndex(self.pyaudioDeviceListIdx.index(self.tmpPref["pref"]["sound"]["pyaudioDevice"])) soundPrefGrid.addWidget(self.pyaudioDeviceChooser, n, 1) n = n+1 if self.tmpPref['pref']['sound']['playCommandType'] != "pyaudio": self.pyaudioDeviceLabel.hide() self.pyaudioDeviceChooser.hide() if self.parent().prm["appData"]["alsaaudioAvailable"] == True or self.parent().prm["appData"]["pyaudioAvailable"] == True: self.bufferSizeLabel = QLabel(self.tr('Buffer Size (samples):')) soundPrefGrid.addWidget(self.bufferSizeLabel, n, 0) self.bufferSizeWidget = QLineEdit(self.currLocale.toString(self.tmpPref["pref"]["sound"]["bufferSize"])) self.bufferSizeWidget.setValidator(QIntValidator(self)) soundPrefGrid.addWidget(self.bufferSizeWidget, n, 1) n = n+1 if self.tmpPref['pref']['sound']['playCommandType'] not in ["alsaaudio", "pyaudio"]: self.bufferSizeLabel.hide() self.bufferSizeWidget.hide() self.samplerateLabel = QLabel(self.tr('Default Sampling Rate:')) soundPrefGrid.addWidget(self.samplerateLabel, n, 0) self.samplerateWidget = QLineEdit(self.tmpPref["pref"]["sound"]["defaultSampleRate"]) #self.samplerateWidget.setValidator(QIntValidator(self)) soundPrefGrid.addWidget(self.samplerateWidget, n, 1) n = n+1 self.nbitsLabel = QLabel(self.tr('Default Bits:')) self.nbitsChooser = QComboBox() self.nbitsChooser.addItems(self.parent().prm["nBitsChoices"]) self.nbitsChooser.setCurrentIndex(self.parent().prm["nBitsChoices"].index(self.tmpPref["pref"]["sound"]["defaultNBits"])) soundPrefGrid.addWidget(self.nbitsLabel, n, 0) soundPrefGrid.addWidget(self.nbitsChooser, n, 1) n = n+1 self.wavmanagerLabel = QLabel(self.tr('Wav Manager (requires restart):')) self.wavmanagerChooser = QComboBox() self.wavmanagerChooser.addItems(self.parent().prm['appData']['wavmanagers']) self.wavmanagerChooser.setCurrentIndex(self.wavmanagerChooser.findText(self.tmpPref['pref']['sound']['wavmanager'])) soundPrefGrid.addWidget(self.wavmanagerLabel, n, 0) soundPrefGrid.addWidget(self.wavmanagerChooser, n, 1) n = n+1 self.writewav = QCheckBox(self.tr('Write wav file')) self.writewav.setChecked(self.tmpPref["pref"]["sound"]["writewav"]) soundPrefGrid.addWidget(self.writewav, n, 0) n = n+1 self.writeSndSeqSegments = QCheckBox(self.tr('Write sound sequence segments wavs')) self.writeSndSeqSegments.setChecked(self.tmpPref["pref"]["sound"]["writeSndSeqSegments"]) soundPrefGrid.addWidget(self.writeSndSeqSegments, n, 0) n = n+1 self.appendSilenceLabel = QLabel(self.tr('Append silence to each sound (ms):')) soundPrefGrid.addWidget(self.appendSilenceLabel, n, 0) self.appendSilenceWidget = QLineEdit(self.currLocale.toString(self.tmpPref["pref"]["sound"]["appendSilence"])) soundPrefGrid.addWidget(self.appendSilenceWidget, n, 1) n = n+1 self.soundPrefWidget.setLayout(soundPrefGrid) self.soundPrefWidget.layout().setSizeConstraint(QLayout.SetFixedSize) # NOTIFICATION PREF notificationPrefGrid = QGridLayout() n = 0 self.playEndMessage = QCheckBox(self.tr('Play End Message')) self.playEndMessage.setChecked(self.tmpPref["pref"]["general"]["playEndMessage"]) notificationPrefGrid.addWidget(self.playEndMessage, n, 0) self.endMessageButton = QPushButton(self.tr("Choose Wav"), self) self.endMessageButton.clicked.connect(self.onClickEndMessageButton) notificationPrefGrid.addWidget(self.endMessageButton, n, 1) n = n+1 notificationPrefGrid.addItem(QSpacerItem(20,20,QSizePolicy.Expanding), n, 0) n = n+1 self.nBlocksLabel = QLabel(self.tr('blocks before end of experiment:')) notificationPrefGrid.addWidget(self.nBlocksLabel, n, 1) self.nBlocksWidget = QLineEdit(self.currLocale.toString(self.tmpPref['pref']['email']['nBlocksNotify'])) notificationPrefGrid.addWidget(self.nBlocksWidget, n, 0) n = n+1 self.emailNotify = QCheckBox(self.tr('Send Notification e-mail')) self.emailNotify.setChecked(self.tmpPref["pref"]["email"]["notifyEnd"]) notificationPrefGrid.addWidget(self.emailNotify, n, 0) n = n+1 self.nBlocksCustomCommandLabel = QLabel(self.tr('Execute custom command:')) notificationPrefGrid.addWidget(self.nBlocksCustomCommandLabel, n, 0) self.nBlocksCustomCommandWidget = QLineEdit(self.tmpPref["pref"]["general"]["nBlocksCustomCommand"]) notificationPrefGrid.addWidget(self.nBlocksCustomCommandWidget, n, 1) n = n+1 notificationPrefGrid.addItem(QSpacerItem(20,20,QSizePolicy.Expanding), n, 0) n = n+1 self.atEndLabel = QLabel(self.tr('At the end of the experiment:')) notificationPrefGrid.addWidget(self.atEndLabel, n, 0) n = n+1 self.sendData = QCheckBox(self.tr('Send data via e-mail')) self.sendData.setChecked(self.tmpPref["pref"]["email"]["sendData"]) notificationPrefGrid.addWidget(self.sendData, n, 0) n = n+1 self.atEndCustomCommandLabel = QLabel(self.tr('Execute custom command:')) notificationPrefGrid.addWidget(self.atEndCustomCommandLabel, n, 0) self.atEndCustomCommandWidget = QLineEdit(self.tmpPref["pref"]["general"]["atEndCustomCommand"]) notificationPrefGrid.addWidget(self.atEndCustomCommandWidget, n, 1) n = n+1 notificationPrefGrid.addItem(QSpacerItem(20,20,QSizePolicy.Expanding), n, 0) n = n+1 self.serverLabel = QLabel(self.tr('Outgoing server (SMTP):')) notificationPrefGrid.addWidget(self.serverLabel, n, 0) self.serverWidget = QLineEdit(self.tmpPref['pref']['email']['SMTPServer']) notificationPrefGrid.addWidget(self.serverWidget, n, 1) n = n+1 self.serverPortLabel = QLabel(self.tr('Port:')) notificationPrefGrid.addWidget(self.serverPortLabel, n, 0) self.serverPortWidget = QLineEdit(self.currLocale.toString(self.tmpPref['pref']['email']['SMTPServerPort'])) self.serverPortWidget.setValidator(QIntValidator(self)) notificationPrefGrid.addWidget(self.serverPortWidget, n, 1) n = n+1 self.serverSecurityLabel = QLabel(self.tr('Security:')) notificationPrefGrid.addWidget(self.serverSecurityLabel, n, 0) self.serverSecurityChooser = QComboBox() self.serverSecurityChooser.addItems(["TLS/SSL (a)", "TLS/SSL (b)", "none"]) self.serverSecurityChooser.setCurrentIndex(self.serverSecurityChooser.findText(self.tmpPref['pref']['email']['SMTPServerSecurity'])) notificationPrefGrid.addWidget(self.serverSecurityChooser, n, 1) n = n+1 self.serverRequiresAuthCheckBox = QCheckBox(self.tr('Server requires authentication')) self.serverRequiresAuthCheckBox.setChecked(self.tmpPref["pref"]["email"]["serverRequiresAuthentication"]) notificationPrefGrid.addWidget(self.serverRequiresAuthCheckBox, n, 0, 1, 2) n = n+1 self.usernameLabel = QLabel(self.tr('Username:'******'pref']['email']['fromUsername']) notificationPrefGrid.addWidget(self.usernameWidget, n, 1) n = n+1 self.passwordLabel = QLabel(self.tr('Password:'******'pref']['email']['fromPassword']) self.passwordWidget.setEchoMode(QLineEdit.Password) notificationPrefGrid.addWidget(self.passwordWidget, n, 1) n = n+1 self.passwordWarningLabel = QLabel(self.tr('Password is NOT stored safely (see manual), use at your own risk!')) notificationPrefGrid.addWidget(self.passwordWarningLabel, n, 0, 1, 2) n = n+1 self.testEmailButton = QPushButton(self.tr("Send test e-mail"), self) self.testEmailButton.clicked.connect(self.onClickTestEmailButton) self.testEmailButton.setToolTip(self.tr("Send a test e-mail")) notificationPrefGrid.addWidget(self.testEmailButton, n, 0, 1, 2) self.notificationPrefWidget.setLayout(notificationPrefGrid) self.notificationPrefWidget.layout().setSizeConstraint(QLayout.SetFixedSize) ##--#--#--#--#-- # EEG PREF GRID eegPrefGrid = QGridLayout() n = 0 self.ONTriggerLabel = QLabel(self.tr('ON Trigger:')) eegPrefGrid.addWidget(self.ONTriggerLabel, n, 0) self.ONTriggerWidget = QLineEdit(self.currLocale.toString(self.tmpPref["pref"]["general"]["ONTrigger"])) eegPrefGrid.addWidget(self.ONTriggerWidget, n, 1) n = n+1 self.OFFTriggerLabel = QLabel(self.tr('OFF Trigger:')) eegPrefGrid.addWidget(self.OFFTriggerLabel, n, 0) self.OFFTriggerWidget = QLineEdit(self.currLocale.toString(self.tmpPref["pref"]["general"]["OFFTrigger"])) eegPrefGrid.addWidget(self.OFFTriggerWidget, n, 1) n = n+1 self.triggerDurLabel = QLabel(self.tr('Trigger Duration (ms):')) eegPrefGrid.addWidget(self.triggerDurLabel, n, 0) self.triggerDurWidget = QLineEdit(self.currLocale.toString(self.tmpPref["pref"]["general"]["triggerDur"])) eegPrefGrid.addWidget(self.triggerDurWidget, n, 1) self.eegPrefWidget.setLayout(eegPrefGrid) self.eegPrefWidget.layout().setSizeConstraint(QLayout.SetFixedSize) # ........................ self.tabWidget.addTab(self.appPrefWidget, self.tr("Genera&l")) self.tabWidget.addTab(self.soundPrefWidget, self.tr("Soun&d")) self.tabWidget.addTab(self.notificationPrefWidget, self.tr("Notification&s")) self.tabWidget.addTab(self.eegPrefWidget, self.tr("EE&G")) buttonBox = QDialogButtonBox(QDialogButtonBox.Apply|QDialogButtonBox.Ok|QDialogButtonBox.Cancel) buttonBox.accepted.connect(self.accept) buttonBox.rejected.connect(self.reject) buttonBox.button(QDialogButtonBox.Apply).clicked.connect(self.permanentApply) layout = QVBoxLayout() layout.addWidget(self.tabWidget) layout.addWidget(buttonBox) self.setLayout(layout) def onLanguageChooserChange(self): for i in range(self.countryChooser.count()): self.countryChooser.removeItem(0) self.countryChooser.addItems(self.parent().prm['appData']['available_countries'][self.languageChooser.currentText()]) def onResponseBoxLanguageChooserChange(self): for i in range(self.responseBoxCountryChooser.count()): self.responseBoxCountryChooser.removeItem(0) self.responseBoxCountryChooser.addItems(self.parent().prm['appData']['available_countries'][self.responseBoxLanguageChooser.currentText()]) def onPlayChooserChange(self): foo = self.playChooser.currentText() if foo != self.tr('custom'): self.playCommandLabel.hide() self.playCommandWidget.hide() self.playCommandWidget.setText(foo) self.playCommandWidget.setReadOnly(True) else: self.playCommandWidget.show() self.playCommandLabel.show() self.playCommandWidget.setReadOnly(False) if self.parent().prm["appData"]["alsaaudioAvailable"] == True: if foo == "alsaaudio": self.alsaaudioDeviceLabel.show() self.alsaaudioDeviceChooser.show() else: self.alsaaudioDeviceLabel.hide() self.alsaaudioDeviceChooser.hide() if self.parent().prm["appData"]["pyaudioAvailable"] == True: if foo == "pyaudio": self.pyaudioDeviceLabel.show() self.pyaudioDeviceChooser.show() else: self.pyaudioDeviceLabel.hide() self.pyaudioDeviceChooser.hide() if self.parent().prm["appData"]["alsaaudioAvailable"] == True or self.parent().prm["appData"]["pyaudioAvailable"] == True: if foo in ["alsaaudio", "pyaudio"]: self.bufferSizeLabel.show() self.bufferSizeWidget.show() else: self.bufferSizeLabel.hide() self.bufferSizeWidget.hide() def onClickEndMessageButton(self): dialog = wavListDialog(self) if dialog.exec_(): self.wavsList = dialog.wavsList self.wavsPref = {} self.wavsPref['endMessageFiles'] = [] self.wavsPref['endMessageFilesUse'] = [] self.wavsPref['endMessageFilesID'] = [] self.wavsPref['endMessageLevels'] = [] keys = sorted(self.wavsList.keys()) for key in keys: self.wavsPref['endMessageFiles'].append(str(self.wavsList[key]['file'])) self.wavsPref['endMessageFilesUse'].append(self.wavsList[key]['use']) self.wavsPref['endMessageLevels'].append(self.wavsList[key]['level']) self.wavsPref['endMessageFilesID'].append(key) def onClickTestEmailButton(self): self.mailer.sendTestEmail() def popMailerMessage(self, msg, msgtype): if msgtype == 'critical': QMessageBox.critical(self, self.tr("Error"), msg) elif msgtype == 'warning': QMessageBox.warning(self, self.tr("Warning"), msg) elif msgtype == 'information': QMessageBox.information(self, self.tr("Information"), msg) def tryApply(self): self.tmpPref['pref']['language'] = self.tr(self.languageChooser.currentText()) self.tmpPref['pref']['country'] = self.tr(self.countryChooser.currentText()) self.tmpPref['pref']['responseBoxLanguage'] = self.tr(self.responseBoxLanguageChooser.currentText()) self.tmpPref['pref']['responseBoxCountry'] = self.tr(self.responseBoxCountryChooser.currentText()) self.tmpPref['pref']['general']['csvSeparator'] = self.csvSeparatorWidget.text() self.tmpPref['pref']['general']['ONTrigger'] = self.currLocale.toInt(self.ONTriggerWidget.text())[0] self.tmpPref['pref']['general']['OFFTrigger'] = self.currLocale.toInt(self.OFFTriggerWidget.text())[0] self.tmpPref['pref']['general']['triggerDur'] = self.currLocale.toDouble(self.triggerDurWidget.text())[0] self.tmpPref['pref']['general']['maxRecursionDepth'] = self.currLocale.toInt(self.recursionLimitWidget.text())[0] self.tmpPref['pref']['general']['startupCommand'] = self.startupCommandWidget.text() self.tmpPref['pref']['sound']['playCommand'] = self.tr(self.playCommandWidget.text()) self.tmpPref['pref']['sound']['playCommandType'] = self.tr(self.playChooser.currentText()) if self.parent().prm["appData"]["alsaaudioAvailable"] == True: self.tmpPref['pref']['sound']['alsaaudioDevice'] = self.alsaaudioDeviceChooser.currentText() if self.parent().prm["appData"]["pyaudioAvailable"] == True: self.tmpPref['pref']['sound']['pyaudioDevice'] = self.pyaudioDeviceListIdx[self.pyaudioDeviceChooser.currentIndex()] self.tmpPref['pref']['sound']['wavmanager'] = str(self.wavmanagerChooser.currentText()) if self.parent().prm["appData"]["alsaaudioAvailable"] == True or self.parent().prm["appData"]["pyaudioAvailable"] == True: self.tmpPref['pref']['sound']['bufferSize'] = self.currLocale.toInt(self.bufferSizeWidget.text())[0] self.tmpPref['pref']['sound']['defaultSampleRate'] = self.samplerateWidget.text() self.tmpPref['pref']['sound']['defaultNBits'] = self.nbitsChooser.currentText() self.tmpPref['pref']['sound']['appendSilence'] = self.currLocale.toInt(self.appendSilenceWidget.text())[0] self.tmpPref["pref"]["email"]["nBlocksNotify"] = self.currLocale.toInt(self.nBlocksWidget.text())[0] self.tmpPref["pref"]["general"]["nBlocksCustomCommand"] = self.nBlocksCustomCommandWidget.text() self.tmpPref["pref"]["general"]["atEndCustomCommand"] = self.atEndCustomCommandWidget.text() self.tmpPref["pref"]["email"]['SMTPServer'] = self.serverWidget.text() self.tmpPref["pref"]["email"]['SMTPServerPort'] = self.currLocale.toInt(self.serverPortWidget.text())[0] self.tmpPref["pref"]["email"]['fromUsername'] = self.usernameWidget.text() self.tmpPref["pref"]["email"]['SMTPServerSecurity'] = self.serverSecurityChooser.currentText() self.tmpPref["pref"]["general"]["endMessageFiles"] = self.wavsPref['endMessageFiles'] self.tmpPref["pref"]["general"]["endMessageFilesUse"] = self.wavsPref['endMessageFilesUse'] self.tmpPref["pref"]["general"]["endMessageFilesID"] = self.wavsPref['endMessageFilesID'] self.tmpPref["pref"]["general"]["endMessageLevels"] = self.wavsPref['endMessageLevels'] self.tmpPref["pref"]["email"]['fromPassword'] = self.passwordWidget.text() if self.writewav.isChecked(): self.tmpPref['pref']['sound']['writewav'] = True else: self.tmpPref['pref']['sound']['writewav'] = False if self.writeSndSeqSegments.isChecked(): self.tmpPref['pref']['sound']['writeSndSeqSegments'] = True else: self.tmpPref['pref']['sound']['writeSndSeqSegments'] = False if self.dpCorrCheckBox.isChecked(): self.tmpPref['pref']['general']['dprimeCorrection'] = True else: self.tmpPref['pref']['general']['dprimeCorrection'] = False if self.listenerNameWarnCheckBox.isChecked(): self.tmpPref['pref']['general']['listenerNameWarn'] = True else: self.tmpPref['pref']['general']['listenerNameWarn'] = False if self.sessionLabelWarnCheckBox.isChecked(): self.tmpPref['pref']['general']['sessionLabelWarn'] = True else: self.tmpPref['pref']['general']['sessionLabelWarn'] = False if self.emailNotify.isChecked(): self.tmpPref['pref']['email']['notifyEnd'] = True else: self.tmpPref['pref']['email']['notifyEnd'] = False if self.sendData.isChecked(): self.tmpPref['pref']['email']['sendData'] = True else: self.tmpPref['pref']['email']['sendData'] = False if self.serverRequiresAuthCheckBox.isChecked(): self.tmpPref['pref']['email']['serverRequiresAuthentication'] = True else: self.tmpPref['pref']['email']['serverRequiresAuthentication'] = False if self.playEndMessage.isChecked(): self.tmpPref['pref']['general']['playEndMessage'] = True else: self.tmpPref['pref']['general']['playEndMessage'] = False if self.tmpPref['pref']['email']['notifyEnd'] == True or self.tmpPref['pref']['email']['sendData'] == True: if checkUsernameValid(self.tmpPref["pref"]["email"]['fromUsername']) == False: errMsg = self.tr("Username invalid. Disabling sending e-mails.") QMessageBox.warning(self, self.tr("Warning"), errMsg) self.emailNotify.setChecked(False) self.sendData.setChecked(False) self.tmpPref['pref']['email']['notifyEnd'] = False self.tmpPref['pref']['email']['sendData'] = False elif checkServerValid(self.tmpPref["pref"]["email"]['SMTPServer']) == False: errMsg = self.tr("SMTP server name invalid. Disabling sending e-mails.") QMessageBox.warning(self, self.tr("Warning"), errMsg) self.emailNotify.setChecked(False) self.sendData.setChecked(False) self.tmpPref['pref']['email']['notifyEnd'] = False self.tmpPref['pref']['email']['sendData'] = False def revertChanges(self): self.languageChooser.setCurrentIndex(self.languageChooser.findText(self.tmpPref['pref']['language'])) self.countryChooser.setCurrentIndex(self.countryChooser.findText(self.tmpPref['pref']['country'])) self.responseBoxLanguageChooser.setCurrentIndex(self.responseBoxLanguageChooser.findText(self.tmpPref['pref']['responseBoxLanguage'])) self.responseBoxCountryChooser.setCurrentIndex(self.responseBoxCountryChooser.findText(self.tmpPref['pref']['responseBoxCountry'])) self.csvSeparatorWidget.setText(self.tmpPref['pref']['general']['csvSeparator']) self.ONTriggerWidget.setText(self.currLocale.toString(self.tmpPref['pref']['general']['ONTrigger'])) self.OFFTriggerWidget.setText(self.currLocale.toString(self.tmpPref['pref']['general']['OFFTrigger'])) self.triggerDurWidget.setText(self.currLocale.toString(self.tmpPref['pref']['general']['triggerDur'])) self.recursionLimitWidget.setText(self.currLocale.toString(self.tmpPref['pref']['general']['maxRecursionDepth'])) self.startupCommandWidget.setText(self.tmpPref['pref']['general']['startupCommand']) self.playChooser.setCurrentIndex(self.playChooser.findText(self.tmpPref['pref']['sound']['playCommandType'])) if self.parent().prm["appData"]["alsaaudioAvailable"] == True: self.alsaaudioDeviceChooser.setCurrentIndex(self.alsaaudioDeviceChooser.findText(self.tmpPref['pref']['sound']['alsaaudioDevice'])) if self.parent().prm["appData"]["pyaudioAvailable"] == True: self.pyaudioDeviceChooser.setCurrentIndex(self.pyaudioDeviceListIdx.index(self.tmpPref['pref']['sound']['pyaudioDevice'])) self.wavmanagerChooser.setCurrentIndex(self.wavmanagerChooser.findText(self.tmpPref['pref']['sound']['wavmanager'])) self.playCommandWidget.setText(self.tmpPref['pref']['sound']['playCommand']) if self.parent().prm["appData"]["alsaaudioAvailable"] == True or self.parent().prm["appData"]["pyaudioAvailable"] == True: self.bufferSizeWidget.setText(self.currLocale.toString(self.tmpPref['pref']['sound']['bufferSize'])) self.samplerateWidget.setText(self.tmpPref['pref']['sound']['defaultSampleRate']) self.nbitsChooser.setCurrentIndex(self.nbitsChooser.findText(self.tmpPref['pref']['sound']['defaultNBits'])) self.appendSilenceWidget.setText(self.currLocale.toString(self.tmpPref['pref']['sound']['appendSilence'])) self.nBlocksWidget.setText(self.currLocale.toString(self.tmpPref['pref']['email']['nBlocksNotify'])) self.nBlocksCustomCommandWidget.setText( self.tmpPref["pref"]["general"]["nBlocksCustomCommand"]) self.atEndCustomCommandWidget.setText( self.tmpPref["pref"]["general"]["nBlocksCustomCommand"]) self.serverWidget.setText(self.tmpPref['pref']['email']['SMTPServer']) self.serverPortWidget.setText(self.currLocale.toString(self.tmpPref['pref']['email']['SMTPServerPort'])) self.usernameWidget.setText(self.tmpPref['pref']['email']['fromUsername']) self.passwordWidget.setText(self.tmpPref['pref']['email']['fromPassword']) self.serverSecurityChooser.setCurrentIndex(self.serverSecurityChooser.findText(self.tmpPref['pref']['email']['SMTPServerSecurity'])) self.wavsPref["endMessageFiles"] = self.tmpPref["pref"]["general"]["endMessageFiles"] self.wavsPref["endMessageFilesUse"] = self.tmpPref["pref"]["general"]["endMessageFilesUse"] self.wavsPref["endMessageFilesID"] = self.tmpPref["pref"]["general"]["endMessageFilesID"] self.wavsPref["endMessageLevels"] = self.tmpPref["pref"]["general"]["endMessageLevels"] if self.playChooser.currentText() != self.tr('custom'): self.playCommandWidget.setReadOnly(True) self.writewav.setChecked(self.tmpPref["pref"]["sound"]["writewav"]) self.writeSndSeqSegments.setChecked(self.tmpPref["pref"]["sound"]["writeSndSeqSegments"]) self.dpCorrCheckBox.setChecked(self.tmpPref["pref"]["general"]["dprimeCorrection"]) self.listenerNameWarnCheckBox.setChecked(self.tmpPref["pref"]["general"]["listenerNameWarn"]) self.sessionLabelWarnCheckBox.setChecked(self.tmpPref["pref"]["general"]["sessionLabelWarn"]) self.emailNotify.setChecked(self.tmpPref["pref"]["email"]["notifyEnd"]) self.sendData.setChecked(self.tmpPref["pref"]["email"]["sendData"]) self.serverRequiresAuthCheckBox.setChecked(self.tmpPref["pref"]["email"]["serverRequiresAuthentication"]) self.playEndMessage.setChecked(self.tmpPref["pref"]["general"]["playEndMessage"]) def permanentApply(self): self.tryApply() if self.parent().prm['pref']['email']['fromPassword'] != self.tmpPref['pref']['email']['fromPassword']: passwd = bytes(self.passwordWidget.text(),'utf-8') encoded_passwd = base64.b64encode(passwd) encoded_passwd = str(encoded_passwd, "utf-8") #passwd = hashlib.sha1(passwd).hexdigest() self.tmpPref["pref"]["email"]['fromPassword'] = encoded_passwd self.passwordWidget.setText(self.tmpPref['pref']['email']['fromPassword']) self.parent().prm['pref'] = copy.deepcopy(self.tmpPref['pref']) f = open(self.parent().prm['prefFile'], 'wb') pickle.dump(self.parent().prm['pref'], f) f.close() def tabChanged(self): self.tryApply() if self.tmpPref['pref'] != self.parent().prm['pref']: reply = QMessageBox.warning(self, self.tr("Warning"), self.tr('There are unsaved changes. Apply Changes?'), QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) if reply == QMessageBox.Yes: self.permanentApply() else: self.tmpPref['pref'] = copy.deepcopy(self.parent().prm['pref']) self.revertChanges() def listAlsaaudioPlaybackCards(self): playbackCardList = [] for card in alsaaudio.cards(): try: alsaaudio.PCM(type=alsaaudio.PCM_PLAYBACK, mode=alsaaudio.PCM_NORMAL, card=card) playbackCardList.append(card) except: pass return playbackCardList def listPyaudioPlaybackDevices(self): self.pyaudioHostApiListName = [] self.pyaudioHostApiListIdx = [] self.pyaudioDeviceListName = [] self.pyaudioDeviceListIdx = [] paManager = pyaudio.PyAudio() nDevices = paManager.get_device_count() nApi = paManager.get_host_api_count() for i in range(nApi): self.pyaudioHostApiListName.append(paManager.get_host_api_info_by_index(i)['name']) self.pyaudioHostApiListIdx.append(paManager.get_host_api_info_by_index(i)['index']) for i in range(nDevices): thisDevInfo = paManager.get_device_info_by_index(i) if thisDevInfo["maxOutputChannels"] > 0: self.pyaudioDeviceListName.append(thisDevInfo["name"] + ' - ' + self.pyaudioHostApiListName[thisDevInfo["hostApi"]]) self.pyaudioDeviceListIdx.append(thisDevInfo["index"]) return
class WidgetFFmpeg2theora(QDialog): def __init__(self, idCodec, cheminVideoEntre, cheminSorti, valeurNum=0, laisserOuvert=1, systeme=None, cheminFfmpeg2theora=None, tempsApercu=None, optionSpeciale=None, cheminMPlayer=None): """widget mplayer""" QDialog.__init__(self) #=== Paramètres généraux ===# self.systeme=systeme # système d'exploitation if self.systeme=='linux' or self.systeme=='darwin' or self.systeme==None: self.cheminFfmpeg2theora=u"ffmpeg2theora" elif self.systeme=='windows': self.cheminFfmpeg2theora=unicode(cheminFfmpeg2theora) # chemins vidéos self.cheminVideoEntre = unicode(cheminVideoEntre) self.cheminSorti = unicode(cheminSorti) # identifiant du codec self.idCodec = idCodec # valeur de la boite de spin pour l'encodage self.valeurNum = valeurNum # laisser ouvert la fenêtre après encodage self.laisserOuvert = laisserOuvert # Conversion minimale du filtre pour avoir un aperçu. # Indique le temps où l'aperçu doit être créé self.tempsApercu = tempsApercu # drapeau pour ne pas lancer 2 fois l'encodage self.estLancee = False # Est-ce que le 1er % de progression a été récupéré (utile pour montage vidéo -> découper)? self.__recupPourcentDebut = 0 self.log = [] # stocke les infos de mplayer et mencoder # Pour le son lors de la découpe vidéo pour l'instant if optionSpeciale!=None: self.optionSpeciale = optionSpeciale self.resize(500, 100) #=== Widgets ===# self.labelAttente=QLabel() self.labelAttente.setText(_(u"Attendez la fin du calcul s'il vous plaît, soyez patient !")) self.zoneTexte = QTextEdit("") # là où s'afficheront les infos if PYQT_VERSION_STR < "4.1.0": self.zoneTexte.setText = self.zoneTexte.setPlainText self.zoneTexte.setReadOnly(True) self.zoneTexte.hide() self.bout_annuler = QPushButton(_(u"Annuler")) self.bout_preZoneTexte = QPushButton(_("Voir les informations de l'encodage")) self.bout_preZoneTexte.hide() self.pbar = QProgressBar() self.pbar.setMaximum(100) #self.ffmpeg2theoraProcess = QProcess(self) self.ffmpeg2theoraProcess = FFmpeg2theora(cheminVideoEntre, cheminSorti, codec = idCodec) #=== mise-en-page/plan ===# vbox = QVBoxLayout() vbox.addWidget(self.labelAttente) vbox.addWidget(self.bout_preZoneTexte) vbox.addWidget(self.zoneTexte) hbox = QHBoxLayout() hbox.addWidget(self.pbar) hbox.addWidget(self.bout_annuler) vbox.addLayout(hbox) self.setLayout(vbox) #self.adjustSize() #=== connexion des widgets à des fonctions ===# # TEST # sert à calculer la durée d'exécution du script -> comparaison avec avec et sans traitement # des lignes de sortie de QProcess # 'readyReadStandardOutput()': signal émis lors de la sortie standart de lecture self.connect(self.ffmpeg2theoraProcess, SIGNAL('progress(int)'), self.pbar.setValue) self.connect(self.ffmpeg2theoraProcess, SIGNAL('log(QString)'), self.zoneTexte.append) self.connect(self.ffmpeg2theoraProcess, SIGNAL('finished(int)'), self.finEncodage) self.connect(self.bout_annuler, SIGNAL('clicked()'), self.close) self.connect(self.bout_preZoneTexte, SIGNAL('clicked()'), self.afficherLog) def close(self): """ Annule le traitement en cours """ self.ffmpeg2theoraProcess.cancel() self.ffmpeg2theoraProcess.wait() #super(WidgetFFmpeg, self).close() # Python 2.6 QDialog.close(self) def exec_(self): """ Surcharge de la fonction exec permettant l'execution hors de l'init""" self.demarrerEncodeur('Ffmpeg2theora') #super(WidgetFFmpeg, self).exec_() # Python 2.6 QDialog.exec_(self) def demarrerEncodeur(self, encodeur): """démarrage de mencoder avec les arguments choisis""" if self.estLancee == False: # pas question de démarrer 2 fois l'encodage infos = "\n########################\n" infos += "# Informations MPlayer :\n" infos += "########################\n" debug(infos) # Utilisation de la classe infovideo (et en particilier la fonction setVideo) # présents dans gui_modules_animation/infoVideo.py info = infovideo(self.cheminVideoEntre) id_filename = 'ID_FILENAME='+self.cheminVideoEntre+'\n' debug(id_filename) id_demuxer = 'ID_DEMUXER='+info.demux+'\n' debug(id_demuxer) id_video_format = 'ID_VIDEO_FORMAT='+info.videoFormat+'\n' debug(id_video_format) id_video_codec = 'ID_VIDEO_CODEC='+info.video_codec+'\n' debug(id_video_codec) id_video_bitrate = 'ID_VIDEO_BITRATE='+str(info.videoBitrate)+'\n' debug(id_video_bitrate) id_video_largeur = 'ID_VIDEO_WIDTH='+str(info.videoLargeur)+'\n' debug(id_video_largeur) id_video_hauteur = 'ID_VIDEO_HEIGHT='+str(info.videoHauteur)+'\n' debug(id_video_hauteur) id_img_par_sec = 'ID_VIDEO_FPS='+str(info.imgParSec)+'\n' debug(id_img_par_sec) ##### Donnée très importante pour la suite du calcul (pour ffmpeg.py et ffmpeg2theora) #### self.dureeTotaleVideo = float(info.dureeTotaleVideo) ########################################################################################### id_duree_totale_video = 'ID_LENGTH='+str(info.dureeTotaleVideo)+'\n' debug(id_duree_totale_video) id_audio_codec = 'ID_AUDIO_CODEC='+info.audioCodec+'\n' debug(id_audio_codec) id_audio_rate = 'ID_AUDIO_RATE='+str(info.audioRate)+'\n' debug(id_audio_rate) id_audio_bitrate = 'ID_AUDIO_BITRATE='+str(info.audioBitrate)+'\n' debug(id_audio_bitrate) self.log.append(infos+id_filename+id_demuxer+id_video_format+id_video_codec+id_video_bitrate+id_video_largeur+id_video_hauteur+id_img_par_sec+id_duree_totale_video+id_audio_codec+id_audio_rate+id_audio_bitrate) ############################################################################################## infos = "\n############################\n" infos += "# Informations %s :\n" % encodeur infos += "############################\n" debug(infos) self.log.append(infos) self.ffmpeg2theoraProcess.setVideoLen(self.dureeTotaleVideo) if encodeur == 'Ffmpeg2theora': # mode de canal: on fusionne le canal de sortie normal # (stdout) et celui des erreurs (stderr) self.ffmpeg2theoraProcess.setCommand(self.valeurNum) self.ffmpeg2theoraProcess.start() debug(u"Commande lancée") self.estLancee = True def finEncodage(self, statutDeSortie): """choses à faire à la fin de l'encodage de la vidéo""" # fermer la fenêtre à la fin de l'encodage if not self.laisserOuvert: self.close() debug("fini!") self.labelAttente.hide() self.pbar.setValue(100) # l'encodage est fini. Il ne peut plus être annulé. La # seule action possible devient ainsi la fermeture self.bout_annuler.setText(_(u"Fermer")) self.bout_preZoneTexte.show() def afficherLog(self): """afficher les information de la vidéo de départ et de l'encodage""" self.zoneTexte.setText(self.ffmpeg2theoraProcess.log) self.zoneTexte.show() self.resize(500, 300)
class Form(QDialog): def __init__(self, parent = None): super(Form, self).__init__(parent) self.ql = QLabel("URL:") self.le = QLineEdit() self.le.setObjectName("URL") self.ql1 = QLabel("Name of Anime:") self.le1 = QLineEdit() self.le1.setObjectName("Name") self.ql2 = QLabel("Episodes(From):") self.le2 = QLineEdit() self.le2.setObjectName("Episodes") self.ql6 = QLabel("Episodes(Till):") self.le6 = QLineEdit() self.le6.setObjectName("Episodes") self.ql3 = QLabel("Season:") self.le3 = QLineEdit() self.le3.setObjectName("Season") self.ql4 = QLabel("Quality( 1:-360p 2:-480p 3:-720p 4:-1080p ):") self.le4 = QLineEdit() self.le4.setObjectName("Quality") self.ql5 = QLabel("Category:") self.le5 = QLineEdit() self.le5.setObjectName("Category") self.ql7 = QLabel("--::It requires RapidVideo Server to be available for downloading::--") self.ql9 = QLabel("--::This project is in development phase, giving absurd values will lead to errors::--") self.ql10 = QLabel("--::To exit program completely please exit uGet as well as the application window::--") self.ql11 = QLabel("--::For any issues raise the issue on GitHub (link in README.md)::--") self.ql8 = QLabel("\n") self.pb = QPushButton() self.pb.setObjectName("Download") self.pb.setText("Download") layout = QFormLayout() layout.addWidget(self.ql1) layout.addWidget(self.le1) layout.addWidget(self.ql) layout.addWidget(self.le) layout.addWidget(self.ql3) layout.addWidget(self.le3) layout.addWidget(self.ql2) layout.addWidget(self.le2) layout.addWidget(self.ql6) layout.addWidget(self.le6) layout.addWidget(self.ql4) layout.addWidget(self.le4) layout.addWidget(self.ql5) layout.addWidget(self.le5) layout.addWidget(self.ql7) layout.addWidget(self.ql9) layout.addWidget(self.ql10) layout.addWidget(self.ql11) layout.addWidget(self.ql8) layout.addWidget(self.pb) self.setLayout(layout) self.connect(self.pb, SIGNAL("clicked()"),self.button_click) self.setWindowTitle("Anime Downloader") def button_click(self): url = self.le.text() anime = self.le1.text() episodes1 = self.le2.text() episodes2 = self.le6.text() season = self.le3.text() quality = self.le4.text() category = self.le5.text() self.le.hide() self.le1.hide() self.le2.hide() self.le3.hide() self.le4.hide() self.le5.hide() self.ql1.hide() self.ql2.hide() self.ql3.hide() self.ql4.hide() self.ql5.hide() self.ql6.hide() self.ql7.hide() self.ql8.hide() self.ql9.hide() self.ql10.hide() self.ql11.hide() self.ql.hide() self.pb.hide() self.le6.hide() filepath = os.path.realpath(__file__) filepath = filepath.replace('/src/anime_downloader.py','/res/') image_path=filepath fo = open(filepath + 'config.cfg','w') fo.write(category + '\n') fo.close() fo1 = open(filepath + 'links.txt','w') fo1.write(anime + '\n' + season + '\n' + episodes1 +'\n') fo1.close() fo2 = open(filepath + 'data.txt','w') fo2.write(url + '\n' + quality + '\n' + episodes1 + '\n' + episodes2 + '\n') fo2.close() filepath1 = filepath.replace('/res/','/src/') subprocess.call(['python','populate_links.py']) subprocess.call(['python','download_script.py']) self.setStyleSheet("border-image: url("+image_path+"bg_img.jpg); background-repeat: no-repeat;")
class RunDialog(QDialog): def __init__(self, run_model): QDialog.__init__(self) self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) self.setWindowFlags(self.windowFlags() & ~Qt.WindowCloseButtonHint) self.setModal(True) self.setWindowTitle("Simulations") assert isinstance(run_model, RunModelMixin) self.__run_model = run_model layout = QVBoxLayout() layout.setSizeConstraint(QLayout.SetFixedSize) self.simulations_tracker = SimulationsTracker() states = self.simulations_tracker.getList() self.total_progress = SimpleProgress() layout.addWidget(self.total_progress) status_layout = QHBoxLayout() status_layout.addStretch() self.__status_label = QLabel() status_layout.addWidget(self.__status_label) status_layout.addStretch() layout.addLayout(status_layout) self.progress = Progress() self.progress.setIndeterminateColor(self.total_progress.color) for state in states: self.progress.addState(state.state, QColor(*state.color), 100.0 * state.count / state.total_count) layout.addWidget(self.progress) legend_layout = QHBoxLayout() self.legends = {} for state in states: self.legends[state] = Legend("%s (%d/%d)", QColor(*state.color)) self.legends[state].updateLegend(state.name, 0, 0) legend_layout.addWidget(self.legends[state]) layout.addLayout(legend_layout) self.running_time = QLabel("") self.plot_tool = PlotTool() self.plot_tool.setParent(self) self.plot_button = QPushButton(self.plot_tool.getName()) self.plot_button.clicked.connect(self.plot_tool.trigger) self.kill_button = QPushButton("Kill simulations") self.done_button = QPushButton("Done") self.done_button.setHidden(True) button_layout = QHBoxLayout() size = 20 spin_movie = util.resourceMovie("ide/loading.gif") spin_movie.setSpeed(60) spin_movie.setScaledSize(QSize(size, size)) spin_movie.start() self.processing_animation = QLabel() self.processing_animation.setMaximumSize(QSize(size, size)) self.processing_animation.setMinimumSize(QSize(size, size)) self.processing_animation.setMovie(spin_movie) button_layout.addWidget(self.processing_animation) button_layout.addWidget(self.running_time) button_layout.addStretch() button_layout.addWidget(self.plot_button) button_layout.addWidget(self.kill_button) button_layout.addWidget(self.done_button) layout.addStretch() layout.addLayout(button_layout) self.setLayout(layout) self.kill_button.clicked.connect(self.killJobs) self.done_button.clicked.connect(self.accept) self.__updating = False self.__update_queued = False self.__simulation_started = False self.__update_timer = QTimer(self) self.__update_timer.setInterval(500) self.__update_timer.timeout.connect(self.updateRunStatus) def startSimulation(self): simulation_thread = Thread(name="ert_gui_simulation_thread") simulation_thread.setDaemon(True) simulation_thread.run = self.__run_model.startSimulations simulation_thread.start() self.__update_timer.start() def checkIfRunFinished(self): if self.__run_model.isFinished(): self.hideKillAndShowDone() if self.__run_model.hasRunFailed(): error = self.__run_model.getFailMessage() QMessageBox.critical(self, "Simulations failed!", "The simulation failed with the following error:\n\n%s" % error) self.reject() def updateRunStatus(self): self.checkIfRunFinished() self.total_progress.setProgress(self.__run_model.getProgress()) self.__status_label.setText(self.__run_model.getPhaseName()) states = self.simulations_tracker.getList() if self.__run_model.isIndeterminate(): self.progress.setIndeterminate(True) for state in states: self.legends[state].updateLegend(state.name, 0, 0) else: self.progress.setIndeterminate(False) total_count = self.__run_model.getQueueSize() queue_status = self.__run_model.getQueueStatus() for state in states: state.count = 0 state.total_count = total_count for state in states: for queue_state in queue_status: if queue_state in state.state: state.count += queue_status[queue_state] self.progress.updateState(state.state, 100.0 * state.count / state.total_count) self.legends[state].updateLegend(state.name, state.count, state.total_count) self.setRunningTime() def setRunningTime(self): days = 0 hours = 0 minutes = 0 seconds = self.__run_model.getRunningTime() if seconds >= 60: minutes, seconds = divmod(seconds, 60) if minutes >= 60: hours, minutes = divmod(minutes, 60) if hours >= 24: days, hours = divmod(hours, 24) if days > 0: self.running_time.setText("Running time: %d days %d hours %d minutes %d seconds" % (days, hours, minutes, seconds)) elif hours > 0: self.running_time.setText("Running time: %d hours %d minutes %d seconds" % (hours, minutes, seconds)) elif minutes > 0: self.running_time.setText("Running time: %d minutes %d seconds" % (minutes, seconds)) else: self.running_time.setText("Running time: %d seconds" % seconds) def killJobs(self): kill_job = QMessageBox.question(self, "Kill simulations?", "Are you sure you want to kill the currently running simulations?", QMessageBox.Yes | QMessageBox.No ) if kill_job == QMessageBox.Yes: self.__run_model.killAllSimulations() self.reject() def hideKillAndShowDone(self): self.__update_timer.stop() self.processing_animation.hide() self.kill_button.setHidden(True) self.done_button.setHidden(False)
class WSystem(QWidget, Logger.ClassLogger): """ System widget """ # action, description, misc, parameters AddStep = pyqtSignal(str, str, str, dict) UpdateStep = pyqtSignal(str, str, str, dict) CancelEdit = pyqtSignal() def __init__(self, parent): """ Constructor """ QWidget.__init__(self) self.createActions() self.createWidgets() self.createToolbar() self.createConnections() def createActions(self): """ Create qt actions """ self.addAction = QPushButton(QIcon(":/add_black.png"), '&Add Action', self) self.addAction.setMinimumHeight(40) self.addAction.setMaximumWidth(150) self.cancelAction = QtHelper.createAction(self, "&Cancel", self.cancelStep, icon=QIcon(":/undo.png"), tip='Cancel update') self.cancelAction.setEnabled(False) self.optionsAction = QtHelper.createAction( self, "&", self.openOptions, icon=QIcon(":/system-small.png"), tip='System options') def openOptions(self): """ Open options dialog """ if self.optionsDialog.exec_() == QDialog.Accepted: pass def createWidgets(self): """ Create qt widgets """ self.optionsDialog = OptionsDialog(self) self.validatorUpper = ValidatorUpper(self) self.validatorAll = ValidatorAll(self) self.validatorInt = QIntValidator(self) self.actionsComboBox = QComboBox(self) self.actionsComboBox.setMinimumHeight(40) for i in xrange(len(GuiSteps.ACTION_SYSTEM_DESCR)): if not len(GuiSteps.ACTION_SYSTEM_DESCR[i]): self.actionsComboBox.insertSeparator(i + 1) else: el = GuiSteps.ACTION_SYSTEM_DESCR[i].keys() self.actionsComboBox.addItem(list(el)[0]) self.labelActionDescr = QLabel(self) self.labelActionDescr.hide() self.descriptionLine = QLineEdit(self) self.descriptionLine.setPlaceholderText("Step purpose description") self.descriptionLine.hide() actionsLayout = QHBoxLayout() actionsLayout.addWidget(self.actionsComboBox) actionLayout1 = QGridLayout() actionLayout1.addLayout(actionsLayout, 0, 1) self.createWidgetSession() self.createWidgetText() self.createWidgetShortcut() self.createWidgetScreen() actionLayout2 = QGridLayout() actionLayout2.addWidget(self.sessionGroup, 1, 0) actionLayout2.addWidget(self.textGroup, 1, 0) actionLayout2.addWidget(self.shortcutGroup, 1, 0) actionLayout2.addWidget(self.screenGroup, 1, 0) font = QFont() font.setBold(True) labelAct = QLabel(self.tr("Action: ")) labelAct.setFont(font) self.arrowLabel = QLabel("") self.arrowLabel.setPixmap( QPixmap(":/arrow-right.png").scaledToWidth(32)) self.arrowLabel2 = QLabel("") self.arrowLabel2.setPixmap( QPixmap(":/arrow-right.png").scaledToWidth(32)) layoutFinal = QHBoxLayout() layoutFinal.addWidget(labelAct) layoutFinal.addLayout(actionLayout1) layoutFinal.addWidget(self.arrowLabel) layoutFinal.addLayout(actionLayout2) layoutFinal.addWidget(self.arrowLabel2) layoutFinal.addWidget(self.addAction) layoutFinal.addStretch(1) self.setLayout(layoutFinal) def createToolbar(self): """ Create toolbar """ pass def createWidgetScreen(self): """ Create screen widget """ self.screenGroup = QGroupBox(self.tr("")) # text self.checkComboBox = QComboBox(self) self.checkComboBox.addItems([ GuiSteps.OP_ANY, GuiSteps.OP_CONTAINS, GuiSteps.OP_NOTCONTAINS, GuiSteps.OP_REGEXP, GuiSteps.OP_NOTREGEXP, GuiSteps.OP_STARTSWITH, GuiSteps.OP_NOTSTARTSWITH, GuiSteps.OP_ENDSWITH, GuiSteps.OP_NOTENDSWITH ]) self.screenLine = QLineEdit(self) self.screenLine.setMinimumWidth(300) self.screenLine.setEnabled(False) self.screenLine.hide() self.screenArea = QTextEdit(self) self.screenArea.setMinimumWidth(300) self.screenArea.setEnabled(False) self.screenCombo = QComboBox(self) self.screenCombo.addItems(LIST_TYPES) self.screenCombo.setEnabled(False) self.screenSaveCombo = QComboBox(self) self.screenSaveCombo.addItems(["VARIABLE", "CACHE"]) self.screenSaveLine = QLineEdit(self) self.screenSaveLine.setMinimumWidth(300) self.screenSaveLine.setEnabled(False) mainTextlayout = QGridLayout() mainTextlayout.addWidget(QLabel(self.tr("Checking if the screen: ")), 0, 0) mainTextlayout.addWidget(self.checkComboBox, 0, 1) mainTextlayout.addWidget(QLabel(self.tr("The value:")), 1, 0) mainTextlayout.addWidget(self.screenCombo, 1, 1) mainTextlayout.addWidget(self.screenLine, 2, 1) mainTextlayout.addWidget(self.screenArea, 2, 1) mainTextlayout.addWidget(QLabel(self.tr("And save the screen in:")), 0, 2) mainTextlayout.addWidget(self.screenSaveCombo, 1, 2) mainTextlayout.addWidget(self.screenSaveLine, 2, 2) self.screenGroup.setLayout(mainTextlayout) self.screenGroup.hide() def createWidgetText(self): """ Create text widget """ self.textGroup = QGroupBox(self.tr("")) # text self.textLine = QLineEdit(self) self.textLine.setMinimumWidth(300) self.textCombo = QComboBox(self) self.textCombo.addItems(LIST_TYPES) mainTextlayout = QGridLayout() mainTextlayout.addWidget(QLabel(self.tr("Send the value:")), 0, 0) mainTextlayout.addWidget(self.textCombo, 0, 1) mainTextlayout.addWidget(self.textLine, 0, 2) self.textGroup.setLayout(mainTextlayout) self.textGroup.hide() def createWidgetShortcut(self): """ Create shortcut widget """ self.shortcutGroup = QGroupBox(self.tr("")) # text self.shortcutComboBox = QComboBox() self.shortcutComboBox.addItems([KEY_CTRLC, KEY_ENTER]) self.shortcutComboBox.setMinimumWidth(300) mainTextlayout = QGridLayout() mainTextlayout.addWidget(QLabel(self.tr("Shortcut:")), 0, 0) mainTextlayout.addWidget(self.shortcutComboBox, 0, 1) self.shortcutGroup.setLayout(mainTextlayout) self.shortcutGroup.hide() def createWidgetSession(self): """ Create session widget """ self.sessionGroup = QGroupBox(self.tr("")) # login self.loginLine = QLineEdit(self) self.loginLine.setMinimumWidth(300) self.loginCombo = QComboBox(self) self.loginCombo.addItems(LIST_TYPES) # password self.pwdLine = QLineEdit(self) self.pwdLine.setMinimumWidth(300) self.pwdCombo = QComboBox(self) self.pwdCombo.addItems(LIST_TYPES) # ip self.ipLine = QLineEdit(self) self.ipLine.setMinimumWidth(300) self.ipCombo = QComboBox(self) self.ipCombo.addItems(LIST_TYPES) # port self.portLine = QLineEdit(self) self.portLine.setMinimumWidth(300) self.portLine.setText("22") self.portLine.setValidator(self.validatorInt) self.portCombo = QComboBox(self) self.portCombo.addItems(LIST_TYPES) # agent support self.useAgent = QCheckBox("Use with agent mode") mainTextlayout = QGridLayout() mainTextlayout.addWidget(QLabel(self.tr("Host:")), 0, 0) mainTextlayout.addWidget(self.ipCombo, 0, 1) mainTextlayout.addWidget(self.ipLine, 0, 2) mainTextlayout.addWidget(QLabel(self.tr("Port (optional):")), 1, 0) mainTextlayout.addWidget(self.portCombo, 1, 1) mainTextlayout.addWidget(self.portLine, 1, 2) mainTextlayout.addWidget(QLabel(self.tr("Login:"******"Password:"******""" Create qt connections """ self.actionsComboBox.currentIndexChanged.connect(self.onActionChanged) self.addAction.clicked.connect(self.addStep) self.ipCombo.currentIndexChanged.connect(self.onIpTypeChanged) self.portCombo.currentIndexChanged.connect(self.onPortTypeChanged) self.loginCombo.currentIndexChanged.connect(self.onLoginTypeChanged) self.pwdCombo.currentIndexChanged.connect(self.onPwdTypeChanged) self.textCombo.currentIndexChanged.connect(self.onTextTypeChanged) self.screenCombo.currentIndexChanged.connect(self.onScreenTypeChanged) self.checkComboBox.currentIndexChanged.connect( self.onScreenOperatorChanged) self.screenSaveCombo.currentIndexChanged.connect( self.onScreenSaveChanged) def pluginDataAccessor(self): """ Return data to plugin """ return {"data": ""} def onPluginImport(self, dataJson): """ Received data from plugins """ if "steps" not in dataJson: QMessageBox.warning(self, "Assistant Automation", "bad import") return if not isinstance(dataJson['steps'], list): QMessageBox.warning(self, "Assistant Automation", "bad import") return if not ('ip' in dataJson and 'login' in dataJson and 'password' in dataJson): QMessageBox.warning(self, "Assistant Automation", "bad import") return # emit open session parameters = { 'dest-ip': dataJson['ip'], 'dest-port': 22, 'login': dataJson['login'], 'password': dataJson['password'], 'from-cache-ip': False, 'from-alias-ip': False, 'from-cache-port': False, 'from-alias-port': False, 'from-cache-login': False, 'from-alias-login': False, 'from-cache-pwd': False, 'from-alias-pwd': False, 'agent-support': False } self.AddStep.emit(GuiSteps.SYSTEM_SESSION, EMPTY_VALUE, EMPTY_VALUE, parameters) for stp in dataJson['steps']: if isinstance(stp, dict): # new in v16 fromCache = False fromAlias = False if "type-value" in stp: if stp["type-value"].lower() == "cache": fromCache = True if stp["type-value"].lower() == "alias": fromAlias = True # end of new if stp["action-name"] == "SEND": parameters = { 'text': stp["action-value"], 'from-cache': fromCache, 'from-alias': fromAlias } self.AddStep.emit(GuiSteps.SYSTEM_TEXT, EMPTY_VALUE, EMPTY_VALUE, parameters) elif stp["action-name"] == "EXPECT": op = "Contains" if stp["action-type"] == "REGEX": op = "RegEx" parameters = { 'value': stp["action-value"], 'from-cache': fromCache, 'from-alias': fromAlias, 'operator': op, 'to-cache': False, 'cache-key': '' } self.AddStep.emit(GuiSteps.SYSTEM_CHECK_SCREEN, EMPTY_VALUE, EMPTY_VALUE, parameters) else: QMessageBox.warning( self, "Assistant Automation", "action not yet supported: %s" % stp["action-name"]) # close self.AddStep.emit(GuiSteps.SYSTEM_CLOSE, EMPTY_VALUE, EMPTY_VALUE, {}) def onScreenOperatorChanged(self): """ On screen operator changed """ if self.checkComboBox.currentText() == GuiSteps.OP_ANY: self.screenLine.setEnabled(False) self.screenArea.setEnabled(False) self.screenCombo.setEnabled(False) else: self.screenLine.setEnabled(True) self.screenArea.setEnabled(True) self.screenCombo.setEnabled(True) def onScreenSaveChanged(self): """ On screen save changed """ if self.screenSaveCombo.currentText() == "VARIABLE": self.screenSaveLine.setEnabled(False) else: self.screenSaveLine.setEnabled(True) def onScreenTypeChanged(self): """ On screen type changed """ if self.screenCombo.currentText() in ["TEXT"]: self.screenArea.show() self.screenLine.hide() else: self.screenLine.show() self.screenArea.hide() if self.screenCombo.currentText() in ["CACHE"]: self.screenLine.setValidator(self.validatorAll) if self.screenCombo.currentText() == "ALIAS": self.screenLine.setText(self.screenLine.text().upper()) self.screenLine.setValidator(self.validatorUpper) def onTextTypeChanged(self): """ On text type changed """ if self.textCombo.currentText() in ["TEXT", "CACHE"]: self.textLine.setValidator(self.validatorAll) if self.textCombo.currentText() == "ALIAS": self.textLine.setText(self.textLine.text().upper()) self.textLine.setValidator(self.validatorUpper) def onLoginTypeChanged(self): """ On login type changed """ if self.loginCombo.currentText() in ["TEXT", "CACHE"]: self.loginLine.setValidator(self.validatorAll) if self.loginCombo.currentText() == "ALIAS": self.loginLine.setText(self.loginLine.text().upper()) self.loginLine.setValidator(self.validatorUpper) def onPwdTypeChanged(self): """ On password type changed """ if self.pwdCombo.currentText() in ["TEXT", "CACHE"]: self.pwdLine.setValidator(self.validatorAll) if self.pwdCombo.currentText() == "ALIAS": self.pwdLine.setText(self.pwdLine.text().upper()) self.pwdLine.setValidator(self.validatorUpper) def onIpTypeChanged(self): """ On ip type changed """ if self.ipCombo.currentText() in ["TEXT", "CACHE"]: self.ipLine.setValidator(self.validatorAll) if self.ipCombo.currentText() == "ALIAS": self.ipLine.setText(self.ipLine.text().upper()) self.ipLine.setValidator(self.validatorUpper) def onPortTypeChanged(self): """ On port type changed """ if self.portCombo.currentText() in ["TEXT"]: self.portLine.setText("22") self.portLine.setValidator(self.validatorInt) if self.portCombo.currentText() in ["CACHE"]: self.portLine.setValidator(self.validatorAll) if self.portCombo.currentText() == "ALIAS": self.portLine.setText(self.portLine.text().upper()) self.portLine.setValidator(self.validatorUpper) def onActionChanged(self): """ On action changed """ descr = 'No description available!' i = 0 for el in GuiSteps.ACTION_SYSTEM_DESCR: if isinstance(el, dict): if self.actionsComboBox.currentText() in el: descr = GuiSteps.ACTION_SYSTEM_DESCR[i][ self.actionsComboBox.currentText()] break i += 1 self.labelActionDescr.setText("%s\n" % descr) if self.actionsComboBox.currentText() in [GuiSteps.SYSTEM_SESSION]: self.sessionGroup.show() self.textGroup.hide() self.shortcutGroup.hide() self.screenGroup.hide() self.arrowLabel.show() self.arrowLabel2.show() elif self.actionsComboBox.currentText() in [GuiSteps.SYSTEM_CLOSE]: self.sessionGroup.hide() self.textGroup.hide() self.shortcutGroup.hide() self.screenGroup.hide() self.arrowLabel.hide() self.arrowLabel2.show() elif self.actionsComboBox.currentText() in [ GuiSteps.SYSTEM_CLEAR_SCREEN ]: self.sessionGroup.hide() self.textGroup.hide() self.shortcutGroup.hide() self.screenGroup.hide() self.arrowLabel.hide() self.arrowLabel2.show() elif self.actionsComboBox.currentText() in [GuiSteps.SYSTEM_TEXT]: self.sessionGroup.hide() self.textGroup.show() self.shortcutGroup.hide() self.screenGroup.hide() self.arrowLabel.show() self.arrowLabel2.show() elif self.actionsComboBox.currentText() in [GuiSteps.SYSTEM_SHORTCUT]: self.sessionGroup.hide() self.textGroup.hide() self.shortcutGroup.show() self.screenGroup.hide() self.arrowLabel.show() self.arrowLabel2.show() elif self.actionsComboBox.currentText() in [ GuiSteps.SYSTEM_CHECK_SCREEN ]: self.sessionGroup.hide() self.textGroup.hide() self.shortcutGroup.hide() self.screenGroup.show() self.arrowLabel.show() self.arrowLabel2.show() else: self.sessionGroup.hide() self.textGroup.hide() self.shortcutGroup.hide() self.screenGroup.hide() self.arrowLabel.hide() self.arrowLabel2.hide() def addStep(self): """ Add step """ action = self.actionsComboBox.currentText() descr = self.descriptionLine.text() descr = unicode(descr).replace('"', '') signal = self.AddStep if self.cancelAction.isEnabled(): signal = self.UpdateStep if action in [GuiSteps.SYSTEM_SESSION]: fromCacheIp = False if self.ipCombo.currentText() == "CACHE": fromCacheIp = True fromAliasIp = False if self.ipCombo.currentText() == "ALIAS": fromAliasIp = True fromCachePort = False if self.portCombo.currentText() == "CACHE": fromCachePort = True fromAliasPort = False if self.portCombo.currentText() == "ALIAS": fromAliasPort = True fromCacheLogin = False if self.loginCombo.currentText() == "CACHE": fromCacheLogin = True fromAliasLogin = False if self.loginCombo.currentText() == "ALIAS": fromAliasLogin = True fromCachePwd = False if self.pwdCombo.currentText() == "CACHE": fromCachePwd = True fromAliasPwd = False if self.pwdCombo.currentText() == "ALIAS": fromAliasPwd = True newIp = self.ipLine.text() if not len(newIp): QMessageBox.warning(self, "Assistant", "Please to provide a ip!") return newPort = self.portLine.text() if not len(newPort): QMessageBox.warning(self, "Assistant", "Please to provide a port!") return newLogin = self.loginLine.text() if not len(newLogin): QMessageBox.warning(self, "Assistant", "Please to provide a login!") return newPwd = self.pwdLine.text() agentSupport = "False" if self.useAgent.isChecked(): agentSupport = "True" parameters = { 'dest-ip': newIp, 'dest-port': newPort, 'login': newLogin, 'password': newPwd, 'from-cache-ip': fromCacheIp, 'from-alias-ip': fromAliasIp, 'from-cache-port': fromCachePort, 'from-alias-port': fromAliasPort, 'from-cache-login': fromCacheLogin, 'from-alias-login': fromAliasLogin, 'from-cache-pwd': fromCachePwd, 'from-alias-pwd': fromAliasPwd, 'agent-support': agentSupport } signal.emit(str(action), unicode(descr), EMPTY_VALUE, parameters) elif action in [GuiSteps.SYSTEM_CLOSE]: signal.emit(str(action), unicode(descr), EMPTY_VALUE, {}) elif action in [GuiSteps.SYSTEM_CLEAR_SCREEN]: signal.emit(str(action), unicode(descr), EMPTY_VALUE, {}) elif action in [GuiSteps.SYSTEM_TEXT]: fromCache = False if self.textCombo.currentText() == "CACHE": fromCache = True fromAlias = False if self.textCombo.currentText() == "ALIAS": fromAlias = True newText = self.textLine.text() if not len(newText): QMessageBox.warning(self, "Assistant", "Please to provide text!") return parameters = { 'text': newText, 'from-cache': fromCache, 'from-alias': fromAlias } signal.emit(str(action), unicode(descr), EMPTY_VALUE, parameters) elif action in [GuiSteps.SYSTEM_SHORTCUT]: newShortcut = self.shortcutComboBox.currentText() parameters = {'shortcut': newShortcut} signal.emit(str(action), unicode(descr), EMPTY_VALUE, parameters) elif action in [GuiSteps.SYSTEM_CHECK_SCREEN]: op = self.checkComboBox.currentText() fromCache = False if self.screenCombo.currentText() == "CACHE": fromCache = True fromAlias = False if self.screenCombo.currentText() == "ALIAS": fromAlias = True toCache = False if self.screenSaveCombo.currentText() == "CACHE": toCache = True keyCache = self.screenSaveLine.text() newText = "" if op != GuiSteps.OP_ANY: if fromCache or fromAlias: newText = self.screenLine.text() else: newText = self.screenArea.toPlainText() if not len(newText): QMessageBox.warning(self, "Assistant", "Please to provide value to search!") return parameters = { 'value': newText, 'from-cache': fromCache, 'from-alias': fromAlias, 'operator': op, 'to-cache': toCache, 'cache-key': keyCache } signal.emit(str(action), unicode(descr), EMPTY_VALUE, parameters) else: signal.emit(str(action), unicode(descr), EMPTY_VALUE, {}) def cancelStep(self): """ Cancel step """ self.addAction.setText("&Add") buttonFont = QFont() buttonFont.setBold(False) self.addAction.setFont(buttonFont) self.cancelAction.setEnabled(False) self.CancelEdit.emit() def finalizeUpdate(self): """ Finalize the update of the step """ self.addAction.setText("&Add Action") buttonFont = QFont() buttonFont.setBold(False) self.addAction.setFont(buttonFont) self.cancelAction.setEnabled(False) def editStep(self, stepData): """ Edit step """ self.addAction.setText("&Update") buttonFont = QFont() buttonFont.setBold(True) self.addAction.setFont(buttonFont) self.cancelAction.setEnabled(True) # set the current value for actions combo for i in xrange(self.actionsComboBox.count()): item_text = self.actionsComboBox.itemText(i) if unicode(stepData["action"]) == unicode(item_text): self.actionsComboBox.setCurrentIndex(i) break # and then refresh options self.onActionChanged() # finally fill all fields self.descriptionLine.setText(stepData["description"]) if self.actionsComboBox.currentText() in [GuiSteps.SYSTEM_SESSION]: self.ipLine.setText(stepData["parameters"]["dest-ip"]) self.portLine.setText("%s" % stepData["parameters"]["dest-port"]) self.loginLine.setText(stepData["parameters"]["login"]) self.pwdLine.setText(stepData["parameters"]["password"]) if stepData["parameters"]["from-cache-ip"]: self.ipLine.setValidator(self.validatorAll) self.ipCombo.setCurrentIndex(INDEX_CACHE) elif stepData["parameters"]["from-alias-ip"]: self.ipLine.setValidator(self.validatorUpper) self.ipCombo.setCurrentIndex(INDEX_ALIAS) else: self.ipLine.setValidator(self.validatorAll) self.ipCombo.setCurrentIndex(INDEX_TEXT) if stepData["parameters"]["from-cache-port"]: self.portLine.setValidator(self.validatorAll) self.portCombo.setCurrentIndex(INDEX_CACHE) elif stepData["parameters"]["from-alias-port"]: self.portLine.setValidator(self.validatorUpper) self.portCombo.setCurrentIndex(INDEX_ALIAS) else: self.portLine.setValidator(self.validatorInt) self.portCombo.setCurrentIndex(INDEX_TEXT) if stepData["parameters"]["from-cache-login"]: self.loginLine.setValidator(self.validatorAll) self.loginCombo.setCurrentIndex(INDEX_CACHE) elif stepData["parameters"]["from-alias-login"]: self.loginLine.setValidator(self.validatorUpper) self.loginCombo.setCurrentIndex(INDEX_ALIAS) else: self.loginLine.setValidator(self.validatorAll) self.loginCombo.setCurrentIndex(INDEX_TEXT) if stepData["parameters"]["from-cache-pwd"]: self.pwdLine.setValidator(self.validatorAll) self.pwdCombo.setCurrentIndex(INDEX_CACHE) elif stepData["parameters"]["from-alias-pwd"]: self.pwdLine.setValidator(self.validatorUpper) self.pwdCombo.setCurrentIndex(INDEX_ALIAS) else: self.pwdLine.setValidator(self.validatorAll) self.pwdCombo.setCurrentIndex(INDEX_TEXT) if self.actionsComboBox.currentText() in [GuiSteps.SYSTEM_CLOSE]: pass if self.actionsComboBox.currentText() in [ GuiSteps.SYSTEM_CLEAR_SCREEN ]: pass if self.actionsComboBox.currentText() in [GuiSteps.SYSTEM_TEXT]: if stepData["parameters"]["from-cache"]: self.textLine.setValidator(self.validatorAll) self.textCombo.setCurrentIndex(INDEX_CACHE) elif stepData["parameters"]["from-alias"]: self.textLine.setValidator(self.validatorUpper) self.textCombo.setCurrentIndex(INDEX_ALIAS) else: self.textLine.setValidator(self.validatorAll) self.textCombo.setCurrentIndex(INDEX_TEXT) self.textLine.setText(stepData["parameters"]["text"]) if self.actionsComboBox.currentText() in [GuiSteps.SYSTEM_SHORTCUT]: for i in xrange(self.shortcutComboBox.count()): item_text = self.shortcutComboBox.itemText(i) if unicode(stepData["parameters"]["shortcut"]) == unicode( item_text): self.shortcutComboBox.setCurrentIndex(i) break if self.actionsComboBox.currentText() in [ GuiSteps.SYSTEM_CHECK_SCREEN ]: if stepData["parameters"]["from-cache"]: self.screenLine.setValidator(self.validatorAll) self.screenCombo.setCurrentIndex(INDEX_CACHE) self.screenLine.setText(stepData["parameters"]["value"]) elif stepData["parameters"]["from-alias"]: self.screenLine.setValidator(self.validatorUpper) self.screenCombo.setCurrentIndex(INDEX_ALIAS) self.screenLine.setText(stepData["parameters"]["value"]) else: self.screenCombo.setCurrentIndex(INDEX_TEXT) self.screenArea.setPlainText(stepData["parameters"]["value"]) for i in xrange(self.checkComboBox.count()): item_text = self.checkComboBox.itemText(i) if unicode(stepData["parameters"]["operator"]) == unicode( item_text): self.checkComboBox.setCurrentIndex(i) break if stepData["parameters"]["to-cache"]: self.screenSaveCombo.setCurrentIndex(1) self.screenSaveLine.setText( stepData["parameters"]["cache-key"]) else: self.screenSaveCombo.setCurrentIndex(0) def getTimeout(self): """ Return timeout value """ return self.optionsDialog.timeoutLine.text() def setTimeout(self, timeout): """ Set the timeout """ return self.optionsDialog.timeoutLine.setText(timeout) def getAgentName(self): """ Return the agent name """ return self.optionsDialog.agentNameLine.text() def getAgentList(self): """ Return the agent list """ return self.optionsDialog.agentsList
class WAndroid(QWidget, Logger.ClassLogger): """ Android widget """ # action, description, misc, parameters AddStep = pyqtSignal(str, str, str, dict) UpdateStep = pyqtSignal(str, str, str, dict) CancelEdit = pyqtSignal() def __init__(self, parent): """ Constructor """ QWidget.__init__(self) self.createActions() self.createWidgets() self.createToolbar() self.createConnections() def createActions(self): """ Create qt actions """ self.addAndroidAction = QPushButton(QIcon(":/add_black.png"), '&Add Action', self) self.addAndroidAction.setMinimumHeight(40) self.addAndroidAction.setMaximumWidth(150) self.cancelAndroidAction = QtHelper.createAction(self, "&Cancel", self.cancelStep, icon=None, tip = 'Cancel update') self.cancelAndroidAction.setEnabled(False) self.optionsAction = QtHelper.createAction(self, "&", self.openOptions, icon=QIcon(":/recorder-mobile-small.png"), tip = 'Android options') def createWidgets(self): """ Create qt widgets """ self.optionsDialog = OptionsDialog(self) self.validatorUpper = ValidatorUpper(self) self.validatorAll = ValidatorAll(self) self.validatorInt = QIntValidator(self) ###################### android action ######################### self.actionsAndroidComboBox = QComboBox(self) self.actionsAndroidComboBox.setMinimumHeight(40) for i in xrange(len(GuiSteps.ACTION_ANDROID_DESCR)): if not len( GuiSteps.ACTION_ANDROID_DESCR[i] ): self.actionsAndroidComboBox.insertSeparator(i+1) else: el = GuiSteps.ACTION_ANDROID_DESCR[i].keys() self.actionsAndroidComboBox.addItem( list(el)[0] ) self.descriptionAndroidLine = QLineEdit(self) self.descriptionAndroidLine.setPlaceholderText("Step purpose description") self.descriptionAndroidLine.hide() self.labelActionAndroidDescr = QLabel( ) self.labelActionAndroidDescr.hide() self.labelActionAndroidDescr.setText( "%s\n" % GuiSteps.ACTION_ANDROID_DESCR[0][GuiSteps.ANDROID_WAKEUP_UNLOCK]) self.labelActionAndroidDescr.setWordWrap(True) actionsLayout = QHBoxLayout() actionsLayout.addWidget(self.actionsAndroidComboBox) actionLayoutAndroid = QGridLayout() actionLayoutAndroid.addLayout(actionsLayout, 0, 1) self.createWidgetShortcut() self.createWidgetCode() self.createWidgetStart() self.createWidgetXY() self.createWidgetEndXY() self.createWidgetElement() self.createWidgetTextTo() self.createWidgetLine() self.createWidgetLine2() actionLayoutAndroid2 = QGridLayout() actionLayoutAndroid2.addWidget( self.shortcutAndroidGroup , 0, 0) actionLayoutAndroid2.addWidget( self.codeAndroidGroup , 0, 0) actionLayoutAndroid2.addWidget( self.elemenAndroidGroup , 0, 0) actionLayoutAndroid2.addWidget( self.xyAndroidGroup , 0, 0) actionLayoutAndroid2.addWidget( self.startAndroidGroup , 0, 0) actionLayoutAndroid2.addWidget( self.lineAndroidGroup , 1, 0) actionLayoutAndroid2.addWidget( self.line2AndroidGroup , 0, 1) actionLayoutAndroid2.addWidget( self.textToGlobalGroup , 0, 1) actionLayoutAndroid2.addWidget( self.endXyAndroidGroup, 0, 1) font = QFont() font.setBold(True) labelAct = QLabel( self.tr("Action: ") ) labelAct.setFont( font) self.arrowLabel = QLabel("") self.arrowLabel.setPixmap(QPixmap(":/arrow-right.png").scaledToWidth(32)) self.arrowLabel.hide() self.arrowLabel2 = QLabel("") self.arrowLabel2.setPixmap(QPixmap(":/arrow-right.png").scaledToWidth(32)) layoutAndroid = QHBoxLayout() layoutAndroid.addWidget( labelAct ) layoutAndroid.addLayout( actionLayoutAndroid ) layoutAndroid.addWidget( self.arrowLabel ) layoutAndroid.addLayout( actionLayoutAndroid2 ) layoutAndroid.addWidget( self.arrowLabel2 ) layoutAndroid.addWidget(self.addAndroidAction) layoutAndroid.addStretch(1) self.setLayout(layoutAndroid) def createToolbar(self): """ Create qt toolbar """ pass def openOptions(self): """ Open options """ if self.optionsDialog.exec_() == QDialog.Accepted: pass def createWidgetLine2(self): """ Create line widget """ self.valueAndroidLine2 = QLineEdit(self) self.valueAndroidLine2.setMinimumWidth(150) self.valueAndroidCombo2 = QComboBox(self) self.valueAndroidCombo2.addItems( LIST_TYPES ) self.line2AndroidGroup = QGroupBox(self.tr("")) line2Androidlayout = QGridLayout() line2Androidlayout.addWidget( QLabel( self.tr("Text to type:") ), 0, 0 ) line2Androidlayout.addWidget( self.valueAndroidCombo2, 0, 1 ) line2Androidlayout.addWidget( self.valueAndroidLine2, 0, 2 ) self.line2AndroidGroup.setLayout(line2Androidlayout) self.line2AndroidGroup.hide() def createWidgetLine(self): """ Create line widget """ self.lineAndroidGroup = QGroupBox(self.tr("")) lineAndroidlayout = QGridLayout() self.valueAndroidLine = QLineEdit(self) self.valueAndroidLine.setMinimumWidth(300) lineAndroidlayout.addWidget( QLabel( self.tr("Value:") ) , 0,1) lineAndroidlayout.addWidget( self.valueAndroidLine , 0, 2) self.lineAndroidGroup.setLayout(lineAndroidlayout) self.lineAndroidGroup.hide() def createWidgetTextTo(self): """ Create text widget """ self.valueTextCacheGlobalLine = QLineEdit(self) self.valueTextCacheGlobalLine.setMinimumWidth(150) self.valueTextCacheGlobalCombo = QComboBox(self) self.valueTextCacheGlobalCombo.addItems( ["CACHE"] ) self.textToGlobalGroup = QGroupBox(self.tr("")) textToGloballayout = QGridLayout() textToGloballayout.addWidget( QLabel( self.tr("Save text in:") ) , 0, 0) textToGloballayout.addWidget( self.valueTextCacheGlobalCombo , 0, 1) textToGloballayout.addWidget( self.valueTextCacheGlobalLine , 0, 2) self.textToGlobalGroup.setLayout(textToGloballayout) self.textToGlobalGroup.hide() def createWidgetElement(self): """ Create text widget """ self.elemenAndroidGroup = QGroupBox(self.tr("")) self.elementTextAndroidLine = QLineEdit(self) self.elementTextAndroidLine.setMinimumWidth(300) self.elementTextCombo = QComboBox(self) self.elementTextCombo.addItems( LIST_TYPES ) self.elementDescriptionAndroidLine = QLineEdit(self) self.elementDescriptionAndroidLine.setMinimumWidth(300) self.elementClassAndroidLine = QLineEdit(self) self.elementClassAndroidLine.setMinimumWidth(300) self.elementRessourceIdAndroidLine = QLineEdit(self) self.elementRessourceIdAndroidLine.setMinimumWidth(300) self.elementPackageAndroidLine = QLineEdit(self) self.elementPackageAndroidLine.setMinimumWidth(300) # get text end elementAndroidlayout = QGridLayout() elementAndroidlayout.addWidget( QLabel( self.tr("Text Element:") ) , 0,1) elementAndroidlayout.addWidget( self.elementTextCombo , 0, 2) elementAndroidlayout.addWidget( self.elementTextAndroidLine , 0, 3) elementAndroidlayout.addWidget( QLabel( self.tr("Description Element:") ) , 1,1) elementAndroidlayout.addWidget( self.elementDescriptionAndroidLine , 1, 3) elementAndroidlayout.addWidget( QLabel( self.tr("Class Name:") ) , 2,1) elementAndroidlayout.addWidget( self.elementClassAndroidLine , 2, 3) elementAndroidlayout.addWidget( QLabel( self.tr("Resource ID:") ) , 3,1) elementAndroidlayout.addWidget( self.elementRessourceIdAndroidLine , 3, 3) elementAndroidlayout.addWidget( QLabel( self.tr("Package Name:") ) , 4,1) elementAndroidlayout.addWidget( self.elementPackageAndroidLine , 4, 3) self.elemenAndroidGroup.setLayout(elementAndroidlayout) self.elemenAndroidGroup.hide() def createWidgetEndXY(self): """ Create widget """ self.endXyAndroidGroup = QGroupBox(self.tr("")) endXyAndroidlayout = QGridLayout() self.endxAndroidLine = QLineEdit(self) validatorEndXAndroid = QIntValidator (self) self.endxAndroidLine.setValidator(validatorEndXAndroid) self.endxAndroidLine.installEventFilter(self) self.endyAndroidLine = QLineEdit(self) validatorEndYAndroid = QIntValidator (self) self.endyAndroidLine.setValidator(validatorEndYAndroid) self.endyAndroidLine.installEventFilter(self) endXyAndroidlayout.addWidget( QLabel( self.tr("Destination Coordinate X:") ) , 0, 0) endXyAndroidlayout.addWidget( self.endxAndroidLine , 0, 1) endXyAndroidlayout.addWidget( QLabel( self.tr("Destination Coordinate Y:") ) , 1,0) endXyAndroidlayout.addWidget( self.endyAndroidLine , 1, 1) self.endXyAndroidGroup.setLayout(endXyAndroidlayout) self.endXyAndroidGroup.hide() def createWidgetXY(self): """ Create text widget """ self.xyAndroidGroup = QGroupBox(self.tr("")) xyAndroidlayout = QGridLayout() self.xAndroidLine = QLineEdit(self) validatorXAndroid = QIntValidator (self) self.xAndroidLine.setValidator(validatorXAndroid) self.xAndroidLine.installEventFilter(self) self.yAndroidLine = QLineEdit(self) validatorYAndroid = QIntValidator (self) self.yAndroidLine.setValidator(validatorYAndroid) self.yAndroidLine.installEventFilter(self) xyAndroidlayout.addWidget( QLabel( self.tr("Coordinate X:") ) , 0,0) xyAndroidlayout.addWidget( self.xAndroidLine , 0, 1) xyAndroidlayout.addWidget( QLabel( self.tr("Coordinate Y:") ) , 1,0) xyAndroidlayout.addWidget( self.yAndroidLine , 1, 1) self.xyAndroidGroup.setLayout(xyAndroidlayout) self.xyAndroidGroup.hide() def createWidgetStart(self): """ Create text widget """ self.startAndroidGroup = QGroupBox(self.tr("")) startAndroidlayout = QGridLayout() self.startXAndroidLine = QLineEdit(self) validatorStartXAndroid = QIntValidator (self) self.startXAndroidLine.setValidator(validatorStartXAndroid) self.startXAndroidLine.installEventFilter(self) self.startYAndroidLine = QLineEdit(self) validatorStartYAndroid = QIntValidator (self) self.startYAndroidLine.setValidator(validatorStartYAndroid) self.startYAndroidLine.installEventFilter(self) self.stopXAndroidLine = QLineEdit(self) validatorStopXAndroid = QIntValidator (self) self.stopXAndroidLine.setValidator(validatorStopXAndroid) self.stopXAndroidLine.installEventFilter(self) self.stopYAndroidLine = QLineEdit(self) validatorStopYAndroid = QIntValidator (self) self.stopYAndroidLine.setValidator(validatorStopYAndroid) self.stopYAndroidLine.installEventFilter(self) startAndroidlayout.addWidget( QLabel( self.tr("From X:") ) , 0,1) startAndroidlayout.addWidget( self.startXAndroidLine , 0, 2) startAndroidlayout.addWidget( QLabel( self.tr("From Y:") ) , 0,3) startAndroidlayout.addWidget( self.startYAndroidLine , 0, 4) startAndroidlayout.addWidget( QLabel( self.tr("To X:") ) ,1,1) startAndroidlayout.addWidget( self.stopXAndroidLine , 1, 2) startAndroidlayout.addWidget( QLabel( self.tr("To Y:") ) , 1,3) startAndroidlayout.addWidget( self.stopYAndroidLine , 1 , 4) self.startAndroidGroup.setLayout(startAndroidlayout) self.startAndroidGroup.hide() def createWidgetShortcut(self): """ Create shortcut widget """ self.shortcutAndroidGroup = QGroupBox(self.tr("")) shortcutAndroidlayout = QGridLayout() self.shortcutAndroidComboBox = QComboBox(self) for i in xrange(len(KEYS_SHORTCUT_ANDROID)): if len(KEYS_SHORTCUT_ANDROID[i]) == 0: self.shortcutAndroidComboBox.insertSeparator(i + 2) else: self.shortcutAndroidComboBox.addItem (KEYS_SHORTCUT_ANDROID[i]) shortcutAndroidlayout.addWidget( QLabel( self.tr("Button:") ) , 0,1) shortcutAndroidlayout.addWidget(self.shortcutAndroidComboBox, 0, 2) self.shortcutAndroidGroup.setLayout(shortcutAndroidlayout) self.shortcutAndroidGroup.hide() def createWidgetCode(self): """ Create code widget """ self.codeAndroidGroup = QGroupBox(self.tr("")) self.codeAndroidLine = QLineEdit(self) validatorCodeAndroid = QIntValidator (self) self.codeAndroidLine.setValidator(validatorCodeAndroid) self.codeAndroidLine.installEventFilter(self) codeAndroidlayout = QGridLayout() codeAndroidlayout.addWidget( QLabel( self.tr("Code:") ) , 0,1) codeAndroidlayout.addWidget( self.codeAndroidLine , 0, 2) self.codeAndroidGroup.setLayout(codeAndroidlayout) self.codeAndroidGroup.hide() def pluginDataAccessor(self): """ Return data for plugin """ return { "data": "" } def onPluginImport(self, dataJson): """ Received data from plugin """ pass def createConnections(self): """ Create qt connections """ self.actionsAndroidComboBox.currentIndexChanged.connect(self.onActionAndroidChanged) self.addAndroidAction.clicked.connect(self.addStep) self.valueAndroidCombo2.currentIndexChanged.connect(self.onValueAndroid2TypeChanged) self.elementTextCombo.currentIndexChanged.connect(self.onElementTextTypeChanged) def onElementTextTypeChanged(self): """ On element text changed """ if self.elementTextCombo.currentText() in [ "TEXT", "CACHE" ]: self.elementTextAndroidLine.setValidator(self.validatorAll) if self.elementTextCombo.currentText() == "ALIAS": self.elementTextAndroidLine.setText( self.elementTextAndroidLine.text().upper() ) self.elementTextAndroidLine.setValidator(self.validatorUpper) def onValueAndroid2TypeChanged(self): """ On value changed """ if self.valueAndroidCombo2.currentText() in [ "TEXT", "CACHE" ]: self.valueAndroidLine2.setValidator(self.validatorAll) if self.valueAndroidCombo2.currentText() == "ALIAS": self.valueAndroidLine2.setText( self.valueAndroidLine2.text().upper() ) self.valueAndroidLine2.setValidator(self.validatorUpper) def addStep(self): """ Add step """ action = self.actionsAndroidComboBox.currentText() descr = self.descriptionAndroidLine.text() descr = unicode(descr).replace('"', '') signal = self.AddStep if self.cancelAndroidAction.isEnabled(): signal = self.UpdateStep if self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_WAKUP, GuiSteps.ANDROID_UNLOCK, GuiSteps.ANDROID_REBOOT, GuiSteps.ANDROID_SLEEP, GuiSteps.ANDROID_FREEZE_ROTATION, GuiSteps.ANDROID_UNFREEZE_ROTATION, GuiSteps.ANDROID_BOOTLOADER, GuiSteps.ANDROID_RECOVERY, GuiSteps.ANDROID_NOTIFICATION, GuiSteps.ANDROID_SETTINGS, GuiSteps.ANDROID_DEVICEINFO, GuiSteps.ANDROID_GET_LOGS, GuiSteps.ANDROID_CLEAR_LOGS , GuiSteps.ANDROID_WAKEUP_UNLOCK, GuiSteps.ANDROID_LOCK, GuiSteps.ANDROID_SLEEP_LOCK ]: signal.emit( str(action), unicode(descr), EMPTY_VALUE, {} ) elif self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_TYPE_SHORTCUT]: shorcut = self.shortcutAndroidComboBox.currentText() signal.emit( str(action), unicode(descr), shorcut, {} ) elif self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_TYPE_KEYCODE ]: code = self.codeAndroidLine.text() if not len(code): QMessageBox.warning(self, "Recording for Gui" , "Please to set a value!") else: signal.emit( str(action), unicode(descr), code, {} ) elif self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_CLEAR_ELEMENT, GuiSteps.ANDROID_CLICK_ELEMENT, GuiSteps.ANDROID_LONG_CLICK_ELEMENT, GuiSteps.ANDROID_EXIST_ELEMENT, GuiSteps.ANDROID_WAIT_ELEMENT, GuiSteps.ANDROID_TYPE_TEXT_ELEMENT, GuiSteps.ANDROID_GET_TEXT_ELEMENT, GuiSteps.ANDROID_DRAG_ELEMENT, GuiSteps.ANDROID_WAIT_CLICK_ELEMENT ]: textAndroid = self.elementTextAndroidLine.text() descrAndroid = self.elementDescriptionAndroidLine.text() classAndroid = self.elementClassAndroidLine.text() ressourceAndroid = self.elementRessourceIdAndroidLine.text() packageAndroid = self.elementPackageAndroidLine.text() if not len(textAndroid) and not len(classAndroid) and not len(ressourceAndroid) and not len(packageAndroid) and not len(descrAndroid): QMessageBox.warning(self, "Recording for Gui" , "Please to set one value!") else: # read text from cache or not ? fromElCache = False if self.elementTextCombo.currentText() == "CACHE": fromElCache = True fromElAlias = False if self.elementTextCombo.currentText() == "ALIAS": fromElAlias = True if self.actionsAndroidComboBox.currentText() == GuiSteps.ANDROID_TYPE_TEXT_ELEMENT: newTextAndroid = self.valueAndroidLine2.text() if not len(newTextAndroid): QMessageBox.warning(self, "Recording for Gui" , "Please to set a text value!") else: # read text from cache or not ? fromCache = False if self.valueAndroidCombo2.currentText() == "CACHE": fromCache = True fromAlias = False if self.valueAndroidCombo2.currentText() == "ALIAS": fromAlias = True parameters = {'text': textAndroid, 'class': classAndroid, 'ressource': ressourceAndroid, 'package': packageAndroid, 'description': descrAndroid, 'new-text': newTextAndroid, 'from-cache': fromCache, 'from-alias': fromAlias, 'from-el-cache': fromElCache, 'from-el-alias': fromElAlias } signal.emit( str(action), unicode(descr), EMPTY_VALUE, parameters ) elif self.actionsAndroidComboBox.currentText() == GuiSteps.ANDROID_GET_TEXT_ELEMENT: # read text from cache or not ? cacheKey = '' toCache = True cacheKey = self.valueTextCacheGlobalLine.text() parameters = {'text': textAndroid, 'class': classAndroid, 'ressource': ressourceAndroid, 'package': packageAndroid, 'description': descrAndroid, 'cache-key': cacheKey, 'to-cache': toCache, 'from-el-cache': fromElCache, 'from-el-alias': fromElAlias } signal.emit( str(action), unicode(descr), EMPTY_VALUE, parameters ) elif self.actionsAndroidComboBox.currentText() == GuiSteps.ANDROID_DRAG_ELEMENT: xAndroid = self.endxAndroidLine.text() yAndroid = self.endyAndroidLine.text() if not len(xAndroid) and not len(yAndroid): QMessageBox.warning(self, "Recording for Gui" , "Please to set values!") else: parameters = {'text': textAndroid, 'class': classAndroid, 'ressource': ressourceAndroid, 'package': packageAndroid, 'description': descrAndroid, 'from-el-cache': fromElCache, 'from-el-alias': fromElAlias, 'x': xAndroid, 'y': yAndroid } signal.emit( str(action), unicode(descr), EMPTY_VALUE, parameters ) else: parameters = {'text': textAndroid, 'class': classAndroid, 'ressource': ressourceAndroid, 'package': packageAndroid, 'description': descrAndroid, 'from-el-cache': fromElCache, 'from-el-alias': fromElAlias } signal.emit( str(action), unicode(descr), EMPTY_VALUE, parameters ) elif self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_CLICK_POSITION ]: xAndroid = self.xAndroidLine.text() yAndroid = self.yAndroidLine.text() if not len(xAndroid) and not len(yAndroid): QMessageBox.warning(self, "Recording for Gui" , "Please to set values!") else: parameters = { 'x': xAndroid, 'y': yAndroid } signal.emit( str(action), unicode(descr), EMPTY_VALUE, parameters ) elif self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_DRAG_ELEMENT, GuiSteps.ANDROID_DRAG_POSITION, GuiSteps.ANDROID_SWIPE_POSITION]: startXAndroid = self.startXAndroidLine.text() startYAndroid = self.startYAndroidLine.text() stopXAndroid = self.stopXAndroidLine.text() stopYAndroid = self.stopYAndroidLine.text() if not len(startXAndroid) and not len(startYAndroid) and not len(stopXAndroid) and not len(stopYAndroid): QMessageBox.warning(self, "Recording for Gui" , "Please to set values!") else: parameters = { 'start-x': startXAndroid, 'start-y': startYAndroid, 'stop-x': stopXAndroid, 'stop-y': stopYAndroid } signal.emit( str(action), unicode(descr), EMPTY_VALUE, parameters ) elif self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_COMMAND, GuiSteps.ANDROID_SHELL, GuiSteps.ANDROID_RESET_APP, GuiSteps.ANDROID_STOP_APP]: miscStr = self.valueAndroidLine.text() if not len(miscStr): QMessageBox.warning(self, "Recording for Gui" , "Please to set a value!") else: if self.actionsAndroidComboBox.currentText() == GuiSteps.ANDROID_COMMAND: parameters = { 'cmd': miscStr } elif self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_RESET_APP, GuiSteps.ANDROID_STOP_APP ]: parameters = { 'pkg': miscStr } else: parameters = { 'sh': miscStr } signal.emit( str(action), unicode(descr), EMPTY_VALUE, parameters ) else: signal.emit( str(action), unicode(descr), EMPTY_VALUE, {} ) def cancelStep(self): """ Cancel step """ self.addAndroidAction.setText( "&Add" ) buttonFont = QFont() buttonFont.setBold(False) self.addAndroidAction.setFont(buttonFont) self.cancelAndroidAction.setEnabled(False) self.CancelEdit.emit() def finalizeUpdate(self): """ Finalize the update of a step """ self.addAndroidAction.setText( "&Add Action" ) buttonFont = QFont() buttonFont.setBold(False) self.addAndroidAction.setFont(buttonFont) self.cancelAndroidAction.setEnabled(False) def onActionAndroidChanged(self): """ On action changed """ descr = 'No description available!' i = 0 for el in GuiSteps.ACTION_ANDROID_DESCR: if isinstance(el, dict): if self.actionsAndroidComboBox.currentText() in el: descr = GuiSteps.ACTION_ANDROID_DESCR[i][self.actionsAndroidComboBox.currentText()] break i += 1 self.labelActionAndroidDescr.setText( "%s\n" % descr ) if self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_TYPE_SHORTCUT ]: self.shortcutAndroidGroup.show() self.codeAndroidGroup.hide() self.elemenAndroidGroup.hide() self.startAndroidGroup.hide() self.xyAndroidGroup.hide() self.lineAndroidGroup.hide() self.line2AndroidGroup.hide() self.textToGlobalGroup.hide() self.endXyAndroidGroup.hide() self.arrowLabel.show() self.arrowLabel2.show() elif self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_TYPE_KEYCODE ]: self.codeAndroidGroup.show() self.shortcutAndroidGroup.hide() self.elemenAndroidGroup.hide() self.startAndroidGroup.hide() self.xyAndroidGroup.hide() self.lineAndroidGroup.hide() self.line2AndroidGroup.hide() self.textToGlobalGroup.hide() self.endXyAndroidGroup.hide() self.arrowLabel.show() self.arrowLabel2.show() elif self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_CLEAR_ELEMENT, GuiSteps.ANDROID_CLICK_ELEMENT, GuiSteps.ANDROID_LONG_CLICK_ELEMENT, GuiSteps.ANDROID_EXIST_ELEMENT, GuiSteps.ANDROID_WAIT_ELEMENT, GuiSteps.ANDROID_WAIT_CLICK_ELEMENT ]: self.shortcutAndroidGroup.hide() self.codeAndroidGroup.hide() self.elemenAndroidGroup.show() self.startAndroidGroup.hide() self.xyAndroidGroup.hide() self.lineAndroidGroup.hide() self.line2AndroidGroup.hide() self.textToGlobalGroup.hide() self.endXyAndroidGroup.hide() self.arrowLabel.show() self.arrowLabel2.show() elif self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_DRAG_ELEMENT ]: self.shortcutAndroidGroup.hide() self.codeAndroidGroup.hide() self.elemenAndroidGroup.show() self.startAndroidGroup.hide() self.xyAndroidGroup.hide() self.lineAndroidGroup.hide() self.line2AndroidGroup.hide() self.textToGlobalGroup.hide() self.endXyAndroidGroup.show() self.arrowLabel.show() self.arrowLabel2.show() elif self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_GET_TEXT_ELEMENT ]: self.shortcutAndroidGroup.hide() self.codeAndroidGroup.hide() self.elemenAndroidGroup.show() self.startAndroidGroup.hide() self.xyAndroidGroup.hide() self.lineAndroidGroup.hide() self.line2AndroidGroup.hide() self.textToGlobalGroup.show() self.endXyAndroidGroup.hide() self.arrowLabel.show() self.arrowLabel2.show() elif self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_CLICK_POSITION ]: self.shortcutAndroidGroup.hide() self.codeAndroidGroup.hide() self.elemenAndroidGroup.hide() self.startAndroidGroup.hide() self.xyAndroidGroup.show() self.lineAndroidGroup.hide() self.line2AndroidGroup.hide() self.textToGlobalGroup.hide() self.endXyAndroidGroup.hide() self.arrowLabel.show() self.arrowLabel2.show() elif self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_DRAG_POSITION, GuiSteps.ANDROID_SWIPE_POSITION ]: self.shortcutAndroidGroup.hide() self.codeAndroidGroup.hide() self.elemenAndroidGroup.hide() self.startAndroidGroup.show() self.xyAndroidGroup.hide() self.lineAndroidGroup.hide() self.line2AndroidGroup.hide() self.textToGlobalGroup.hide() self.endXyAndroidGroup.hide() self.arrowLabel.show() self.arrowLabel2.show() elif self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_COMMAND, GuiSteps.ANDROID_SHELL, GuiSteps.ANDROID_RESET_APP, GuiSteps.ANDROID_STOP_APP ]: self.shortcutAndroidGroup.hide() self.codeAndroidGroup.hide() self.elemenAndroidGroup.hide() self.startAndroidGroup.hide() self.xyAndroidGroup.hide() self.lineAndroidGroup.show() self.line2AndroidGroup.hide() self.textToGlobalGroup.hide() self.endXyAndroidGroup.hide() self.arrowLabel.show() self.arrowLabel2.show() elif self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_TYPE_TEXT_ELEMENT ]: self.shortcutAndroidGroup.hide() self.codeAndroidGroup.hide() self.elemenAndroidGroup.show() self.startAndroidGroup.hide() self.xyAndroidGroup.hide() self.lineAndroidGroup.hide() self.line2AndroidGroup.show() self.textToGlobalGroup.hide() self.endXyAndroidGroup.hide() self.arrowLabel.show() self.arrowLabel2.show() else: self.shortcutAndroidGroup.hide() self.codeAndroidGroup.hide() self.elemenAndroidGroup.hide() self.startAndroidGroup.hide() self.xyAndroidGroup.hide() self.lineAndroidGroup.hide() self.line2AndroidGroup.hide() self.textToGlobalGroup.hide() self.endXyAndroidGroup.hide() self.arrowLabel.hide() self.arrowLabel2.show() def setTimeout(self, timeout): """ Set the timeout """ self.optionsDialog.timeoutAndroidLine.setText(timeout) def getTimeout(self): """ Return the timeout """ return self.optionsDialog.timeoutAndroidLine.text() def getAgentName(self): """ Get the agent name """ return self.optionsDialog.agentNameLineAndroid.text() def getAgentList(self): """ Return the agent list """ return self.optionsDialog.agentsAndroidList def editStep(self, stepData): """ Edit a step """ self.addAndroidAction.setText( "&Update" ) buttonFont = QFont() buttonFont.setBold(True) self.addAndroidAction.setFont(buttonFont) self.cancelAndroidAction.setEnabled(True) # set the current value for actions combo for i in xrange(self.actionsAndroidComboBox.count()): item_text = self.actionsAndroidComboBox.itemText(i) if unicode(stepData["action"]) == unicode(item_text): self.actionsAndroidComboBox.setCurrentIndex(i) break # and then refresh options self.onActionAndroidChanged() # finally fill all fields self.descriptionAndroidLine.setText( stepData["description"] ) if self.actionsAndroidComboBox.currentText() == GuiSteps.ANDROID_COMMAND: self.valueAndroidLine.setText( stepData["parameters"]["cmd"] ) if self.actionsAndroidComboBox.currentText() == GuiSteps.ANDROID_SHELL: self.valueAndroidLine.setText( stepData["parameters"]["sh"] ) if self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_RESET_APP, GuiSteps.ANDROID_STOP_APP ]: self.valueAndroidLine.setText( stepData["parameters"]["pkg"] ) if self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_CLEAR_ELEMENT, GuiSteps.ANDROID_TYPE_TEXT_ELEMENT, GuiSteps.ANDROID_CLICK_ELEMENT, GuiSteps.ANDROID_LONG_CLICK_ELEMENT, GuiSteps.ANDROID_EXIST_ELEMENT, GuiSteps.ANDROID_WAIT_ELEMENT, GuiSteps.ANDROID_GET_TEXT_ELEMENT, GuiSteps.ANDROID_DRAG_ELEMENT, GuiSteps.ANDROID_WAIT_CLICK_ELEMENT ]: self.elementTextAndroidLine.setText( "" ) self.elementDescriptionAndroidLine.setText( "" ) self.elementClassAndroidLine.setText( "" ) self.elementRessourceIdAndroidLine.setText( "" ) self.elementPackageAndroidLine.setText( "" ) self.valueAndroidLine2.setText( "" ) if "text" in stepData["parameters"]: if stepData["parameters"]["from-el-cache"]: self.elementTextCombo.setCurrentIndex(INDEX_CACHE) self.elementTextAndroidLine.setValidator(self.validatorAll) elif stepData["parameters"]["from-el-alias"]: self.elementTextCombo.setCurrentIndex(INDEX_ALIAS) self.elementTextAndroidLine.setValidator(self.validatorUpper) else: self.elementTextCombo.setCurrentIndex(INDEX_TEXT) self.elementTextAndroidLine.setValidator(self.validatorAll) self.elementTextAndroidLine.setText ( stepData["parameters"]["text"] ) if "description" in stepData["parameters"]: self.elementDescriptionAndroidLine.setText( stepData["parameters"]["description"] ) if "class" in stepData["parameters"]: self.elementClassAndroidLine.setText( stepData["parameters"]["class"] ) if "ressource" in stepData["parameters"]: self.elementRessourceIdAndroidLine.setText( stepData["parameters"]["ressource"] ) if "package" in stepData["parameters"]: self.elementPackageAndroidLine.setText( stepData["parameters"]["package"] ) if "new-text" in stepData["parameters"]: self.valueAndroidLine2.setText( stepData["parameters"]["new-text"] ) if self.actionsAndroidComboBox.currentText() == GuiSteps.ANDROID_DRAG_ELEMENT: if "x" in stepData["parameters"]: self.endxAndroidLine.setText( stepData["parameters"]["x"] ) if "y" in stepData["parameters"]: self.endyAndroidLine.setText( stepData["parameters"]["y"] ) if self.actionsAndroidComboBox.currentText() == GuiSteps.ANDROID_TYPE_TEXT_ELEMENT: if stepData["parameters"]["from-cache"]: self.valueAndroidCombo2.setCurrentIndex(INDEX_CACHE) self.valueAndroidLine2.setValidator(self.validatorAll) elif stepData["parameters"]["from-alias"]: self.valueAndroidCombo2.setCurrentIndex(INDEX_ALIAS) self.valueAndroidLine2.setValidator(self.validatorUpper) else: self.valueAndroidCombo2.setCurrentIndex(INDEX_TEXT) self.valueAndroidLine2.setValidator(self.validatorAll) if self.actionsAndroidComboBox.currentText() == GuiSteps.ANDROID_GET_TEXT_ELEMENT: self.valueTextCacheGlobalLine.setText ( stepData["parameters"]["cache-key"] ) if self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_CLICK_POSITION]: if "x" in stepData["parameters"]: self.xAndroidLine.setText( stepData["parameters"]["x"] ) if "y" in stepData["parameters"]: self.yAndroidLine.setText( stepData["parameters"]["y"] ) if self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_DRAG_POSITION, GuiSteps.ANDROID_SWIPE_POSITION]: if "start-x" in stepData["parameters"]: self.startXAndroidLine.setText( stepData["parameters"]["start-x"] ) if "start-y" in stepData["parameters"]: self.startYAndroidLine.setText( stepData["parameters"]["start-y"] ) if "stop-x" in stepData["parameters"]: self.stopXAndroidLine.setText( stepData["parameters"]["stop-x"] ) if "stop-y" in stepData["parameters"]: self.stopYAndroidLine.setText( stepData["parameters"]["stop-y"] ) if self.actionsAndroidComboBox.currentText() == GuiSteps.ANDROID_TYPE_KEYCODE: self.codeAndroidLine.setText( stepData["misc"] ) if self.actionsAndroidComboBox.currentText() in [ GuiSteps.ANDROID_TYPE_SHORTCUT ]: # set default for i in xrange(self.shortcutAndroidComboBox.count()): item_text = self.shortcutAndroidComboBox.itemText(i) if unicode(stepData["misc"]) == unicode(item_text): self.shortcutAndroidComboBox.setCurrentIndex(i) break
class PymetricsViewer(QWidget): " Pymetrics tab widget " # Limits to colorize the McCabe score LittleRiskLimit = 10 ModerateRiskLimit = 20 HighRiskLimit = 50 # Options of providing a report SingleFile = 0 DirectoryFiles = 1 ProjectFiles = 2 SingleBuffer = 3 def __init__(self, parent=None): QWidget.__init__(self, parent) self.__reportUUID = "" self.__reportFileName = "" self.__reportOption = -1 self.__reportShown = False self.__report = None # Prepare members for reuse self.__noneLabel = QLabel("\nNo results available") self.__noneLabel.setFrameShape(QFrame.StyledPanel) self.__noneLabel.setAlignment(Qt.AlignHCenter) self.__headerFont = self.__noneLabel.font() self.__headerFont.setPointSize(self.__headerFont.pointSize() + 4) self.__noneLabel.setFont(self.__headerFont) self.__noneLabel.setAutoFillBackground(True) noneLabelPalette = self.__noneLabel.palette() noneLabelPalette.setColor(QPalette.Background, GlobalData().skin.nolexerPaper) self.__noneLabel.setPalette(noneLabelPalette) self.__createLayout(parent) self.__updateButtonsStatus() return def __createLayout(self, parent): " Creates the toolbar and layout " # Buttons self.__mcCabeButton = QAction(PixmapCache().getIcon('tableview.png'), 'Switch to McCabe only table view', self) self.__mcCabeButton.setCheckable(True) self.connect(self.__mcCabeButton, SIGNAL('toggled(bool)'), self.__onMcCabe) self.printButton = QAction(PixmapCache().getIcon('printer.png'), 'Print', self) #printButton.setShortcut( 'Ctrl+' ) self.connect(self.printButton, SIGNAL('triggered()'), self.__onPrint) self.printButton.setVisible(False) self.printPreviewButton = QAction( PixmapCache().getIcon('printpreview.png'), 'Print preview', self) #printPreviewButton.setShortcut( 'Ctrl+' ) self.connect(self.printPreviewButton, SIGNAL('triggered()'), self.__onPrintPreview) self.printPreviewButton.setVisible(False) spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.clearButton = QAction(PixmapCache().getIcon('trash.png'), 'Clear', self) self.connect(self.clearButton, SIGNAL('triggered()'), self.__clear) # The toolbar self.toolbar = QToolBar(self) self.toolbar.setOrientation(Qt.Vertical) self.toolbar.setMovable(False) self.toolbar.setAllowedAreas(Qt.RightToolBarArea) self.toolbar.setIconSize(QSize(16, 16)) self.toolbar.setFixedWidth(28) self.toolbar.setContentsMargins(0, 0, 0, 0) self.toolbar.addAction(self.__mcCabeButton) self.toolbar.addAction(self.printPreviewButton) self.toolbar.addAction(self.printButton) self.toolbar.addWidget(spacer) self.toolbar.addAction(self.clearButton) self.__totalResultsTree = QTreeWidget() self.__totalResultsTree.setAlternatingRowColors(True) self.__totalResultsTree.setRootIsDecorated(True) self.__totalResultsTree.setItemsExpandable(True) self.__totalResultsTree.setUniformRowHeights(True) self.__totalResultsTree.setItemDelegate(NoOutlineHeightDelegate(4)) headerLabels = ["Path / name", "Value", ""] self.__totalResultsTree.setHeaderLabels(headerLabels) self.connect(self.__totalResultsTree, SIGNAL("itemActivated(QTreeWidgetItem *, int)"), self.__allItemActivated) self.connect(self.__totalResultsTree, SIGNAL("itemExpanded(QTreeWidgetItem *)"), self.__onResultsExpanded) self.__totalResultsTree.setColumnHidden(2, True) self.__totalResultsTree.hide() self.__mcCabeTable = QTreeWidget() self.__mcCabeTable.setAlternatingRowColors(True) self.__mcCabeTable.setRootIsDecorated(False) self.__mcCabeTable.setItemsExpandable(False) self.__mcCabeTable.setSortingEnabled(True) self.__mcCabeTable.setItemDelegate(NoOutlineHeightDelegate(4)) self.__mcCabeTable.setUniformRowHeights(True) headerLabels = ["", "File name", "Object", "McCabe Complexity"] self.__mcCabeTable.setHeaderLabels(headerLabels) self.connect(self.__mcCabeTable, SIGNAL("itemActivated(QTreeWidgetItem *, int)"), self.__mcCabeActivated) self.__mcCabeTable.hide() self.__hLayout = QHBoxLayout() self.__hLayout.setContentsMargins(0, 0, 0, 0) self.__hLayout.setSpacing(0) self.__hLayout.addWidget(self.toolbar) self.__hLayout.addWidget(self.__noneLabel) self.__hLayout.addWidget(self.__totalResultsTree) self.__hLayout.addWidget(self.__mcCabeTable) self.setLayout(self.__hLayout) return def getTotalResultsWidget(self): " Provides a reference to the total results widget " return self.__totalResultsTree def getMcCabeResultsWidget(self): " Provides a reference to the McCabe results widget " return self.__mcCabeTable def __updateButtonsStatus(self): " Updates the buttons status " self.__mcCabeButton.setEnabled(self.__reportShown) self.printButton.setEnabled(self.__reportShown) self.printPreviewButton.setEnabled(self.__reportShown) self.clearButton.setEnabled(self.__reportShown) return def __onResultsExpanded(self, item): " An item has been expanded, so the column width should be adjusted " self.__totalResultsTree.header().resizeSections( QHeaderView.ResizeToContents) return def __onPrint(self): " Triggered when the print button is pressed " pass def __onPrintPreview(self): " triggered when the print preview button is pressed " pass def __onMcCabe(self, state): " Triggered when the metrics view is switched " if not self.__reportShown: return if state: self.__totalResultsTree.hide() self.__mcCabeTable.show() self.__mcCabeButton.setIcon(PixmapCache().getIcon('treeview.png')) self.__mcCabeButton.setToolTip("Switch to complete " "results tree view") else: self.__mcCabeTable.hide() self.__totalResultsTree.show() self.__mcCabeButton.setIcon(PixmapCache().getIcon('tableview.png')) self.__mcCabeButton.setToolTip("Switch to McCabe only table view") return def setFocus(self): " Overridden setFocus " self.__hLayout.setFocus() return def __clear(self): " Clears the content of the vertical layout " if not self.__reportShown: return self.__totalResultsTree.clear() self.__totalResultsTree.hide() self.__mcCabeTable.clear() self.__mcCabeTable.hide() self.__noneLabel.show() self.__report = None self.__reportShown = False self.__updateButtonsStatus() # self.resizeEvent() self.__mcCabeButton.setIcon(PixmapCache().getIcon('tableview.png')) self.__mcCabeButton.setToolTip("Switch to McCabe only table view") self.__mcCabeButton.setChecked(False) self.__updateTooltip() return def __updateTooltip(self): " Generates a signal with appropriate string message " if not self.__reportShown: tooltip = "No metrics available" elif self.__reportOption == self.DirectoryFiles: tooltip = "Metrics generated for directory: " + \ self.__reportFileName elif self.__reportOption == self.ProjectFiles: tooltip = "Metrics generated for the whole project" elif self.__reportOption == self.SingleFile: tooltip = "Metrics generated for file: " + self.__reportFileName elif self.__reportOption == self.SingleBuffer: tooltip = "Metrics generated for unsaved file: " + \ self.__reportFileName else: tooltip = "" self.emit(SIGNAL('updatePymetricsTooltip'), tooltip) return @staticmethod def __shouldShowFileName(table, column): " Checks if the file name is the same " size = table.topLevelItemCount() if size == 0: return False index = size - 1 firstName = table.topLevelItem(index).text(column) index -= 1 while index >= 0: if table.topLevelItem(index).text(column) != firstName: return True index -= 1 return False def showReport(self, metrics, reportOption, fileName, uuid): " Shows the pymetrics results " self.__clear() self.__noneLabel.hide() self.__report = metrics self.__reportUUID = uuid self.__reportFileName = fileName self.__reportOption = reportOption if len(metrics.report) > 1: accumulatedBasic = self.__accumulateBasicMetrics() accItem = QTreeWidgetItem(["Cumulative basic metrics"]) self.__totalResultsTree.addTopLevelItem(accItem) for key in accumulatedBasic: bmItem = [ BasicMetrics.metricsOfInterest[key], splitThousands(str(accumulatedBasic[key])) ] basicMetric = QTreeWidgetItem(bmItem) accItem.addChild(basicMetric) # Add the complete information for fileName in metrics.report: if reportOption == self.SingleBuffer: fileItem = QTreeWidgetItem(["Editor buffer"]) else: fileItem = QTreeWidgetItem([fileName]) info = GlobalData().briefModinfoCache.get(fileName) if info.docstring is not None: fileItem.setToolTip(0, info.docstring.text) else: fileItem.setToolTip(0, "") self.__totalResultsTree.addTopLevelItem(fileItem) # Messages part messages = metrics.report[fileName].messages if len(messages) > 0: messagesItem = QTreeWidgetItem(["Messages"]) fileItem.addChild(messagesItem) for message in messages: mItem = [message, "", "E"] messagesItem.addChild(QTreeWidgetItem(mItem)) # Basic metrics part basicItem = QTreeWidgetItem(["Basic metrics"]) fileItem.addChild(basicItem) basic = metrics.report[fileName].basicMetrics for key in basic.metrics: bmItem = [ BasicMetrics.metricsOfInterest[key], str(basic.metrics[key]) ] basicMetric = QTreeWidgetItem(bmItem) basicItem.addChild(basicMetric) # McCabe part mccabeItem = QTreeWidgetItem(["McCabe metrics"]) fileItem.addChild(mccabeItem) mccabe = metrics.report[fileName].mcCabeMetrics.metrics for objName in mccabe: objItem = [objName, str(mccabe[objName]), "M"] mccabeMetric = QTreeWidgetItem(objItem) mccabeItem.addChild(mccabeMetric) # COCOMO 2 part cocomo = [ "COCOMO 2", str(metrics.report[fileName].cocomo2Metrics.value) ] cocomoItem = QTreeWidgetItem(cocomo) fileItem.addChild(cocomoItem) # Resizing the table self.__totalResultsTree.header().resizeSections( QHeaderView.ResizeToContents) # Add McCabe complexity information for fileName in metrics.report: mccabe = metrics.report[fileName].mcCabeMetrics.metrics for objName in mccabe: values = ["", fileName, objName, str(mccabe[objName])] self.__mcCabeTable.addTopLevelItem(McCabeTableItem(values)) if not self.__shouldShowFileName(self.__mcCabeTable, 1): self.__mcCabeTable.setColumnHidden(1, True) # Resizing and sorting the table self.__mcCabeTable.header().setSortIndicator(3, Qt.DescendingOrder) self.__mcCabeTable.sortItems( 3, self.__mcCabeTable.header().sortIndicatorOrder()) self.__mcCabeTable.header().resizeSections( QHeaderView.ResizeToContents) # Show the complete information self.__mcCabeTable.hide() self.__totalResultsTree.show() self.__reportShown = True self.__updateButtonsStatus() self.__updateTooltip() # It helps, but why do I have flickering? QApplication.processEvents() return def __accumulateBasicMetrics(self): " Accumulates basic metrics for all the processed files " basic = {} for fileName in self.__report.report: singleBasic = self.__report.report[fileName].basicMetrics.metrics for key in singleBasic: if not key.startswith('num'): continue if key in basic: basic[key] += int(singleBasic[key]) else: basic[key] = int(singleBasic[key]) return basic def __mcCabeActivated(self, item, column): " Handles the double click (or Enter) on the mccabe table item " objName = str(item.text(2)) if self.__reportOption == self.SingleBuffer: if os.path.isabs(self.__reportFileName): fileName = self.__reportFileName else: fileName = "" else: fileName = str(item.text(1)) self.__onMcCabeObject(objName, fileName) return def __allItemActivated(self, item, column): " Handles the double click (or Enter) in the total results tree " # We process only the error messages and McCabe items hiddenColumnText = str(item.text(2)) if not hiddenColumnText in ["M", "E"]: return fileName = self.__getTreeItemFileName(item) lineNumber = 0 if hiddenColumnText == "M": # This is McCabe item objName = str(item.text(0)) self.__onMcCabeObject(objName, fileName) return elif hiddenColumnText == "E": # This is an error message message = str(item.text(0)) pos = message.find("at line") if pos == -1: logging.error("Unknown format of the message. " "Please inform the developers.") return parts = message[pos:].split() try: lineNumber = int(parts[2].replace(',', '')) except: logging.error("Unknown format of the message. " "Please inform the developers.") return if fileName == "": # This is an unsaved buffer, try to find the editor by UUID mainWindow = GlobalData().mainWindow widget = mainWindow.getWidgetByUUID(self.__reportUUID) if widget is None: logging.error("The unsaved buffer has been closed") return # The widget was found, so jump to the required editor = widget.getEditor() editor.gotoLine(lineNumber) editor.setFocus() return GlobalData().mainWindow.openFile(fileName, lineNumber) return def __getTreeItemFileName(self, item): " Identifies the tree view item file name " if self.__reportOption == self.SingleBuffer: if os.path.isabs(self.__reportFileName): return self.__reportFileName return "" # The file name is always two levels up fileItem = item.parent().parent() return str(fileItem.text(0)) def __onMcCabeObject(self, objName, fileName): " Called when the user activated McCabe item " info = None mainWindow = GlobalData().mainWindow widget = mainWindow.getWidgetByUUID(self.__reportUUID) if widget is None: if fileName == "": logging.error("The unsaved buffer has been closed") return # No widget, but we know the file name info = getBriefModuleInfoFromFile(fileName) else: # The widget was found editor = widget.getEditor() # The editor content has been modified, so re-parse the buffer info = getBriefModuleInfoFromMemory(editor.text()) parts = objName.split('.') currentIndex = 0 functionsContainer = info.functions classesContainer = info.classes line = -1 if objName == "__main__" and len(parts) == 1: # Special case - global file scope line = 1 currentIndex = 1 while currentIndex < len(parts): found = False for func in functionsContainer: if func.name == parts[currentIndex]: if currentIndex == len(parts) - 1: # Found, jump to the line line = func.line break functionsContainer = func.functions classesContainer = func.classes found = True break if line != -1: break if found: currentIndex += 1 continue for klass in classesContainer: if klass.name == parts[currentIndex]: if currentIndex == len(parts) - 1: # Found, jump to the line line = klass.line break functionsContainer = klass.functions classesContainer = klass.classes found = True if line != -1: break if found: currentIndex += 1 continue # Not found logging.error("Cannot find the " + objName) return # Here we have the line number if widget is None: GlobalData().mainWindow.openFile(fileName, line) else: editor = widget.getEditor() editor.gotoLine(line) editor.setFocus() return def onFileUpdated(self, fileName, uuid): " Called when a buffer is saved or saved as " if not self.__reportShown: return if self.__reportUUID != uuid: return # Currently shown report is for the saved buffer # File name is expected being absolute self.__reportFileName = fileName self.emit(SIGNAL('updatePymetricsTooltip'), "Metrics generated for buffer saved as " + fileName) return
class ActionBar(QFrame): """ SIGNALS: @changeCurrent(PyQt_PyObject) @runFile(QString) @reopenTab(QString) @recentTabsModified() """ def __init__(self, main_combo=False): super(ActionBar, self).__init__() self.setObjectName("actionbar") hbox = QHBoxLayout(self) hbox.setContentsMargins(1, 1, 1, 1) hbox.setSpacing(1) self.lbl_checks = QLabel('') self.lbl_checks.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.lbl_checks.setFixedWidth(48) self.lbl_checks.setVisible(False) hbox.addWidget(self.lbl_checks) self.combo = QComboBox() self.combo.setIconSize(QSize(16, 16)) #model = QStandardItemModel() #self.combo.setModel(model) #self.combo.view().setDragDropMode(QAbstractItemView.InternalMove) self.combo.setMaximumWidth(300) self.combo.setObjectName("combotab") self.connect(self.combo, SIGNAL("currentIndexChanged(int)"), self.current_changed) self.combo.setToolTip(translations.TR_COMBO_FILE_TOOLTIP) self.combo.setContextMenuPolicy(Qt.CustomContextMenu) self.connect(self.combo, SIGNAL( "customContextMenuRequested(const QPoint &)"), self._context_menu_requested) hbox.addWidget(self.combo) self.symbols_combo = QComboBox() self.symbols_combo.setIconSize(QSize(16, 16)) self.symbols_combo.setObjectName("combo_symbols") self.connect(self.symbols_combo, SIGNAL("activated(int)"), self.current_symbol_changed) hbox.addWidget(self.symbols_combo) self.code_navigator = CodeNavigator() hbox.addWidget(self.code_navigator) self._pos_text = "Line: %d, Col: %d" self.lbl_position = QLabel(self._pos_text % (0, 0)) self.lbl_position.setObjectName("position") self.lbl_position.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) hbox.addWidget(self.lbl_position) self.btn_close = QPushButton( self.style().standardIcon(QStyle.SP_DialogCloseButton), '') self.btn_close.setIconSize(QSize(16, 16)) if main_combo: self.btn_close.setObjectName('navigation_button') self.btn_close.setToolTip(translations.TR_CLOSE_FILE) self.connect(self.btn_close, SIGNAL("clicked()"), self.about_to_close_file) else: self.btn_close.setObjectName('close_split') self.btn_close.setToolTip(translations.TR_CLOSE_SPLIT) self.connect(self.btn_close, SIGNAL("clicked()"), self.close_split) self.btn_close.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) hbox.addWidget(self.btn_close) def resizeEvent(self, event): super(ActionBar, self).resizeEvent(event) if event.size().width() < 350: self.symbols_combo.hide() self.code_navigator.hide() self.lbl_position.hide() else: self.symbols_combo.show() self.code_navigator.show() self.lbl_position.show() def add_item(self, text, neditable): """Add a new item to the combo and add the neditable data.""" self.combo.addItem(text, neditable) self.combo.setCurrentIndex(self.combo.count() - 1) def get_editables(self): editables = [] for index in range(self.combo.count()): neditable = self.combo.itemData(index) editables.append(neditable) return editables def add_symbols(self, symbols): """Add the symbols to the symbols's combo.""" self.symbols_combo.clear() for symbol in symbols: data = symbol[1] if data[1] == 'f': icon = QIcon(":img/function") else: icon = QIcon(":img/class") self.symbols_combo.addItem(icon, data[0]) def set_current_symbol(self, index): self.symbols_combo.setCurrentIndex(index) def update_item_icon(self, neditable, icon): index = self.combo.findData(neditable) self.combo.setItemIcon(index, icon) def update_item_text(self, neditable, text): index = self.combo.findData(neditable) self.combo.setItemText(index, text) def current_changed(self, index): """Change the current item in the combo.""" neditable = self.combo.itemData(index) self.emit(SIGNAL("changeCurrent(PyQt_PyObject, int)"), neditable, index) def current_symbol_changed(self, index): """Change the current symbol in the combo.""" self.emit(SIGNAL("goToSymbol(int)"), index) def update_line_col(self, line, col): """Update the line and column position.""" self.lbl_position.setText(self._pos_text % (line, col)) def _context_menu_requested(self, point): """Display context menu for the combo file.""" if self.combo.count() == 0: # If there is not an Editor opened, don't show the menu return menu = QMenu() actionAdd = menu.addAction(translations.TR_ADD_TO_PROJECT) actionRun = menu.addAction(translations.TR_RUN_FILE) menuSyntax = menu.addMenu(translations.TR_CHANGE_SYNTAX) self._create_menu_syntax(menuSyntax) menu.addSeparator() actionClose = menu.addAction(translations.TR_CLOSE_FILE) actionCloseAll = menu.addAction(translations.TR_CLOSE_ALL_FILES) actionCloseAllNotThis = menu.addAction( translations.TR_CLOSE_OTHER_FILES) menu.addSeparator() actionSplitH = menu.addAction(translations.TR_SPLIT_VERTICALLY) actionSplitV = menu.addAction(translations.TR_SPLIT_HORIZONTALLY) menu.addSeparator() actionCopyPath = menu.addAction( translations.TR_COPY_FILE_PATH_TO_CLIPBOARD) actionReopen = menu.addAction(translations.TR_REOPEN_FILE) actionUndock = menu.addAction(translations.TR_UNDOCK_EDITOR) if len(settings.LAST_OPENED_FILES) == 0: actionReopen.setEnabled(False) #Connect actions self.connect(actionSplitH, SIGNAL("triggered()"), lambda: self._split(False)) self.connect(actionSplitV, SIGNAL("triggered()"), lambda: self._split(True)) self.connect(actionRun, SIGNAL("triggered()"), self._run_this_file) self.connect(actionAdd, SIGNAL("triggered()"), self._add_to_project) self.connect(actionClose, SIGNAL("triggered()"), self.about_to_close_file) self.connect(actionCloseAllNotThis, SIGNAL("triggered()"), self._close_all_files_except_this) self.connect(actionCloseAll, SIGNAL("triggered()"), self._close_all_files) self.connect(actionCopyPath, SIGNAL("triggered()"), self._copy_file_location) self.connect(actionReopen, SIGNAL("triggered()"), self._reopen_last_tab) self.connect(actionUndock, SIGNAL("triggered()"), self._undock_editor) menu.exec_(QCursor.pos()) def _create_menu_syntax(self, menuSyntax): """Create Menu with the list of syntax supported.""" syntax = list(settings.SYNTAX.keys()) syntax.sort() for syn in syntax: menuSyntax.addAction(syn) self.connect(menuSyntax, SIGNAL("triggered(QAction*)"), self._reapply_syntax) def _reapply_syntax(self, syntaxAction): #TODO if [self.currentIndex(), syntaxAction] != self._resyntax: self._resyntax = [self.currentIndex(), syntaxAction] self.emit(SIGNAL("syntaxChanged(QWidget, QString)"), self.currentWidget(), syntaxAction.text()) def set_current_file(self, neditable): index = self.combo.findData(neditable) self.combo.setCurrentIndex(index) def set_current_by_index(self, index): self.combo.setCurrentIndex(index) def about_to_close_file(self, index=None): """Close the NFile object.""" if index is None: index = self.combo.currentIndex() neditable = self.combo.itemData(index) if neditable: neditable.nfile.close() def close_split(self): self.emit(SIGNAL("closeSplit()")) def close_file(self, neditable): """Receive the confirmation to close the file.""" index = self.combo.findData(neditable) self.combo.removeItem(index) return index def _run_this_file(self): """Execute the current file.""" neditable = self.combo.itemData(self.combo.currentIndex()) self.emit(SIGNAL("runFile(QString)"), neditable.file_path) def _add_to_project(self): """Emit a signal to let someone handle the inclusion of the file inside a project.""" neditable = self.combo.itemData(self.combo.currentIndex()) self.emit(SIGNAL("addToProject(QString)"), neditable.file_path) def _reopen_last_tab(self): self.emit(SIGNAL("reopenTab(QString)"), settings.LAST_OPENED_FILES.pop()) self.emit(SIGNAL("recentTabsModified()")) def _undock_editor(self): self.emit(SIGNAL("undockEditor()")) def _split(self, orientation): self.emit(SIGNAL("splitEditor(bool)"), orientation) def _copy_file_location(self): """Copy the path of the current opened file to the clipboard.""" neditable = self.combo.itemData(self.combo.currentIndex()) QApplication.clipboard().setText(neditable.file_path, QClipboard.Clipboard) def _close_all_files(self): """Close all the files opened.""" for i in range(self.combo.count()): self.about_to_close_file(0) def _close_all_files_except_this(self): """Close all the files except the current one.""" neditable = self.combo.itemData(self.combo.currentIndex()) for i in reversed(list(range(self.combo.count()))): ne = self.combo.itemData(i) if ne is not neditable: self.about_to_close_file(i)
def create_rows(self, layout): u"""Build one row of the dialog box""" play_button_group = QButtonGroup(self) old_play_button_group = QButtonGroup(self) for num, (source, dest, text, dl_fname, dl_hash, extras, icon)\ in enumerate(self.list, 3): tt_text = self.build_text_help_label(text, source, extras) ico_label = QLabel('', self) ico_label.setToolTip(tt_text) if icon: ico_label.setPixmap(QPixmap.fromImage(icon)) layout.addWidget(ico_label, num, 0) tt_label = QLabel(text, self) tt_label.setToolTip(tt_text) layout.addWidget(tt_label, num, 1) if self.hide_text: tt_label.hide() # Play button. t_play_button = QPushButton(self) play_button_group.addButton(t_play_button, num - 3) t_play_button.setToolTip(self.play_help) t_play_button.setIcon(QIcon(os.path.join(icons_dir, 'play.png'))) layout.addWidget(t_play_button, num, self.play_column) if self.note[dest]: t_play_old_button = QPushButton(self) old_play_button_group.addButton(t_play_old_button, num - 3) t_play_old_button.setIcon( QIcon(os.path.join(icons_dir, 'play.png'))) if not self.hide_text: t_play_old_button.setToolTip(self.note[dest]) else: t_play_old_button.setToolTip(self.play_old_help_short) layout.addWidget(t_play_old_button, num, self.play_old_column) else: dummy_label = QLabel('', self) dummy_label.setToolTip(self.play_old_empty_line_help) layout.addWidget(dummy_label, num, self.play_old_column) # The group where we later look what to do: t_button_group = QButtonGroup(self) t_button_group.setExclusive(True) # Now the four buttons t_add_button = QPushButton(self) t_add_button.setCheckable(True) t_add_button.setChecked(True) t_add_button.setFlat(True) t_add_button.setToolTip(self.add_help_text_short) t_add_button.setIcon(QIcon(os.path.join(icons_dir, 'add.png'))) layout.addWidget(t_add_button, num, self.add_column) t_button_group.addButton(t_add_button, action['add']) t_keep_button = QPushButton(self) t_keep_button.setCheckable(True) t_keep_button.setFlat(True) t_keep_button.setToolTip(self.keep_help_text_short) t_keep_button.setIcon(QIcon(os.path.join(icons_dir, 'keep.png'))) layout.addWidget(t_keep_button, num, self.keep_column) t_button_group.addButton(t_keep_button, action['keep']) t_delete_button = QPushButton(self) t_delete_button.setCheckable(True) t_delete_button.setFlat(True) t_delete_button.setToolTip(self.delete_help_text_short) t_delete_button.setIcon( QIcon(os.path.join(icons_dir, 'delete.png'))) layout.addWidget(t_delete_button, num, self.delete_column) t_button_group.addButton(t_delete_button, action['delete']) t_blacklist_button = QPushButton(self) t_blacklist_button.setCheckable(True) t_blacklist_button.setFlat(True) t_blacklist_button.setToolTip(self.blacklist_help_text_short) t_blacklist_button.setIcon( QIcon(os.path.join(icons_dir, 'blacklist.png'))) if self.show_skull_and_bones: layout.addWidget(t_blacklist_button, num, self.blacklist_column) else: t_blacklist_button.hide() t_button_group.addButton(t_blacklist_button, action['blacklist']) self.buttons_groups.append(t_button_group) play_button_group.buttonClicked.connect( lambda button: play(self.list[play_button_group.id(button)][3])) old_play_button_group.buttonClicked.connect( lambda button: playFromText(self.note[self.list[ old_play_button_group.id(button)][1]]))