def __downloadPluginsDone(self): """ Private method called, when the download of the plugins is finished. """ self.__downloadButton.setEnabled(len(self.__selectedItems())) self.__downloadInstallButton.setEnabled(len(self.__selectedItems())) self.__installButton.setEnabled(True) self.__doneMethod = None if not self.__external: ui = e5App().getObject("UserInterface") else: ui = None if ui and ui.notificationsEnabled(): ui.showNotification( UI.PixmapCache.getPixmap("plugin48.png"), self.tr("Download Plugin Files"), self.tr("""The requested plugins were downloaded.""")) if self.__isDownloadInstall: self.closeAndInstall.emit() else: if ui is None or not ui.notificationsEnabled(): E5MessageBox.information( self, self.tr("Download Plugin Files"), self.tr("""The requested plugins were downloaded.""")) self.downloadProgress.setValue(0) # repopulate the list to update the refresh icons self.__populateList()
def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(SqlBrowserWidget, self).__init__(parent) self.setupUi(self) self.table.addAction(self.insertRowAction) self.table.addAction(self.deleteRowAction) if len(QSqlDatabase.drivers()) == 0: E5MessageBox.information( self, self.tr("No database drivers found"), self.tr( """This tool requires at least one Qt database driver. """ """Please check the Qt documentation how to build the """ """Qt SQL plugins.""" ), ) self.connections.tableActivated.connect(self.on_connections_tableActivated) self.connections.schemaRequested.connect(self.on_connections_schemaRequested) self.connections.cleared.connect(self.on_connections_cleared) self.statusMessage.emit(self.tr("Ready"))
def findPrev(self): """ Public slot to find the next previous of text. """ if not self.havefound or not self.ui.findtextCombo.currentText(): self.show(self.viewmanager.textForFind()) return self.__findBackwards = True txt = self.ui.findtextCombo.currentText() # This moves any previous occurrence of this statement to the head # of the list and updates the combobox if txt in self.findHistory: self.findHistory.remove(txt) self.findHistory.insert(0, txt) self.ui.findtextCombo.clear() self.ui.findtextCombo.addItems(self.findHistory) self.searchListChanged.emit() ok = self.__findNextPrev(txt, True) if ok: if self.replace: self.ui.replaceButton.setEnabled(True) self.ui.replaceSearchButton.setEnabled(True) else: E5MessageBox.information( self, self.windowTitle(), self.tr("'{0}' was not found.").format(txt))
def _selectEntries(self, local=True, filter=None): """ Protected method to select entries based on their VCS status. @param local flag indicating local (i.e. non VCS controlled) file/directory entries should be selected (boolean) @param filter list of classes to check against """ if self.project.vcs is None: return if local: compareString = \ QCoreApplication.translate('ProjectBaseBrowser', "local") else: compareString = self.project.vcs.vcsName() # expand all directories in order to iterate over all entries self._expandAllDirs() QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.processEvents() self.selectionModel().clear() QApplication.processEvents() # now iterate over all entries startIndex = None endIndex = None selectedEntries = 0 index = self.model().index(0, 0) while index.isValid(): itm = self.model().item(index) if self.wantedItem(itm, filter) and \ compareString == itm.data(1): if startIndex is not None and \ startIndex.parent() != index.parent(): self._setItemRangeSelected(startIndex, endIndex, True) startIndex = None selectedEntries += 1 if startIndex is None: startIndex = index endIndex = index else: if startIndex is not None: self._setItemRangeSelected(startIndex, endIndex, True) startIndex = None index = self.indexBelow(index) if startIndex is not None: self._setItemRangeSelected(startIndex, endIndex, True) QApplication.restoreOverrideCursor() QApplication.processEvents() if selectedEntries == 0: E5MessageBox.information( self, QCoreApplication.translate( 'ProjectBaseBrowser', "Select entries"), QCoreApplication.translate( 'ProjectBaseBrowser', """There were no matching entries found."""))
def __getIpAddressReportFinished(self): """ Private slot to process the IP address report data. """ reply = self.sender() if reply.error() == QNetworkReply.NoError: result = json.loads(str(reply.readAll(), "utf-8")) if result["response_code"] == 0: E5MessageBox.information( None, self.tr("VirusTotal IP Address Report"), self.tr("""VirusTotal does not have any information for""" """ the given IP address.""")) elif result["response_code"] == -1: E5MessageBox.information( None, self.tr("VirusTotal IP Address Report"), self.tr("""The submitted IP address is invalid.""")) else: owner = result["as_owner"] resolutions = result["resolutions"] try: urls = result["detected_urls"] except KeyError: urls = [] from .VirusTotalIpReportDialog import VirusTotalIpReportDialog self.__ipReportDlg = VirusTotalIpReportDialog( self.__lastIP, owner, resolutions, urls) self.__ipReportDlg.show() self.__replies.remove(reply) reply.deleteLater()
def on_namedReferenceButton_clicked(self): """ Private slot to handle the named reference toolbutton. """ # determine cursor position as length into text length = self.regexpTextEdit.textCursor().position() # only present group names that occur before the # current cursor position regex = self.regexpTextEdit.toPlainText()[:length] names = self.namedGroups(regex) if not names: E5MessageBox.information( self, self.tr("Named reference"), self.tr("""No named groups have been defined yet.""")) return groupName, ok = QInputDialog.getItem( self, self.tr("Named reference"), self.tr("Select group name:"), names, 0, True) if ok and groupName: self.__insertString("(?P={0})".format(groupName))
def __diff(self): """ Private slot to handle the Diff context menu entry. """ namesW = [ os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getStageableItems() ] namesS = [ os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getUnstageableItems() ] if not namesW and not namesS: E5MessageBox.information( self, self.tr("Differences"), self.tr("""There are no uncommitted changes""" """ available/selected.""")) return diffMode = "work2stage2repo" names = namesW + namesS if self.diff is None: from .GitDiffDialog import GitDiffDialog self.diff = GitDiffDialog(self.vcs) self.diff.show() self.diff.start(names, diffMode=diffMode, refreshable=True)
def hgQueueGuardsDefine(self, name): """ Public method to define guards for the current or a named patch. @param name file/directory name (string) """ # find the root of the repo repodir = self.vcs.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return patchnames = sorted( self.__getPatchesList(repodir, Queues.SERIES_LIST)) if patchnames: from .HgQueuesDefineGuardsDialog import HgQueuesDefineGuardsDialog self.queuesDefineGuardsDialog = HgQueuesDefineGuardsDialog( self.vcs, self, patchnames) self.queuesDefineGuardsDialog.show() self.queuesDefineGuardsDialog.start(name) else: E5MessageBox.information( None, self.tr("Define Guards"), self.tr("""No patches available to define guards for."""))
def hgQueueDeletePatch(self, name): """ Public method to delete a selected unapplied patch. @param name file/directory name (string) """ # find the root of the repo repodir = self.vcs.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return args = self.vcs.initCommand("qdelete") patchnames = sorted(self.__getPatchesList(repodir, Queues.UNAPPLIED_LIST)) if patchnames: patch, ok = QInputDialog.getItem( None, self.tr("Select Patch"), self.tr("Select the patch to be deleted:"), patchnames, 0, False) if ok and patch: args.append(patch) dia = HgDialog(self.tr("Delete Patch"), self.vcs) res = dia.startProcess(args, repodir) if res: dia.exec_() else: E5MessageBox.information( None, self.tr("Select Patch"), self.tr("""No patches to select from."""))
def on_replaceAllButton_clicked(self): """ Private slot to replace all occurrences of data. """ replacements = 0 cursorPosition = self.__editor.cursorPosition() fba, ftxt = self.__getContent(False) rba, rtxt = self.__getContent(True) idx = 0 while idx >= 0: idx = self.__editor.indexOf(fba, idx) if idx >= 0: self.__editor.replaceByteArray(idx, len(fba), rba) idx += len(rba) replacements += 1 if replacements: E5MessageBox.information( self, self.windowTitle(), self.tr("Replaced {0} occurrences.") .format(replacements)) else: E5MessageBox.information( self, self.windowTitle(), self.tr("Nothing replaced because '{0}' was not found.") .format(ftxt)) self.__editor.setCursorPosition(cursorPosition) self.__editor.ensureVisible()
def hgQueueGuardsDropAll(self, name): """ Public method to drop all guards of the current or a named patch. @param name file/directory name (string) """ # find the root of the repo repodir = self.vcs.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return patchnames = sorted(self.__getPatchesList(repodir, Queues.SERIES_LIST)) if patchnames: patch, ok = QInputDialog.getItem( None, self.tr("Drop All Guards"), self.tr("Select the patch to drop guards for" " (leave empty for the current patch):"), [""] + patchnames, 0, False) if ok: args = self.vcs.initCommand("qguard") if patch: args.append(patch) args.append("--none") client = self.vcs.getClient() client.runcommand(args) else: E5MessageBox.information( None, self.tr("Drop All Guards"), self.tr("""No patches available to define guards for."""))
def __find(self, backwards): """ Private method to search the associated text edit. @param backwards flag indicating a backwards search (boolean) """ if not self.__textedit: return txt = self.findtextCombo.currentText() self.__findBackwards = backwards # This moves any previous occurrence of this statement to the head # of the list and updates the combobox if txt in self.findHistory: self.findHistory.remove(txt) self.findHistory.insert(0, txt) self.findtextCombo.clear() self.findtextCombo.addItems(self.findHistory) if backwards: flags = QTextDocument.FindFlags(QTextDocument.FindBackward) else: flags = QTextDocument.FindFlags() if self.caseCheckBox.isChecked(): flags |= QTextDocument.FindCaseSensitively if self.wordCheckBox.isChecked(): flags |= QTextDocument.FindWholeWords ok = self.__textedit.find(txt, flags) if not ok: E5MessageBox.information( self, self.tr("Find"), self.tr("""'{0}' was not found.""").format(txt))
def on_validateButton_clicked(self): """ Private slot to validate the entered QRegularExpression. """ if not self.__pyqt5Available: # only available for PyQt5 return regexp = self.regexpTextEdit.toPlainText() if regexp: options = [] if self.caseInsensitiveCheckBox.isChecked(): options.append("CaseInsensitiveOption") if self.multilineCheckBox.isChecked(): options.append("MultilineOption") if self.dotallCheckBox.isChecked(): options.append("DotMatchesEverythingOption") if self.extendedCheckBox.isChecked(): options.append("ExtendedPatternSyntaxOption") if self.greedinessCheckBox.isChecked(): options.append("InvertedGreedinessOption") if self.unicodeCheckBox.isChecked(): options.append("UseUnicodePropertiesOption") if self.captureCheckBox.isChecked(): options.append("DontCaptureOption") if self.__sendCommand("validate", options=options, regexp=regexp): response = self.__receiveResponse() if response and "valid" in response: if response["valid"]: E5MessageBox.information( self, self.tr("Validation"), self.tr("""The regular expression is valid.""")) else: E5MessageBox.critical( self, self.tr("Error"), self.tr( """Invalid regular expression: {0}""").format( response["errorMessage"])) # move cursor to error offset offset = response["errorOffset"] tc = self.regexpTextEdit.textCursor() tc.setPosition(offset) self.regexpTextEdit.setTextCursor(tc) self.regexpTextEdit.setFocus() return else: E5MessageBox.critical( self, self.tr("Communication Error"), self.tr("""Invalid response received from""" """ PyQt5 backend.""")) else: E5MessageBox.critical( self, self.tr("Communication Error"), self.tr("""Communication with PyQt5 backend""" """ failed.""")) else: E5MessageBox.critical( self, self.tr("Error"), self.tr("""A regular expression must be given."""))
def _selectEntries(self, local=True, filterList=None): """ Protected method to select entries based on their VCS status. @param local flag indicating local (i.e. non VCS controlled) file/directory entries should be selected (boolean) @param filterList list of classes to check against """ if self.project.vcs is None: return if local: compareString = QCoreApplication.translate('ProjectBaseBrowser', "local") else: compareString = self.project.vcs.vcsName() # expand all directories in order to iterate over all entries self._expandAllDirs() QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.processEvents() self.selectionModel().clear() QApplication.processEvents() # now iterate over all entries startIndex = None endIndex = None selectedEntries = 0 index = self.model().index(0, 0) while index.isValid(): itm = self.model().item(index) if (self.wantedItem(itm, filterList) and compareString == itm.data(1)): if (startIndex is not None and startIndex.parent() != index.parent()): self._setItemRangeSelected(startIndex, endIndex, True) startIndex = None selectedEntries += 1 if startIndex is None: startIndex = index endIndex = index else: if startIndex is not None: self._setItemRangeSelected(startIndex, endIndex, True) startIndex = None index = self.indexBelow(index) if startIndex is not None: self._setItemRangeSelected(startIndex, endIndex, True) QApplication.restoreOverrideCursor() QApplication.processEvents() if selectedEntries == 0: E5MessageBox.information( self, QCoreApplication.translate('ProjectBaseBrowser', "Select entries"), QCoreApplication.translate( 'ProjectBaseBrowser', """There were no matching entries found."""))
def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(SqlBrowserWidget, self).__init__(parent) self.setupUi(self) self.table.addAction(self.insertRowAction) self.table.addAction(self.deleteRowAction) if len(QSqlDatabase.drivers()) == 0: E5MessageBox.information( self, self.tr("No database drivers found"), self.tr( """This tool requires at least one Qt database driver. """ """Please check the Qt documentation how to build the """ """Qt SQL plugins.""")) self.connections.tableActivated.connect( self.on_connections_tableActivated) self.connections.schemaRequested.connect( self.on_connections_schemaRequested) self.connections.cleared.connect(self.on_connections_cleared) self.statusMessage.emit(self.tr("Ready"))
def __showMimeType(self): """ Private slot to show the mime type of the selected entry. """ itmList = self.getSelectedItems() if itmList: mimetype = Utilities.MimeTypes.mimeType(itmList[0].fileName()) if mimetype is None: E5MessageBox.warning( self, self.tr("Show Mime-Type"), self.tr("""The mime type of the file could not be""" """ determined.""")) elif mimetype.split("/")[0] == "text": E5MessageBox.information( self, self.tr("Show Mime-Type"), self.tr("""The file has the mime type <b>{0}</b>."""). format(mimetype)) else: textMimeTypesList = Preferences.getUI("TextMimeTypes") if mimetype in textMimeTypesList: E5MessageBox.information( self, self.tr("Show Mime-Type"), self.tr("""The file has the mime type <b>{0}</b>."""). format(mimetype)) else: ok = E5MessageBox.yesNo( self, self.tr("Show Mime-Type"), self.tr("""The file has the mime type <b>{0}</b>.""" """<br/> Shall it be added to the list of""" """ text mime types?""").format(mimetype)) if ok: textMimeTypesList.append(mimetype) Preferences.setUI("TextMimeTypes", textMimeTypesList)
def __downloadRequires(self): """ Private slot to initiate the download of required scripts. """ if self.__requireUrls: self.__reply = FollowRedirectReply( self.__requireUrls.pop(0), Helpviewer.HelpWindow.HelpWindow.networkAccessManager()) self.__reply.finished.connect(self.__requireDownloaded) else: from .GreaseMonkeyScript import GreaseMonkeyScript deleteScript = True script = GreaseMonkeyScript(self.__manager, self.__fileName) if script.isValid(): if not self.__manager.containsScript(script.fullName()): from .GreaseMonkeyAddScriptDialog import \ GreaseMonkeyAddScriptDialog dlg = GreaseMonkeyAddScriptDialog(self.__manager, script) deleteScript = dlg.exec_() != QDialog.Accepted else: E5MessageBox.information( None, self.tr("GreaseMonkey Download"), self.tr("""<p><b>{0}</b> is already installed.</p>"""). format(script.name())) if deleteScript: try: os.remove(self.__fileName) except (IOError, OSError): # ignore pass self.finished.emit()
def on_loadButton_clicked(self): """ Private slot to load a regexp from a file. """ fname = E5FileDialog.getOpenFileName( self, self.tr("Load regular expression"), "", self.tr("RegExp Files (*.rx);;All Files (*)")) if fname: try: f = open( Utilities.toNativeSeparators(fname), "r", encoding="utf-8") regexp = f.read() f.close() if regexp.startswith("syntax="): lines = regexp.splitlines() syntax = int(lines[0].replace("syntax=", "")) index = self.syntaxCombo.findData(syntax) self.syntaxCombo.setCurrentIndex(index) regexp = lines[1] self.regexpLineEdit.setText(regexp) except IOError as err: E5MessageBox.information( self, self.tr("Save regular expression"), self.tr("""<p>The regular expression could not""" """ be saved.</p><p>Reason: {0}</p>""") .format(str(err)))
def on_namedReferenceButton_clicked(self): """ Private slot to handle the named reference toolbutton. """ # determine cursor position as length into text length = self.regexpTextEdit.textCursor().position() # only present group names that occur before the current # cursor position regex = self.regexpTextEdit.toPlainText()[:length] names = self.namedGroups(regex) if not names: E5MessageBox.information( self, self.tr("Named reference"), self.tr("""No named groups have been defined yet.""")) return groupName, ok = QInputDialog.getItem( self, self.tr("Named reference"), self.tr("Select group name:"), names, 0, True) if ok and groupName: self.__insertString("(?P={0})".format(groupName))
def on_validateButton_clicked(self): """ Private slot to validate the entered regexp. """ regex = self.regexpLineEdit.text() if regex: re = QRegExp(regex) if self.caseSensitiveCheckBox.isChecked(): re.setCaseSensitivity(Qt.CaseSensitive) else: re.setCaseSensitivity(Qt.CaseInsensitive) re.setMinimal(self.minimalCheckBox.isChecked()) re.setPatternSyntax( self.syntaxCombo.itemData(self.syntaxCombo.currentIndex())) if re.isValid(): E5MessageBox.information( self, self.tr("Validation"), self.tr("""The regular expression is valid.""")) else: E5MessageBox.critical( self, self.tr("Error"), self.tr("""Invalid regular expression: {0}""") .format(re.errorString())) return else: E5MessageBox.critical( self, self.tr("Error"), self.tr("""A regular expression must be given."""))
def on_updateCacheButton_clicked(self): """ Private slot to update the local cache database. """ E5MessageBox.information( self, self.tr("Update Safe Browsing Cache"), self.tr("""Updating the Safe Browsing cache might be a lengthy""" """ operation. Please be patient!""")) QApplication.setOverrideCursor(Qt.WaitCursor) ok, error = self.__manager.updateHashPrefixCache() self.__resetProgress() QApplication.restoreOverrideCursor() if not ok: if error: E5MessageBox.critical( self, self.tr("Update Safe Browsing Cache"), self.tr("""<p>Updating the Safe Browsing cache failed.""" """</p><p>Reason: {0}</p>""").format(error)) else: E5MessageBox.critical( self, self.tr("Update Safe Browsing Cache"), self.tr("""<p>Updating the Safe Browsing cache failed.""" """</p>"""))
def __versionCheckResult(self, versions): """ Private method to show the result of the version check action. @param versions contents of the downloaded versions file (list of strings) """ url = "" ui = self.__ui try: # check release version if calc_int_version(versions[0]) > calc_int_version(Version): res = E5MessageBox.yesNo( ui, ui.tr("Update available"), ui.tr("""Pymakr version <b>{0}</b> is now""" """ available at <b>{1}</b>. Would you like""" """ to get it?""").format(versions[0], versions[1]), yesDefault=True) url = res and versions[1] or '' else: if ui.manualUpdatesCheck: E5MessageBox.information( ui, ui.tr("Pymakr is up to date"), ui.tr("""You are using the latest version of""" """ Pymakr""")) except IndexError: E5MessageBox.warning(ui, ui.tr("Error during updates check"), ui.tr("""Could not perform updates check.""")) if url: QDesktopServices.openUrl(QUrl(url))
def __configureUicCompiler(self): """ Private slot to configure some non-common uic compiler options. """ from .UicCompilerOptionsDialog import UicCompilerOptionsDialog params = self.project.pdata["UICPARAMS"] if self.project.getProjectType() in ["Qt4", "PyQt5", "E6Plugin"]: dlg = UicCompilerOptionsDialog(params, self.getUiCompiler()) if dlg.exec_() == QDialog.Accepted: package, suffix, root = dlg.getData() if package != params["Package"]: params["Package"] = package self.project.setDirty(True) if suffix != params["RcSuffix"]: params["RcSuffix"] = suffix self.project.setDirty(True) if root != params["PackagesRoot"]: params["PackagesRoot"] = root self.project.setDirty(True) elif self.project.getProjectType() in ["PySide", "PySide2"]: E5MessageBox.information( self, self.tr("Configure uic Compiler"), self.tr("""No project specific uic compiler flags are""" """ supported for PySide or PySide2."""))
def __getIpAddressReportFinished(self, reply): """ Private slot to process the IP address report data. @param reply reference to the network reply @type QNetworkReply """ if reply.error() == QNetworkReply.NoError: result = json.loads(str(reply.readAll(), "utf-8")) if result["response_code"] == 0: E5MessageBox.information( None, self.tr("VirusTotal IP Address Report"), self.tr("""VirusTotal does not have any information for""" """ the given IP address.""")) elif result["response_code"] == -1: E5MessageBox.information( None, self.tr("VirusTotal IP Address Report"), self.tr("""The submitted IP address is invalid.""")) else: owner = result["as_owner"] resolutions = result["resolutions"] try: urls = result["detected_urls"] except KeyError: urls = [] from .VirusTotalIpReportDialog import VirusTotalIpReportDialog self.__ipReportDlg = VirusTotalIpReportDialog( self.__lastIP, owner, resolutions, urls) self.__ipReportDlg.show() self.__replies.remove(reply) reply.deleteLater()
def findPrev(self): """ Public slot to find the next previous of text. """ if not self.havefound or not self.ui.findtextCombo.currentText(): self.show(self.__viewmanager.textForFind()) return self.__findBackwards = True txt = self.ui.findtextCombo.currentText() # This moves any previous occurrence of this statement to the head # of the list and updates the combobox if txt in self.findHistory: self.findHistory.remove(txt) self.findHistory.insert(0, txt) self.ui.findtextCombo.clear() self.ui.findtextCombo.addItems(self.findHistory) self.searchListChanged.emit() ok = self.__findNextPrev(txt, True) if ok: if self.__replace: self.__setReplaceSelectionEnabled(True) self.__setReplaceAndSearchEnabled(True) else: E5MessageBox.information( self, self.windowTitle(), self.tr("'{0}' was not found.").format(txt))
def on_testButton_clicked(self): """ Private slot to test the mail server login data. """ QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.processEvents() try: server = smtplib.SMTP(self.mailServerEdit.text(), self.portSpin.value(), timeout=10) if self.useTlsCheckBox.isChecked(): server.starttls() try: server.login(self.mailUserEdit.text(), self.mailPasswordEdit.text()) QApplication.restoreOverrideCursor() E5MessageBox.information( self, self.tr("Login Test"), self.tr("""The login test succeeded.""")) except (smtplib.SMTPException, socket.error) as e: QApplication.restoreOverrideCursor() if isinstance(e, smtplib.SMTPResponseException): errorStr = e.smtp_error.decode() elif isinstance(e, socket.timeout): errorStr = str(e) elif isinstance(e, socket.error): try: errorStr = e[1] except TypeError: errorStr = str(e) else: errorStr = str(e) E5MessageBox.critical( self, self.tr("Login Test"), self.tr( """<p>The login test failed.<br>Reason: {0}</p>""") .format(errorStr)) server.quit() except (smtplib.SMTPException, socket.error) as e: QApplication.restoreOverrideCursor() if isinstance(e, smtplib.SMTPResponseException): errorStr = e.smtp_error.decode() elif isinstance(e, socket.timeout): errorStr = str(e) elif isinstance(e, socket.error): try: errorStr = e[1] except TypeError: errorStr = str(e) else: errorStr = str(e) E5MessageBox.critical( self, self.tr("Login Test"), self.tr("""<p>The login test failed.<br>Reason: {0}</p>""") .format(errorStr))
def __getDomainReportFinished(self): """ Private slot to process the IP address report data. """ reply = self.sender() if reply.error() == QNetworkReply.NoError: result = json.loads(str(reply.readAll(), "utf-8")) if result["response_code"] == 0: E5MessageBox.information( None, self.tr("VirusTotal Domain Report"), self.tr("""VirusTotal does not have any information for""" """ the given domain.""")) elif result["response_code"] == -1: E5MessageBox.information( None, self.tr("VirusTotal Domain Report"), self.tr("""The submitted domain address is invalid.""")) else: resolutions = result["resolutions"] try: urls = result["detected_urls"] except KeyError: urls = [] try: subdomains = result["subdomains"] except KeyError: subdomains = [] try: bdCategory = result["BitDefender category"] except KeyError: bdCategory = self.tr("not available") try: tmCategory = result["TrendMicro category"] except KeyError: tmCategory = self.tr("not available") try: wtsCategory = result["Websense ThreatSeeker category"] except KeyError: wtsCategory = self.tr("not available") try: whois = result["whois"] except KeyError: whois = "" from .VirusTotalDomainReportDialog import \ VirusTotalDomainReportDialog self.__domainReportDlg = VirusTotalDomainReportDialog( self.__lastDomain, resolutions, urls, subdomains, bdCategory, tmCategory, wtsCategory, whois) self.__domainReportDlg.show() self.__replies.remove(reply) reply.deleteLater()
def __showDfuDisableInstructions(self): """ Private method to show some instructions to disable the DFU mode. """ msg = self.tr("<h3>Disable DFU Mode</h3>" "<p>1. Disconnect your board</p>" "<p>2. Remove the DFU jumper</p>" "<p>3. Re-connect your board</p>" "<hr />" "<p>Press <b>OK</b> to continue...</p>") E5MessageBox.information(self.microPython, self.tr("Disable DFU mode"), msg)
def __getDomainReportFinished(self, reply): """ Private slot to process the IP address report data. @param reply reference to the network reply @type QNetworkReply """ if reply.error() == QNetworkReply.NoError: result = json.loads(str(reply.readAll(), "utf-8")) if result["response_code"] == 0: E5MessageBox.information( None, self.tr("VirusTotal Domain Report"), self.tr("""VirusTotal does not have any information for""" """ the given domain.""")) elif result["response_code"] == -1: E5MessageBox.information( None, self.tr("VirusTotal Domain Report"), self.tr("""The submitted domain address is invalid.""")) else: resolutions = result["resolutions"] try: urls = result["detected_urls"] except KeyError: urls = [] try: subdomains = result["subdomains"] except KeyError: subdomains = [] try: bdCategory = result["BitDefender category"] except KeyError: bdCategory = self.tr("not available") try: tmCategory = result["TrendMicro category"] except KeyError: tmCategory = self.tr("not available") try: wtsCategory = result["Websense ThreatSeeker category"] except KeyError: wtsCategory = self.tr("not available") try: whois = result["whois"] except KeyError: whois = "" from .VirusTotalDomainReportDialog import ( VirusTotalDomainReportDialog) self.__domainReportDlg = VirusTotalDomainReportDialog( self.__lastDomain, resolutions, urls, subdomains, bdCategory, tmCategory, wtsCategory, whois) self.__domainReportDlg.show() self.__replies.remove(reply) reply.deleteLater()
def __forget(self): """ Private slot to handle the Remove context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getMissingItems()] if not names: E5MessageBox.information( self, self.tr("Remove"), self.tr("""There are no missing entries""" """ available/selected.""") ) return self.vcs.hgForget(names) self.on_refreshButton_clicked()
def on_validateButton_clicked(self): """ Private slot to validate the entered regexp. """ regex = self.regexpTextEdit.toPlainText() if regex: try: flags = 0 if not self.caseSensitiveCheckBox.isChecked(): flags |= re.IGNORECASE if self.multilineCheckBox.isChecked(): flags |= re.MULTILINE if self.dotallCheckBox.isChecked(): flags |= re.DOTALL if self.verboseCheckBox.isChecked(): flags |= re.VERBOSE if self.py2Button.isChecked(): if self.localeCheckBox.isChecked(): flags |= re.LOCALE if self.unicodeCheckBox.isChecked(): flags |= re.UNICODE else: if self.unicodeCheckBox.isChecked(): flags |= re.ASCII re.compile(regex, flags) E5MessageBox.information( self, self.tr("Validation"), self.tr("""The regular expression is valid.""")) except re.error as e: E5MessageBox.critical( self, self.tr("Error"), self.tr("""Invalid regular expression: {0}""") .format(str(e))) return except IndexError: E5MessageBox.critical( self, self.tr("Error"), self.tr("""Invalid regular expression: missing""" """ group name""")) return else: E5MessageBox.critical( self, self.tr("Error"), self.tr("""A regular expression must be given."""))
def __compileProtoDone(self, exitCode, exitStatus, grpc): """ Private slot to handle the finished signal of the protoc process. @param exitCode exit code of the process @type int @param exitStatus exit status of the process @type QProcess.ExitStatus @param grpc flag indicating to compile as gRPC files @type bool """ self.__compileRunning = False ui = e5App().getObject("UserInterface") if exitStatus == QProcess.NormalExit and exitCode == 0: path = os.path.dirname(self.__protoFile) fileList = glob.glob(os.path.join(path, "*_pb2.py")) if grpc: fileList += glob.glob(os.path.join(path, "*_pb2_grpc.py")) for file in fileList: self.project.appendFile(file) if not self.noDialog and not ui.notificationsEnabled(): E5MessageBox.information( self, self.tr("Protocol Compilation"), self.tr("The compilation of the protocol file was" " successful.")) else: if grpc: icon = UI.PixmapCache.getPixmap("gRPC48.png") else: icon = UI.PixmapCache.getPixmap("protobuf48.png") ui.showNotification( icon, self.tr("Protocol Compilation"), self.tr("The compilation of the protocol file was" " successful.")) else: if not self.noDialog: E5MessageBox.information( self, self.tr("Protocol Compilation"), self.tr("The compilation of the protocol file failed.")) else: if grpc: icon = UI.PixmapCache.getPixmap("gRPC48.png") else: icon = UI.PixmapCache.getPixmap("protobuf48.png") ui.showNotification( icon, self.tr("Protocol Compilation"), self.tr("The compilation of the protocol file failed.")) self.compileProc = None
def __showDfuEnableInstructions(self, flash=True): """ Private method to show some instructions to enable the DFU mode. @param flash flag indicating to show a warning message for flashing @type bool @return flag indicating OK to continue or abort @rtype bool """ msg = self.tr("<h3>Enable DFU Mode</h3>" "<p>1. Disconnect everything from your board</p>" "<p>2. Disconnect your board</p>" "<p>3. Connect the DFU/BOOT0 pin with a 3.3V pin</p>" "<p>4. Re-connect your board</p>" "<hr />") if flash: msg += self.tr( "<p><b>Warning:</b> Make sure that all other DFU capable" " devices except your PyBoard are disconnected." "<hr />") msg += self.tr("<p>Press <b>OK</b> to continue...</p>") res = E5MessageBox.information( self.microPython, self.tr("Enable DFU mode"), msg, E5MessageBox.StandardButtons(E5MessageBox.Abort | E5MessageBox.Ok)) return res == E5MessageBox.Ok
def __addPackage(self, pkgDir): """ Private method to add a package to the list. @param pkgDir name of the package directory (string) """ if pkgDir: if "\\" in pkgDir or "/" in pkgDir: # It is a directory. Check for an __init__.py file. if os.path.isabs(pkgDir): prefix = "" else: prefix = self.packageRootEdit.text() initName = os.path.join(prefix, Utilities.toNativeSeparators(pkgDir), "__init__.py") if not os.path.exists(initName): res = E5MessageBox.information( self, self.tr("Add Package"), self.tr("""<p>The directory <b>{0}</b> is not""" """ a Python package.</p>""").format(pkgDir), E5MessageBox.StandardButtons(E5MessageBox.Ignore | E5MessageBox.Ok)) if res == E5MessageBox.Ok: return pkg = pkgDir.replace( Utilities.toNativeSeparators(self.packageRootEdit.text()), "") if pkg.startswith(("\\", "/")): pkg = pkg[1:] if pkg: QListWidgetItem( pkg.replace("\\", ".").replace("/", "."), self.packagesList) self.packageEdit.clear()
def __unlock(self): """ Private slot to handle the Unlock context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getLockActionItems(self.lockedIndicators)] if not names: E5MessageBox.information( self, self.tr("Unlock"), self.tr("""There are no locked files""" """ available/selected.""")) return self.vcs.svnUnlock(names, parent=self) self.on_refreshButton_clicked()
def __showHelp(self): """ Private method to show some help. """ E5MessageBox.information( self, self.tr("Template Help"), self.tr( """<p><b>Template groups</b> are a means of grouping""" """ individual templates. Groups have an attribute that""" """ specifies, which programming language they apply for.""" """ In order to add template entries, at least one group""" """ has to be defined.</p>""" """<p><b>Template entries</b> are the actual templates.""" """ They are grouped by the template groups. Help about""" """ how to define them is available in the template edit""" """ dialog.</p>"""))
def __removeFromChangelist(self): """ Private slot to remove entries from their changelists. """ names = [ os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getChangelistItems() ] if not names: E5MessageBox.information( self, self.tr("Remove from Changelist"), self.tr("""There are no files available/selected belonging""" """ to a changelist.""")) return self.vcs.svnRemoveFromChangelist(names) self.on_refreshButton_clicked()
def __forget(self): """ Private slot to handle the Forget Missing context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getMissingItems()] if not names: E5MessageBox.information( self, self.tr("Forget Missing"), self.tr("""There are no missing entries""" """ available/selected.""")) return self.vcs.vcsRemove(names, stageOnly=True) self.on_refreshButton_clicked()
def __restoreMissing(self): """ Private slot to handle the Restore Missing context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getMissingItems()] if not names: E5MessageBox.information( self, self.tr("Revert"), self.tr("""There are no missing entries""" """ available/selected.""")) return self.vcs.vcsRevert(names) self.on_refreshButton_clicked() self.vcs.checkVCSStatus()
def __diff(self): """ Private slot to handle the Diff context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getModifiedItems()] if not names: E5MessageBox.information( self, self.tr("Differences"), self.tr("""There are no uncommitted changes""" """ available/selected.""") ) return if self.diff is None: from .HgDiffDialog import HgDiffDialog self.diff = HgDiffDialog(self.vcs) self.diff.show() self.diff.start(names, refreshable=True)
def __compileIDLDone(self, exitCode, exitStatus): """ Private slot to handle the finished signal of the omniidl process. @param exitCode exit code of the process (integer) @param exitStatus exit status of the process (QProcess.ExitStatus) """ self.compileRunning = False ui = e5App().getObject("UserInterface") if exitStatus == QProcess.NormalExit and exitCode == 0: path = os.path.dirname(self.idlFile) poaList = glob.glob(os.path.join(path, "*__POA")) npoaList = [f.replace("__POA", "") for f in poaList] fileList = glob.glob(os.path.join(path, "*_idl.py")) for dir in poaList + npoaList: fileList += Utilities.direntries(dir, True, "*.py") for file in fileList: self.project.appendFile(file) if not self.noDialog and not ui.notificationsEnabled(): E5MessageBox.information( self, self.tr("Interface Compilation"), self.tr( "The compilation of the interface file was" " successful.")) else: ui.showNotification( UI.PixmapCache.getPixmap("corba48.png"), self.tr("Interface Compilation"), self.tr( "The compilation of the interface file was" " successful.")) else: if not self.noDialog: E5MessageBox.information( self, self.tr("Interface Compilation"), self.tr( "The compilation of the interface file failed.")) else: ui.showNotification( UI.PixmapCache.getPixmap("corba48.png"), self.tr("Interface Compilation"), self.tr( "The compilation of the interface file failed.")) self.compileProc = None
def __addFeed(self): """ Private slot to add a RSS feed. """ button = self.sender() urlString = button.feed[1] url = QUrl(urlString) if not url.host(): if not urlString.startswith("/"): urlString = "/" + urlString urlString = self.__browser.url().host() + urlString tmpUrl = QUrl(urlString) if not tmpUrl.scheme(): urlString = "http://" + urlString tmpUrl = QUrl(urlString) if not tmpUrl.scheme() or not tmpUrl.host(): return if not url.isValid(): return if button.feed[0]: title = button.feed[0] else: title = self.__browser.url().host() import Helpviewer.HelpWindow feedsManager = Helpviewer.HelpWindow.HelpWindow.feedsManager() if feedsManager.addFeed(urlString, title, self.__browser.icon()): if Helpviewer.HelpWindow.HelpWindow.notificationsEnabled(): Helpviewer.HelpWindow.HelpWindow.showNotification( UI.PixmapCache.getPixmap("rss48.png"), self.tr("Add RSS Feed"), self.tr("""The feed was added successfully.""")) else: E5MessageBox.information( self, self.tr("Add RSS Feed"), self.tr("""The feed was added successfully.""")) else: E5MessageBox.warning( self, self.tr("Add RSS Feed"), self.tr("""The feed was already added before.""")) self.close()
def __add(self): """ Private slot to handle the Add context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getUnversionedItems()] if not names: E5MessageBox.information( self, self.tr("Add"), self.tr("""There are no unversioned entries""" """ available/selected.""") ) return self.vcs.vcsAdd(names) self.on_refreshButton_clicked() project = e5App().getObject("Project") for name in names: project.getModel().updateVCSStatus(name) self.vcs.checkVCSStatus()
def __removeFromChangelist(self): """ Private slot to remove entries from their changelists. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getChangelistItems()] if not names: E5MessageBox.information( self, self.tr("Remove from Changelist"), self.tr( """There are no files available/selected belonging""" """ to a changelist.""" ) ) return self.vcs.svnRemoveFromChangelist(names) self.on_refreshButton_clicked()
def hgQueueGuardsDropAll(self, name): """ Public method to drop all guards of the current or a named patch. @param name file/directory name (string) """ # find the root of the repo repodir = self.vcs.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return patchnames = sorted( self.__getPatchesList(repodir, Queues.SERIES_LIST)) if patchnames: patch, ok = QInputDialog.getItem( None, self.tr("Drop All Guards"), self.tr("Select the patch to drop guards for" " (leave empty for the current patch):"), [""] + patchnames, 0, False) if ok: args = self.vcs.initCommand("qguard") if patch: args.append(patch) args.append("--none") client = self.vcs.getClient() if client: client.runcommand(args) else: process = QProcess() process.setWorkingDirectory(repodir) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: process.waitForFinished(30000) else: E5MessageBox.information( None, self.tr("Drop All Guards"), self.tr("""No patches available to define guards for."""))
def __commit(self): """ Private slot to handle the Commit context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getCommitableItems()] if not names: E5MessageBox.information( self, self.tr("Commit"), self.tr("""There are no entries selected to be""" """ committed.""")) return if Preferences.getVCS("AutoSaveFiles"): vm = e5App().getObject("ViewManager") for name in names: vm.saveEditor(name) self.vcs.vcsCommit(names, '')
def __doReplace(self, searchNext): """ Private method to replace one occurrence of text. @param searchNext flag indicating to search for the next occurrence (boolean). """ self.__finding = True # Check enabled status due to dual purpose usage of this method if not self.ui.replaceButton.isEnabled() and \ not self.ui.replaceSearchButton.isEnabled(): return ftxt = self.ui.findtextCombo.currentText() rtxt = self.ui.replacetextCombo.currentText() # This moves any previous occurrence of this statement to the head # of the list and updates the combobox if rtxt in self.replaceHistory: self.replaceHistory.remove(rtxt) self.replaceHistory.insert(0, rtxt) self.ui.replacetextCombo.clear() self.ui.replacetextCombo.addItems(self.replaceHistory) aw = self.viewmanager.activeWindow() aw.hideFindIndicator() aw.replace(rtxt) if searchNext: ok = self.__findNextPrev(ftxt, self.__findBackwards) if not ok: self.ui.replaceButton.setEnabled(False) self.ui.replaceSearchButton.setEnabled(False) E5MessageBox.information( self, self.windowTitle(), self.tr("'{0}' was not found.").format(ftxt)) else: self.ui.replaceButton.setEnabled(False) self.ui.replaceSearchButton.setEnabled(False) self.__finding = False
def __downloadRepositoryFileDone(self): """ Private method called after the repository file was downloaded. """ reply = self.sender() if reply in self.__replies: self.__replies.remove(reply) if reply.error() != QNetworkReply.NoError: E5MessageBox.warning( None, self.tr("Error downloading file"), self.tr( """<p>Could not download the requested file""" """ from {0}.</p><p>Error: {1}</p>""" ).format(Preferences.getUI("PluginRepositoryUrl6"), reply.errorString()) ) return ioDevice = QFile(self.pluginRepositoryFile + ".tmp") ioDevice.open(QIODevice.WriteOnly) ioDevice.write(reply.readAll()) ioDevice.close() if QFile.exists(self.pluginRepositoryFile): QFile.remove(self.pluginRepositoryFile) ioDevice.rename(self.pluginRepositoryFile) if os.path.exists(self.pluginRepositoryFile): f = QFile(self.pluginRepositoryFile) if f.open(QIODevice.ReadOnly): # save current URL url = Preferences.getUI("PluginRepositoryUrl6") # read the repository file from E5XML.PluginRepositoryReader import PluginRepositoryReader reader = PluginRepositoryReader(f, self.checkPluginEntry) reader.readXML() if url != Preferences.getUI("PluginRepositoryUrl6"): # redo if it is a redirect self.checkPluginUpdatesAvailable() return if self.__updateAvailable: res = E5MessageBox.information( None, self.tr("New plugin versions available"), self.tr("<p>There are new plug-ins or plug-in" " updates available. Use the plug-in" " repository dialog to get them.</p>"), E5MessageBox.StandardButtons( E5MessageBox.Ignore | E5MessageBox.Open), E5MessageBox.Open) if res == E5MessageBox.Open: self.__ui.showPluginsAvailable()
def hgQueueFoldUnappliedPatches(self, name): """ Public method to fold patches into the current patch. @param name file/directory name (string) """ # find the root of the repo repodir = self.vcs.splitPath(name)[0] while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return args = self.vcs.initCommand("qfold") patchnames = sorted( self.__getPatchesList(repodir, Queues.UNAPPLIED_LIST, withSummary=True)) if patchnames: from .HgQueuesFoldDialog import HgQueuesFoldDialog dlg = HgQueuesFoldDialog(patchnames) if dlg.exec_() == QDialog.Accepted: message, patchesList = dlg.getData() if message: args.append("--message") args.append(message) if patchesList: args.extend(patchesList) dia = HgDialog(self.tr("Fold Patches"), self.vcs) res = dia.startProcess(args, repodir) if res: dia.exec_() else: E5MessageBox.information( None, self.tr("Fold Patches"), self.tr("""No patches selected.""")) else: E5MessageBox.information( None, self.tr("Fold Patches"), self.tr("""No patches available to be folded."""))
def __revert(self): """ Private slot to handle the Revert context menu entry. """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getModifiedItems()] if not names: E5MessageBox.information( self, self.tr("Revert"), self.tr("""There are no uncommitted changes""" """ available/selected.""") ) return self.vcs.hgRevert(names) self.raise_() self.activateWindow() self.on_refreshButton_clicked() project = e5App().getObject("Project") for name in names: project.getModel().updateVCSStatus(name) self.vcs.checkVCSStatus()
def __addWhitelist(self, origin): """ Private method to add a cookie origin to the whitelist. @param origin origin to be added to the list @type str """ if not origin: return if len(self.blackList.findItems(origin, Qt.MatchFixedString)) > 0: E5MessageBox.information( self, self.tr("Add to whitelist"), self.tr("""The server '{0}' is already in the blacklist.""" """ Please remove it first.""").format(origin)) return if len(self.whiteList.findItems(origin, Qt.MatchFixedString)) == 0: self.whiteList.addItem(origin)
def __lfAdd(self, mode): """ Private slot to add a file to the repository. @param mode add mode (string one of 'normal' or 'large') """ names = [os.path.join(self.dname, itm.text(self.__pathColumn)) for itm in self.__getUnversionedItems()] if not names: E5MessageBox.information( self, self.tr("Add"), self.tr("""There are no unversioned entries""" """ available/selected.""") ) return self.vcs.getExtensionObject("largefiles").hgAdd(names, mode) self.on_refreshButton_clicked() project = e5App().getObject("Project") for name in names: project.getModel().updateVCSStatus(name) self.vcs.checkVCSStatus()