def on_diffButton_clicked(self): """ Private slot to handle the Compare button press. """ filename1 = Utilities.toNativeSeparators(self.file1Edit.text()) try: f1 = open(filename1, "r", encoding="utf-8") lines1 = f1.readlines() f1.close() except IOError: E5MessageBox.critical( self, self.tr("Compare Files"), self.tr( """<p>The file <b>{0}</b> could not be read.</p>""") .format(filename1)) return filename2 = Utilities.toNativeSeparators(self.file2Edit.text()) try: f2 = open(filename2, "r", encoding="utf-8") lines2 = f2.readlines() f2.close() except IOError: E5MessageBox.critical( self, self.tr("Compare Files"), self.tr( """<p>The file <b>{0}</b> could not be read.</p>""") .format(filename2)) return self.__compare(lines1, lines2)
def on_bTest_clicked(self): """ Private method to test the selected options. """ if self.rColor.isChecked(): if not self.eColor.currentText(): QColorDialog.getColor() else: coStr = self.eColor.currentText() if coStr.startswith("#"): coStr = "QColor('{0}')".format(coStr) else: coStr = "QColor({0})".format(coStr) try: exec( "from PyQt5.QtCore import Qt;" ' QColorDialog.getColor({0}, None, "{1}")'.format(coStr, self.eTitle.text()) ) except: E5MessageBox.critical( self, self.tr("QColorDialog Wizard Error"), self.tr("""<p>The colour <b>{0}</b> is not valid.</p>""").format(coStr), ) elif self.rRGBA.isChecked(): QColorDialog.getColor( QColor(self.sRed.value(), self.sGreen.value(), self.sBlue.value(), self.sAlpha.value()), None, self.eTitle.text(), QColorDialog.ColorDialogOptions(QColorDialog.ShowAlphaChannel), )
def exportShortcuts(fn): """ Module function to export the keyboard shortcuts for the defined QActions. @param fn filename of the export file (string) """ # let the plugin manager create on demand plugin objects pm = e5App().getObject("PluginManager") pm.initOnDemandPlugins() f = QFile(fn) if f.open(QIODevice.WriteOnly): from E5XML.ShortcutsWriter import ShortcutsWriter ShortcutsWriter(f).writeXML() f.close() else: E5MessageBox.critical( None, QCoreApplication.translate( "Shortcuts", "Export Keyboard Shortcuts"), QCoreApplication.translate( "Shortcuts", "<p>The keyboard shortcuts could not be written to file" " <b>{0}</b>.</p>") .format(fn))
def on_newButton_clicked(self): """ Private slot to create a new toolbar. """ name, ok = QInputDialog.getText( self, self.tr("New Toolbar"), self.tr("Toolbar Name:"), QLineEdit.Normal) if ok and name: if self.toolbarComboBox.findText(name) != -1: # toolbar with this name already exists E5MessageBox.critical( self, self.tr("New Toolbar"), self.tr( """A toolbar with the name <b>{0}</b> already""" """ exists.""") .format(name)) return tbItem = E5ToolBarItem(None, [], False) tbItem.title = name tbItem.isChanged = True self.__toolbarItems[id(tbItem)] = tbItem self.__toolBarItemToWidgetActionID[id(tbItem)] = [] self.toolbarComboBox.addItem(name, int(id(tbItem))) self.toolbarComboBox.model().sort(0) self.toolbarComboBox.setCurrentIndex( self.toolbarComboBox.findText(name))
def on_renameButton_clicked(self): """ Private slot to rename a custom toolbar. """ oldName = self.toolbarComboBox.currentText() newName, ok = QInputDialog.getText( self, self.tr("Rename Toolbar"), self.tr("New Toolbar Name:"), QLineEdit.Normal, oldName) if ok and newName: if oldName == newName: return if self.toolbarComboBox.findText(newName) != -1: # toolbar with this name already exists E5MessageBox.critical( self, self.tr("Rename Toolbar"), self.tr( """A toolbar with the name <b>{0}</b> already""" """ exists.""") .format(newName)) return index = self.toolbarComboBox.currentIndex() self.toolbarComboBox.setItemText(index, newName) tbItem = \ self.__toolbarItems[self.toolbarComboBox.itemData(index)] tbItem.title = newName tbItem.isChanged = True
def addEntry(self, name, description, template, quiet=False): """ Public method to add a template entry to this group. @param name name of the entry (string) @param description description of the entry to add (string) @param template template text of the entry (string) @param quiet flag indicating quiet operation (boolean) """ if name in self.entries: if not quiet: E5MessageBox.critical( None, QCoreApplication.translate("TemplateGroup", "Add Template"), QCoreApplication.translate( "TemplateGroup", """<p>The group <b>{0}</b> already contains a""" """ template named <b>{1}</b>.</p>""") .format(self.name, name)) return self.entries[name] = TemplateEntry(self, name, description, template) if Preferences.getTemplates("AutoOpenGroups") and \ not self.isExpanded(): self.setExpanded(True)
def __startServer(self): """ Private slot to start the Mercurial server. """ port = self.__portSpin.value() style = self.__styleCombo.currentText() args = self.vcs.initCommand("serve") args.append("-v") args.append("--port") args.append(str(port)) args.append("--style") args.append(style) self.process.setWorkingDirectory(self.__repoPath) self.process.start('hg', args) procStarted = self.process.waitForStarted(5000) if procStarted: self.__startAct.setEnabled(False) self.__stopAct.setEnabled(True) self.__browserAct.setEnabled(True) self.__portSpin.setEnabled(False) self.__styleCombo.setEnabled(False) self.vcs.getPlugin().setPreferences("ServerPort", port) self.vcs.getPlugin().setPreferences("ServerStyle", style) else: E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('hg'))
def exportBookmarks(self): """ Public method to export the bookmarks. """ fileName, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( None, self.tr("Export Bookmarks"), "eric6_bookmarks.xbel", self.tr("XBEL bookmarks (*.xbel);;" "XBEL bookmarks (*.xml);;" "HTML Bookmarks (*.html)")) if not fileName: return ext = QFileInfo(fileName).suffix() if not ext: ex = selectedFilter.split("(*")[1].split(")")[0] if ex: fileName += ex ext = QFileInfo(fileName).suffix() if ext == "html": from .NsHtmlWriter import NsHtmlWriter writer = NsHtmlWriter() else: from .XbelWriter import XbelWriter writer = XbelWriter() if not writer.write(fileName, self.__bookmarkRootNode): E5MessageBox.critical( None, self.tr("Exporting Bookmarks"), self.tr("""Error exporting bookmarks to <b>{0}</b>.""") .format(fileName))
def __startProc(self, applName, *applArgs): """ Private method to start an eric6 application. @param applName name of the eric6 application script (string) @param *applArgs variable list of application arguments """ proc = QProcess() applPath = os.path.join(getConfig("ericDir"), applName) args = [] args.append(applPath) for arg in applArgs: args.append(arg) if not os.path.isfile(applPath) or \ not proc.startDetached(sys.executable, args): E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( '<p>Could not start the process.<br>' 'Ensure that it is available as <b>{0}</b>.</p>' ).format(applPath), self.tr('OK'))
def writeTemplates(self, filename=None): """ Public method to write the templates data to an XML file (.e4c). @param filename name of a templates file to read (string) @return flag indicating success (boolean) """ if filename is None: filename = os.path.join( Utilities.getConfigDir(), "eric6templates.e4c") f = QFile(filename) ok = f.open(QIODevice.WriteOnly) if not ok: E5MessageBox.critical( self, self.tr("Save templates"), self.tr( "<p>The templates file <b>{0}</b> could not be" " written.</p>") .format(filename)) return False from E5XML.TemplatesWriter import TemplatesWriter TemplatesWriter(f, self).writeXML() f.close() return True
def __printPdfRequested(self, frame): """ Private slot to handle a print to PDF request. @param frame reference to the frame to be printed (QWebFrame) """ printer = QPrinter(mode=QPrinter.HighResolution) if Preferences.getPrinter("ColorMode"): printer.setColorMode(QPrinter.Color) else: printer.setColorMode(QPrinter.GrayScale) printerName = Preferences.getPrinter("PrinterName") if printerName: printer.setPrinterName(printerName) printer.setOutputFormat(QPrinter.PdfFormat) name = frame.url().path().rsplit('/', 1)[-1] if name: name = name.rsplit('.', 1)[0] name += '.pdf' printer.setOutputFileName(name) printDialog = QPrintDialog(printer, self) if printDialog.exec_() == QDialog.Accepted: try: frame.print_(printer) except AttributeError: E5MessageBox.critical( self, self.tr("eric6 Web Browser"), self.tr( """<p>Printing is not available due to a bug in""" """ PyQt5. Please upgrade.</p>""")) return
def __importCertificate(self): """ Private method to read a certificate. @return certificates read (list of QSslCertificate) """ fname = E5FileDialog.getOpenFileName( self, self.tr("Import Certificate"), "", self.tr("Certificate Files (*.pem *.crt *.der *.cer *.ca);;" "All Files (*)"), ) if fname: f = QFile(fname) if not f.open(QIODevice.ReadOnly): E5MessageBox.critical( self, self.tr("Export Certificate"), self.tr( """<p>The certificate could not be read from file""" """ <b>{0}</b></p><p>Error: {1}</p>""" ).format(fname, f.errorString()), ) return [] crt = f.readAll() f.close() cert = QSslCertificate.fromData(crt, QSsl.Pem) if not cert: cert = QSslCertificate.fromData(crt, QSsl.Der) return cert return []
def readTemplates(self, filename=None): """ Public method to read in the templates file (.e4c). @param filename name of a templates file to read (string) """ if filename is None: filename = os.path.join( Utilities.getConfigDir(), "eric6templates.e4c") if not os.path.exists(filename): return f = QFile(filename) if f.open(QIODevice.ReadOnly): from E5XML.TemplatesReader import TemplatesReader reader = TemplatesReader(f, viewer=self) reader.readXML() f.close() else: E5MessageBox.critical( self, self.tr("Read templates"), self.tr( "<p>The templates file <b>{0}</b> could not be read.</p>") .format(filename))
def on_saveButton_clicked(self): """ Private slot to handle the Save button press. It saves the diff shown in the dialog to a file in the local filesystem. """ if isinstance(self.filename, list): if len(self.filename) > 1: fname = self.vcs.splitPathList(self.filename)[0] else: dname, fname = self.vcs.splitPath(self.filename[0]) if fname != ".": fname = "{0}.diff".format(self.filename[0]) else: fname = dname else: fname = self.vcs.splitPath(self.filename)[0] fname, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( self, self.tr("Save Diff"), fname, self.tr("Patch Files (*.diff)"), None, E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite), ) if not fname: return # user aborted ext = QFileInfo(fname).suffix() if not ext: ex = selectedFilter.split("(*")[1].split(")")[0] if ex: fname += ex if QFileInfo(fname).exists(): res = E5MessageBox.yesNo( self, self.tr("Save Diff"), self.tr("<p>The patch file <b>{0}</b> already exists." " Overwrite it?</p>").format(fname), icon=E5MessageBox.Warning, ) if not res: return fname = Utilities.toNativeSeparators(fname) eol = e5App().getObject("Project").getEolString() try: f = open(fname, "w", encoding="utf-8", newline="") f.write(eol.join(self.contents.toPlainText().splitlines())) f.close() except IOError as why: E5MessageBox.critical( self, self.tr("Save Diff"), self.tr("<p>The patch file <b>{0}</b> could not be saved." "<br>Reason: {1}</p>").format( fname, str(why) ), )
def on_changeButton_clicked(self): """ Private slot to change an entry. """ row = self.groupsList.currentRow() if row < 0: return groupName = self.nameEdit.text() if not groupName: E5MessageBox.critical( self, self.tr("Add tool group entry"), self.tr("You have to give a name for the group to add.")) return if len(self.groupsList.findItems( groupName, Qt.MatchFlags(Qt.MatchExactly))): E5MessageBox.critical( self, self.tr("Add tool group entry"), self.tr("An entry for the group name {0} already exists.") .format(groupName)) return self.toolGroups[row][0] = groupName self.groupsList.currentItem().setText(groupName)
def __checkPluginsDownloadDirectory(self): """ Private slot to check for the existence of the plugins download directory. """ downloadDir = Preferences.getPluginManager("DownloadPath") if not downloadDir: downloadDir = self.__defaultDownloadDir if not os.path.exists(downloadDir): try: os.mkdir(downloadDir, 0o755) except (OSError, IOError) as err: # try again with (possibly) new default downloadDir = self.__defaultDownloadDir if not os.path.exists(downloadDir): try: os.mkdir(downloadDir, 0o755) except (OSError, IOError) as err: E5MessageBox.critical( self.__ui, self.tr("Plugin Manager Error"), self.tr( """<p>The plugin download directory""" """ <b>{0}</b> could not be created. Please""" """ configure it via the configuration""" """ dialog.</p><p>Reason: {1}</p>""") .format(downloadDir, str(err))) downloadDir = "" Preferences.setPluginManager("DownloadPath", downloadDir)
def __printPreviewImage(self): """ Private slot to handle the Print Preview menu action. """ from PyQt5.QtPrintSupport import QPrintPreviewDialog if self.mainWidget is None: E5MessageBox.critical( self, self.tr("Print Preview"), self.tr("""There is no UI file loaded.""")) return settings = Preferences.Prefs.settings printer = QPrinter(QPrinter.HighResolution) printer.setFullPage(True) printerName = Preferences.getPrinter("UIPreviewer/printername") if printerName: printer.setPrinterName(printerName) printer.setPageSize( QPrinter.PageSize(int(settings.value("UIPreviewer/pagesize")))) printer.setPageOrder( QPrinter.PageOrder(int(settings.value("UIPreviewer/pageorder")))) printer.setOrientation(QPrinter.Orientation( int(settings.value("UIPreviewer/orientation")))) printer.setColorMode( QPrinter.ColorMode(int(settings.value("UIPreviewer/colormode")))) preview = QPrintPreviewDialog(printer, self) preview.paintRequested.connect(self.__print) preview.exec_()
def importShortcuts(fn): """ Module function to import the keyboard shortcuts for the defined E5Actions. @param fn filename of the import file (string) """ # let the plugin manager create on demand plugin objects pm = e5App().getObject("PluginManager") pm.initOnDemandPlugins() f = QFile(fn) if f.open(QIODevice.ReadOnly): from E5XML.ShortcutsReader import ShortcutsReader reader = ShortcutsReader(f) reader.readXML() f.close() if not reader.hasError(): shortcuts = reader.getShortcuts() setActions(shortcuts) saveShortcuts() syncPreferences() else: E5MessageBox.critical( None, QCoreApplication.translate( "Shortcuts", "Import Keyboard Shortcuts"), QCoreApplication.translate( "Shortcuts", "<p>The keyboard shortcuts could not be read from file" " <b>{0}</b>.</p>") .format(fn)) return
def on_addButton_clicked(self): """ Private slot to add a new idntity. """ name, ok = QInputDialog.getText( self, self.tr("Add Identity"), self.tr("Identity Name:"), QLineEdit.Normal) if ok: if name: if name in self.__identities: E5MessageBox.critical( self, self.tr("Add Identity"), self.tr( """An identity named <b>{0}</b> already exists.""" """ You must provide a different name.""").format( name)) self.on_addButton_clicked() else: identity = IrcIdentity(name) identity.setIdent(Utilities.getUserName()) identity.setRealName(Utilities.getRealName()) self.__identities[name] = identity self.identitiesCombo.addItem(name) self.identitiesCombo.setCurrentIndex( self.identitiesCombo.count() - 1) else: E5MessageBox.critical( self, self.tr("Add Identity"), self.tr("""The identity has to have a name.""")) self.on_addButton_clicked()
def on_renameButton_clicked(self): """ Private slot to rename the selected identity. """ currentIdentity = self.identitiesCombo.currentText() name, ok = QInputDialog.getText( self, self.tr("Rename Identity"), self.tr("Identity Name:"), QLineEdit.Normal, currentIdentity) if ok and name != currentIdentity: if name: if name in self.__identities: E5MessageBox.critical( self, self.tr("Rename Identity"), self.tr( """An identity named <b>{0}</b> already exists.""" """ You must provide a different name.""").format( name)) self.on_renameButton_clicked() else: del self.__identities[currentIdentity] self.__currentIdentity.setName(name) self.__identities[name] = self.__currentIdentity self.identitiesCombo.setItemText( self.identitiesCombo.currentIndex(), name) else: E5MessageBox.critical( self, self.tr("Copy Identity"), self.tr("""The identity has to have a name.""")) self.on_renameButton_clicked()
def __checkFileFilter(self, filter): """ Private method to check a file filter for validity. @param filter file filter pattern to check (string) @return flag indicating validity (boolean) """ if not self.__showsOpenFilters and \ filter.count("*") != 1: E5MessageBox.critical( self, self.tr("Add File Filter"), self.tr("""A Save File Filter must contain exactly one""" """ wildcard pattern. Yours contains {0}.""") .format(filter.count("*"))) return False if filter.count("*") == 0: E5MessageBox.critical( self, self.tr("Add File Filter"), self.tr("""A File Filter must contain at least one""" """ wildcard pattern.""")) return False return True
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 __addNewPackage(self): """ Private method to add a new package to the project. """ itm = self.model().item(self.currentIndex()) if isinstance(itm, ProjectBrowserFileItem) or \ isinstance(itm, BrowserClassItem) or \ isinstance(itm, BrowserMethodItem): dn = os.path.dirname(itm.fileName()) elif isinstance(itm, ProjectBrowserSimpleDirectoryItem) or \ isinstance(itm, ProjectBrowserDirectoryItem): dn = itm.dirName() else: dn = "" dn = self.project.getRelativePath(dn) if dn.startswith(os.sep): dn = dn[1:] from .NewPythonPackageDialog import NewPythonPackageDialog dlg = NewPythonPackageDialog(dn, self) if dlg.exec_() == QDialog.Accepted: packageName = dlg.getData() nameParts = packageName.split(".") packagePath = self.project.ppath packageFile = "" for name in nameParts: packagePath = os.path.join(packagePath, name) if not os.path.exists(packagePath): try: os.mkdir(packagePath) except OSError as err: E5MessageBox.critical( self, self.tr("Add new Python package"), self.tr( """<p>The package directory <b>{0}</b> could""" """ not be created. Aborting...</p>""" """<p>Reason: {1}</p>""") .format(packagePath, str(err))) return packageFile = os.path.join(packagePath, "__init__.py") if not os.path.exists(packageFile): try: f = open(packageFile, "w", encoding="utf-8") f.close() except IOError as err: E5MessageBox.critical( self, self.tr("Add new Python package"), self.tr( """<p>The package file <b>{0}</b> could""" """ not be created. Aborting...</p>""" """<p>Reason: {1}</p>""") .format(packageFile, str(err))) return self.project.appendFile(packageFile) if packageFile: self.sourceFile[str].emit(packageFile)
def __saveAs(self, filename=""): """ Private slot to save the diagram. @param filename name of the file to write to (string) """ if not filename: fname, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( self, self.tr("Save Diagram"), "", self.tr("Eric Graphics File (*.e5g);;All Files (*)"), "", E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) if not fname: return ext = QFileInfo(fname).suffix() if not ext: ex = selectedFilter.split("(*")[1].split(")")[0] if ex: fname += ex if QFileInfo(fname).exists(): res = E5MessageBox.yesNo( self, self.tr("Save Diagram"), self.tr("<p>The file <b>{0}</b> already exists." " Overwrite it?</p>").format(fname), icon=E5MessageBox.Warning) if not res: return filename = fname lines = [ "version: 1.0", "diagram_type: {0} ({1})".format( self.__diagramType, self.__diagramTypeString()), "scene_size: {0};{1}".format(self.scene.width(), self.scene.height()), ] persistenceData = self.builder.getPersistenceData() if persistenceData: lines.append("builder_data: {0}".format(persistenceData)) lines.extend(self.umlView.getPersistenceData()) try: f = open(filename, "w", encoding="utf-8") f.write("\n".join(lines)) f.close() except (IOError, OSError) as err: E5MessageBox.critical( self, self.tr("Save Diagram"), self.tr( """<p>The file <b>{0}</b> could not be saved.</p>""" """<p>Reason: {1}</p>""").format(filename, str(err))) return self.__fileName = filename
def on_diffButton_clicked(self): """ Private slot to handle the Compare button press. """ self.filename1 = Utilities.toNativeSeparators(self.file1Edit.text()) try: filemtime1 = time.ctime(os.stat(self.filename1).st_mtime) except IOError: filemtime1 = "" try: f1 = open(self.filename1, "r", encoding="utf-8") lines1 = f1.readlines() f1.close() except IOError: E5MessageBox.critical( self, self.tr("Compare Files"), self.tr( """<p>The file <b>{0}</b> could not be read.</p>""") .format(self.filename1)) return self.filename2 = Utilities.toNativeSeparators(self.file2Edit.text()) try: filemtime2 = time.ctime(os.stat(self.filename2).st_mtime) except IOError: filemtime2 = "" try: f2 = open(self.filename2, "r", encoding="utf-8") lines2 = f2.readlines() f2.close() except IOError: E5MessageBox.critical( self, self.tr("Compare Files"), self.tr( """<p>The file <b>{0}</b> could not be read.</p>""") .format(self.filename2)) return self.contents.clear() self.saveButton.setEnabled(False) if self.unifiedRadioButton.isChecked(): self.__generateUnifiedDiff( lines1, lines2, self.filename1, self.filename2, filemtime1, filemtime2) else: self.__generateContextDiff( lines1, lines2, self.filename1, self.filename2, filemtime1, filemtime2) tc = self.contents.textCursor() tc.movePosition(QTextCursor.Start) self.contents.setTextCursor(tc) self.contents.ensureCursorVisible() self.saveButton.setEnabled(True)
def __getParents(self, rev): """ Private method to get the parents of the currently viewed file/directory. @param rev revision number to get parents for (string) @return list of parent revisions (list of strings) """ errMsg = "" parents = [] if int(rev) > 0: args = self.vcs.initCommand("parents") if self.mode == "incoming": if self.bundle: args.append("--repository") args.append(self.bundle) elif self.vcs.bundleFile and \ os.path.exists(self.vcs.bundleFile): args.append("--repository") args.append(self.vcs.bundleFile) args.append("--template") args.append("{rev}:{node|short}\n") args.append("-r") args.append(rev) if not self.projectMode: args.append(self.filename) output = "" if self.__hgClient: output, errMsg = self.__hgClient.runcommand(args) else: process = QProcess() process.setWorkingDirectory(self.repodir) process.start('hg', args) procStarted = process.waitForStarted(5000) if procStarted: finished = process.waitForFinished(30000) if finished and process.exitCode() == 0: output = str(process.readAllStandardOutput(), self.vcs.getEncoding(), 'replace') else: if not finished: errMsg = self.tr( "The hg process did not finish within 30s.") else: errMsg = self.tr("Could not start the hg executable.") if errMsg: E5MessageBox.critical( self, self.tr("Mercurial Error"), errMsg) if output: parents = [p for p in output.strip().splitlines()] return parents
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 __getSeries(self, missing=False): """ Private slot to get the list of applied, unapplied and guarded patches and patches missing in the series file. @param missing flag indicating to get the patches missing in the series file (boolean) """ if missing: self.__mode = "missing" else: self.__mode = "qseries" args = self.vcs.initCommand("qseries") args.append('--summary') args.append('--verbose') if missing: args.append('--missing') if self.__hgClient: self.inputGroup.setEnabled(False) self.inputGroup.hide() out, err = self.__hgClient.runcommand(args) if err: self.__showError(err) if out: for line in out.splitlines(): self.__processOutputLine(line) if self.__hgClient.wasCanceled(): self.__mode = "" break if self.__mode == "qseries": self.__getSeries(True) elif self.__mode == "missing": self.__getTop() else: self.__finish() else: self.process.kill() self.process.setWorkingDirectory(self.__repodir) self.process.start('hg', args) procStarted = self.process.waitForStarted(5000) if not procStarted: self.inputGroup.setEnabled(False) self.inputGroup.hide() E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('hg')) else: self.inputGroup.setEnabled(True) self.inputGroup.show()
def startProcess(self, args, workingDir=None, setLanguage=False): """ Public slot used to start the process. @param args list of arguments for the process (list of strings) @param workingDir working directory for the process (string) @param setLanguage flag indicating to set the language to "C" (boolean) @return flag indicating a successful start of the process """ self.errorGroup.hide() self.normal = False self.intercept = False self.__hasAddOrDelete = False self.proc = QProcess() if setLanguage: env = QProcessEnvironment.systemEnvironment() env.insert("LANG", "C") self.proc.setProcessEnvironment(env) nargs = [] lastWasPwd = False for arg in args: if lastWasPwd: lastWasPwd = True continue nargs.append(arg) if arg == '--password': lastWasPwd = True nargs.append('*****') self.resultbox.append(' '.join(nargs)) self.resultbox.append('') self.proc.finished.connect(self.__procFinished) self.proc.readyReadStandardOutput.connect(self.__readStdout) self.proc.readyReadStandardError.connect(self.__readStderr) if workingDir: self.proc.setWorkingDirectory(workingDir) self.proc.start('svn', args) procStarted = self.proc.waitForStarted(5000) if not procStarted: self.buttonBox.setFocus() self.inputGroup.setEnabled(False) self.inputGroup.hide() E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('svn')) else: self.inputGroup.setEnabled(True) self.inputGroup.show() return procStarted
def start(self, path, bookmarksList): """ Public slot to start the bookmarks command. @param path name of directory to be listed (string) @param bookmarksList reference to string list receiving the bookmarks (list of strings) """ self.errorGroup.hide() self.intercept = False self.activateWindow() self.__bookmarksList = bookmarksList dname, fname = self.vcs.splitPath(path) # find the root of the repo repodir = dname 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("bookmarks") if self.__hgClient: self.inputGroup.setEnabled(False) self.inputGroup.hide() out, err = self.__hgClient.runcommand(args) if err: self.__showError(err) if out: for line in out.splitlines(): self.__processOutputLine(line) if self.__hgClient.wasCanceled(): break self.__finish() else: self.process.kill() self.process.setWorkingDirectory(repodir) self.process.start('hg', args) procStarted = self.process.waitForStarted(5000) if not procStarted: self.inputGroup.setEnabled(False) self.inputGroup.hide() E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('hg')) else: self.inputGroup.setEnabled(True) self.inputGroup.show()
def on_addButton_clicked(self): """ Private slot to add a new entry. """ menutext = self.menuEdit.text() icon = self.iconEdit.text() executable = self.executableEdit.text() arguments = self.argumentsEdit.text() redirect = self.redirectionModes[self.redirectCombo.currentIndex()][0] if not executable: E5MessageBox.critical( self, self.tr("Add tool entry"), self.tr("You have to set an executable to add to the" " Tools-Menu first.")) return if not menutext: E5MessageBox.critical( self, self.tr("Add tool entry"), self.tr("You have to insert a menuentry text to add the" " selected program to the Tools-Menu first.")) return if not Utilities.isinpath(executable): E5MessageBox.critical( self, self.tr("Add tool entry"), self.tr("The selected file could not be found or" " is not an executable." " Please choose an executable filename.")) return if len( self.toolsList.findItems(menutext, Qt.MatchFlags(Qt.MatchExactly))): E5MessageBox.critical( self, self.tr("Add tool entry"), self.tr("An entry for the menu text {0} already exists."). format(menutext)) return self.toolsList.addItem(menutext) tool = { 'menutext': menutext, 'icon': icon, 'executable': executable, 'arguments': arguments, 'redirect': redirect, } self.toollist.append(tool)
def __getStashEntries(self): """ Private method to retrieve the list of stashes. """ self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.inputGroup.setEnabled(True) self.inputGroup.show() self.refreshButton.setEnabled(False) QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.processEvents() self.buf = [] self.errors.clear() self.intercept = False args = self.vcs.initCommand("stash") args.append("list") args.append("--format=format:%gd{0}%ai{0}%gs%n".format(self.Separator)) self.process.kill() self.process.setWorkingDirectory(self.repodir) self.inputGroup.setEnabled(True) self.inputGroup.show() self.process.start('git', args) procStarted = self.process.waitForStarted(5000) if not procStarted: self.inputGroup.setEnabled(False) self.inputGroup.hide() E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.').format('git'))
def __getTop(self): """ Private slot to get patch at the top of the stack. """ self.__mode = "qtop" args = self.vcs.initCommand("qtop") if self.__hgClient: self.inputGroup.setEnabled(False) self.inputGroup.hide() out, err = self.__hgClient.runcommand(args) if err: self.__showError(err) if out: for line in out.splitlines(): self.__processOutputLine(line) if self.__hgClient.wasCanceled(): break self.__finish() else: self.process.kill() self.process.setWorkingDirectory(self.__repodir) self.process.start('hg', args) procStarted = self.process.waitForStarted(5000) if not procStarted: self.inputGroup.setEnabled(False) self.inputGroup.hide() E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('hg')) else: self.inputGroup.setEnabled(True) self.inputGroup.show()
def __readMultiProject(self, fn): """ Private method to read in a multi project (.e4m, .e5m) file. @param fn filename of the multi project file to be read (string) @return flag indicating success """ f = QFile(fn) if f.open(QIODevice.ReadOnly): from E5XML.MultiProjectReader import MultiProjectReader reader = MultiProjectReader(f, self) reader.readXML() f.close() if reader.hasError(): return False else: QApplication.restoreOverrideCursor() E5MessageBox.critical( self.ui, self.tr("Read multiproject file"), self.tr( "<p>The multiproject file <b>{0}</b> could not be" " read.</p>").format(fn)) return False self.pfile = os.path.abspath(fn) self.ppath = os.path.abspath(os.path.dirname(fn)) self.__extractCategories() # insert filename into list of recently opened multi projects self.__syncRecent() self.name = os.path.splitext(os.path.basename(fn))[0] # check, if the files of the multi project still exist self.__checkFilesExist() return True
def __loadNonXml(self, agentFile): """ Private method to load non-XML user agent files. This method is to convert from the old, non-XML format to the new XML based format. @param agentFile name of the non-XML user agent file (string) """ if os.path.exists(agentFile): try: f = open(agentFile, "r", encoding="utf-8") lines = f.read() f.close() except IOError as err: E5MessageBox.critical( None, self.tr("Loading user agent data"), self.tr("""<p>User agent data could not be loaded """ """from <b>{0}</b></p>""" """<p>Reason: {1}</p>""") .format(agentFile, str(err))) return for line in lines.splitlines(): if not line or \ line.startswith("#") or \ "@@" not in line: continue host, agent = line.split("@@", 1) self.__agents[host] = agent os.remove(agentFile) self.__loaded = True # this does the conversion self.save()
def __finish(self): """ Private slot called when the process finished or the user pressed the cancel button. """ self.__stopProcess() self.__processOutput() self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.buttonBox.button(QDialogButtonBox.Close).setFocus( Qt.OtherFocusReason) self.__refreshButton.setEnabled(True) if self.packageList.topLevelItemCount() == 0: QTreeWidgetItem(self.packageList, [self.__nothingStrings[self.__mode]]) if self.__errors and not self.__errors.startswith("DEPRECATION"): E5MessageBox.critical( self, self.windowTitle(), self.tr("""<p>The pip command failed.</p>""" """<p>Reason: {0}</p>""").format( self.__errors.replace("\r\n", "<br/>").replace( "\n", "<br/>").replace("\r", "<br/>").replace( " ", " "))) if self.__upgradeAllButton is not None: self.__upgradeAllButton.setEnabled(False) else: if self.__upgradeAllButton is not None: self.__upgradeAllButton.setEnabled(True) self.packageList.sortItems( 0, self.packageList.header().sortIndicatorOrder()) self.packageList.header().resizeSections(QHeaderView.ResizeToContents) self.packageList.header().setStretchLastSection(True)
def __requireDownloaded(self): """ Private slot to handle the finished download of a required script. """ if self.sender() != self.__reply: self.finished.emit() return response = bytes(self.__reply.readAll()).decode() if self.__reply.error() == QNetworkReply.NoError and response: from Helpviewer import HelpUtilities filePath = os.path.join(self.__manager.requireScriptsDirectory(), "require.js") fileName = HelpUtilities.ensureUniqueFilename(filePath, "{0}") try: f = open(fileName, "w", encoding="utf-8") except (IOError, OSError) as err: E5MessageBox.critical( None, self.tr("GreaseMonkey Download"), self.tr("""<p>The file <b>{0}</b> could not be opened""" """ for writing.<br/>Reason: {1}</p>""").format( fileName, str(err))) self.finished.emit() return f.write(response) f.close() settings = QSettings( os.path.join(self.__manager.requireScriptsDirectory(), "requires.ini"), QSettings.IniFormat) settings.beginGroup("Files") settings.setValue(self.__reply.originalUrl().toString(), fileName) self.__reply.deleteLater() self.__reply = None self.__downloadRequires()
def start(self, fn, noEntries=0): """ Public slot to start the cvs log command. @param fn filename to show the log for (string) @param noEntries number of entries to show (integer) """ self.errorGroup.hide() QApplication.processEvents() self.intercept = False self.filename = fn self.dname, self.fname = self.vcs.splitPath(fn) self.process.kill() args = [] args.append('log') self.vcs.addArguments(args, self.vcs.options['global']) self.vcs.addArguments(args, self.vcs.options['log']) if noEntries: args.append('--limit') args.append(str(noEntries)) self.activateWindow() self.raise_() args.append(self.fname) self.process.setWorkingDirectory(self.dname) self.process.start('svn', args) procStarted = self.process.waitForStarted(5000) if not procStarted: self.inputGroup.setEnabled(False) E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.').format('svn'))
def exportSource(self): """ Public method performing the export. """ filename = self._getFileName(self.tr("ODT Files (*.odt)")) if not filename: return QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.processEvents() tabSize = Preferences.getEditor("TabWidth") if tabSize == 0: tabSize = 4 wysiwyg = Preferences.getEditorExporter("ODT/WYSIWYG") onlyStylesUsed = Preferences.getEditorExporter("ODT/OnlyStylesUsed") tabs = Preferences.getEditorExporter("ODT/UseTabs") # generate HTML of the source generator = HTMLGenerator(self.editor) html = generator.generate(tabSize=tabSize, useTabs=tabs, wysiwyg=wysiwyg, folding=False, onlyStylesUsed=onlyStylesUsed, titleFullPath=False) # convert HTML to ODT doc = QTextDocument() doc.setHtml(html) writer = QTextDocumentWriter(filename) ok = writer.write(doc) QApplication.restoreOverrideCursor() if not ok: E5MessageBox.critical( self.editor, self.tr("Export source"), self.tr("""<p>The source could not be exported to""" """ <b>{0}</b>.</p>""").format(filename))
def __importStyles(self, lexers): """ Private method to import the styles of the given lexers. @param lexers dictionary of lexer objects for which to import the styles """ from eric6config import getConfig stylesDir = getConfig("ericStylesDir") fn = E5FileDialog.getOpenFileName( self, self.tr("Import Highlighting Styles"), stylesDir, self.tr("Highlighting styles file (*.e6h *.e4h)")) if not fn: return f = QFile(fn) if f.open(QIODevice.ReadOnly): from E5XML.HighlightingStylesReader import HighlightingStylesReader reader = HighlightingStylesReader(f, lexers) reader.readXML() f.close() else: E5MessageBox.critical( self, self.tr("Import Highlighting Styles"), self.tr( """<p>The highlighting styles could not be read""" """ from file <b>{0}</b>.</p><p>Reason: {1}</p>""") .format(fn, f.errorString()) ) return self.on_lexerLanguageComboBox_activated( self.lexerLanguageComboBox.currentText())
def __checkCurrentIdentity(self): """ Private method to check the data for the current identity. @return flag indicating a successful check (boolean) """ if self.nicknamesList.count() == 0: E5MessageBox.critical( self, self.tr("Edit Identity"), self.tr( """The identity must contain at least one nick name.""")) block = self.identitiesCombo.blockSignals(True) identity = self.__currentIdentity.getName() if identity == IrcIdentity.DefaultIdentityName: identity = IrcIdentity.DefaultIdentityDisplay self.identitiesCombo.setCurrentIndex( self.identitiesCombo.findText(identity)) self.identitiesCombo.blockSignals(block) self.identityTabWidget.setCurrentIndex(0) self.nicknameEdit.setFocus() return False if not self.realnameEdit.text(): E5MessageBox.critical( self, self.tr("Edit Identity"), self.tr("""The identity must have a real name.""")) block = self.identitiesCombo.blockSignals(True) identity = self.__currentIdentity.getName() if identity == IrcIdentity.DefaultIdentityName: identity = IrcIdentity.DefaultIdentityDisplay self.identitiesCombo.setCurrentIndex( self.identitiesCombo.findText(identity)) self.identitiesCombo.blockSignals(block) self.identityTabWidget.setCurrentIndex(0) self.realnameEdit.setFocus() return False return True
def __saveChat(self): """ Private slot to save the contents of the chat display. """ txt = self.chatEdit.toPlainText() if txt: fname, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( self, self.tr("Save Chat"), "", self.tr("Text Files (*.txt);;All Files (*)"), None, E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) if fname: ext = QFileInfo(fname).suffix() if not ext: ex = selectedFilter.split("(*")[1].split(")")[0] if ex: fname += ex if QFileInfo(fname).exists(): res = E5MessageBox.yesNo( self, self.tr("Save Chat"), self.tr("<p>The file <b>{0}</b> already exists." " Overwrite it?</p>").format(fname), icon=E5MessageBox.Warning) if not res: return fname = Utilities.toNativeSeparators(fname) try: f = open(fname, "w", encoding="utf-8") f.write(txt) f.close() except IOError as err: E5MessageBox.critical( self, self.tr("Error saving Chat"), self.tr("""<p>The chat contents could not be""" """ written to <b>{0}</b></p>""" """<p>Reason: {1}</p>""").format( fname, str(err)))
def __printRequested(self, frame): """ Private slot to handle a print request. @param frame reference to the frame to be printed (QWebFrame) """ printer = QPrinter(mode=QPrinter.HighResolution) if Preferences.getPrinter("ColorMode"): printer.setColorMode(QPrinter.Color) else: printer.setColorMode(QPrinter.GrayScale) if Preferences.getPrinter("FirstPageFirst"): printer.setPageOrder(QPrinter.FirstPageFirst) else: printer.setPageOrder(QPrinter.LastPageFirst) printer.setPageMargins( Preferences.getPrinter("LeftMargin") * 10, Preferences.getPrinter("TopMargin") * 10, Preferences.getPrinter("RightMargin") * 10, Preferences.getPrinter("BottomMargin") * 10, QPrinter.Millimeter ) printerName = Preferences.getPrinter("PrinterName") if printerName: printer.setPrinterName(printerName) printDialog = QPrintDialog(printer, self) if printDialog.exec_() == QDialog.Accepted: try: frame.print_(printer) except AttributeError: E5MessageBox.critical( self, self.tr("eric6 Web Browser"), self.tr( """<p>Printing is not available due to a bug in""" """ PyQt5. Please upgrade.</p>""")) return
def __getMasterPassword(): """ Private module function to get the password from the user. """ global MasterPassword pw, ok = QInputDialog.getText( None, QCoreApplication.translate("Crypto", "Master Password"), QCoreApplication.translate("Crypto", "Enter the master password:"******"MasterPassword") try: if masterPassword: if verifyPassword(pw, masterPassword): MasterPassword = pwEncode(pw) else: E5MessageBox.warning( None, QCoreApplication.translate("Crypto", "Master Password"), QCoreApplication.translate( "Crypto", """The given password is incorrect.""")) else: E5MessageBox.critical( None, QCoreApplication.translate("Crypto", "Master Password"), QCoreApplication.translate( "Crypto", """There is no master password registered.""")) except ValueError as why: E5MessageBox.warning( None, QCoreApplication.translate("Crypto", "Master Password"), QCoreApplication.translate( "Crypto", """<p>The given password cannot be verified.</p>""" """<p>Reason: {0}""".format(str(why))))
def __writeMultiProject(self, fn=None): """ Private method to save the multi project infos to a multi project file. @param fn optional filename of the multi project file to be written. If fn is None, the filename stored in the multi project object is used. This is the 'save' action. If fn is given, this filename is used instead of the one in the multi project object. This is the 'save as' action. @return flag indicating success """ if fn is None: fn = self.pfile f = QFile(fn) if f.open(QIODevice.WriteOnly): from E5XML.MultiProjectWriter import MultiProjectWriter MultiProjectWriter( f, self, os.path.splitext(os.path.basename(fn))[0])\ .writeXML() res = True else: E5MessageBox.critical( self.ui, self.tr("Save multiproject file"), self.tr("<p>The multiproject file <b>{0}</b> could not be " "written.</p>").format(fn)) res = False if res: self.pfile = os.path.abspath(fn) self.ppath = os.path.abspath(os.path.dirname(fn)) self.name = os.path.splitext(os.path.basename(fn))[0] self.setDirty(False) # insert filename into list of recently opened projects self.__syncRecent() return res
def __handle(self, variant): """ Private method to handle the wizards action. @param variant dialog variant to be generated (E5FileDialog or QFileDialog) @type str @exception ValueError raised to indicate an illegal file dialog variant """ editor = e5App().getObject("ViewManager").activeWindow() if editor is None: E5MessageBox.critical( self.__ui, self.tr('No current editor'), self.tr('Please open or create a file first.')) else: if variant == "QFileDialog": match = self.__pyqtRe.search(editor.text()) if match is None: # unknown dialogVariant = 0 else: # PyQt4 or PyQt5 dialogVariant = int(match.group(1)) elif variant == "E5FileDialog": # E5FileDialog dialogVariant = -1 else: raise ValueError("Illegal dialog variant given") code, ok = self.__callForm(editor, dialogVariant) if ok: line, index = editor.getCursorPosition() # It should be done on this way to allow undo editor.beginUndoAction() editor.insertAt(code, line, index) editor.endUndoAction()
def startSynchronizedProcess(self, proc, program, arguments, workingDir=None): """ Public method to start a synchroneous process. This method starts a process and waits for its end while still serving the Qt event loop. @param proc process to start (QProcess) @param program path of the executable to start (string) @param arguments list of arguments for the process (list of strings) @param workingDir working directory for the process (string) @return flag indicating normal exit (boolean) """ if proc is None: return if workingDir: proc.setWorkingDirectory(workingDir) proc.start(program, arguments) procStarted = proc.waitForStarted(5000) if not procStarted: E5MessageBox.critical( None, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.').format(program)) return False else: while proc.state() == QProcess.Running: QApplication.processEvents() QThread.msleep(300) QApplication.processEvents() return (proc.exitStatus() == QProcess.NormalExit) and \ (proc.exitCode() == 0)
def __printImage(self): """ Private slot to handle the Print Image menu action. """ if self.mainWidget is None: E5MessageBox.critical(self, self.tr("Print Image"), self.tr("""There is no UI file loaded.""")) return settings = Preferences.Prefs.settings printer = QPrinter(QPrinter.HighResolution) printer.setFullPage(True) printerName = Preferences.getPrinter("UIPreviewer/printername") if printerName: printer.setPrinterName(printerName) printer.setPageSize( QPrinter.PageSize(int(settings.value("UIPreviewer/pagesize")))) printer.setPageOrder( QPrinter.PageOrder(int(settings.value("UIPreviewer/pageorder")))) printer.setOrientation( QPrinter.Orientation(int( settings.value("UIPreviewer/orientation")))) printer.setColorMode( QPrinter.ColorMode(int(settings.value("UIPreviewer/colormode")))) printDialog = QPrintDialog(printer, self) if printDialog.exec_() == QDialog.Accepted: self.statusBar().showMessage(self.tr("Printing the image...")) self.__print(printer) settings.setValue("UIPreviewer/printername", printer.printerName()) settings.setValue("UIPreviewer/pagesize", printer.pageSize()) settings.setValue("UIPreviewer/pageorder", printer.pageOrder()) settings.setValue("UIPreviewer/orientation", printer.orientation()) settings.setValue("UIPreviewer/colormode", printer.colorMode()) self.statusBar().showMessage(self.tr("Image sent to printer..."), 2000)
def __installDictionary(self, reply): """ Private slot to install the downloaded dictionary. @param reply reference to the network reply @type QNetworkReply """ if reply in self.__replies: self.__replies.remove(reply) reply.deleteLater() if reply.error() != QNetworkReply.NoError: if not self.__downloadCancelled: E5MessageBox.warning( self, self.tr("Error downloading dictionary file"), self.tr( """<p>Could not download the requested dictionary""" """ file from {0}.</p><p>Error: {1}</p>""").format( reply.url(), reply.errorString())) self.downloadProgress.setValue(0) return archiveData = reply.readAll() archiveFile = io.BytesIO(bytes(archiveData)) archive = zipfile.ZipFile(archiveFile, "r") if archive.testzip() is not None: E5MessageBox.critical( self, self.tr("Error downloading dictionary"), self.tr("""<p>The downloaded dictionary archive is invalid.""" """ Skipping it.</p>""")) else: installDir = self.locationComboBox.currentText() archive.extractall(installDir) if self.__dictionariesToDownload: self.__downloadDictionary() else: self.__installationFinished()
def __startProc(self, applName, *applArgs): """ Private method to start an eric6 application. @param applName name of the eric6 application script (string) @param *applArgs variable list of application arguments """ proc = QProcess() applPath = os.path.join(getConfig("ericDir"), applName) args = [] args.append(applPath) for arg in applArgs: args.append(arg) if not os.path.isfile(applPath) or \ not proc.startDetached(sys.executable, args): E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( '<p>Could not start the process.<br>' 'Ensure that it is available as <b>{0}</b>.</p>').format( applPath), self.tr('OK'))
def __pdfGeneratedForSave(self, filePath, pdfData): """ Private slot to save the generated PDF data to a file. @param filePath path to save the PDF to @type str @param pdfData generated PDF document @type QByteArray """ if pdfData.size() == 0: return pdfFile = QFile(filePath) if pdfFile.open(QFile.WriteOnly): pdfFile.write(pdfData) pdfFile.close() if pdfFile.error() != QFileDevice.NoError: E5MessageBox.critical( self, self.tr("Print to PDF"), self.tr("""<p>The PDF could not be written to file <b>{0}""" """</b>.</p><p><b>Error:</b> {1}</p>""").format( filePath, pdfFile.errorString()), E5MessageBox.StandardButtons(E5MessageBox.Ok))
def __checkFileFilter(self, fileFilter): """ Private method to check a file filter for validity. @param fileFilter file filter pattern to check (string) @return flag indicating validity (boolean) """ if (not self.__showsOpenFilters and fileFilter.count("*") != 1): E5MessageBox.critical( self, self.tr("Add File Filter"), self.tr("""A Save File Filter must contain exactly one""" """ wildcard pattern. Yours contains {0}.""").format( fileFilter.count("*"))) return False if fileFilter.count("*") == 0: E5MessageBox.critical( self, self.tr("Add File Filter"), self.tr("""A File Filter must contain at least one""" """ wildcard pattern.""")) return False return True
def on_pathButton_clicked(self): """ Private slot to handle the path selection via a directory selection dialog. """ path = E5FileDialog.getExistingDirectory( self, self.tr("Add Sub-repository"), os.path.join(self.__projectPath, self.pathEdit.text()), E5FileDialog.Options(E5FileDialog.Option(0))) if path: path = Utilities.toNativeSeparators(path) if path.startswith(self.__projectPath): path = path.replace(self.__projectPath, "")[1:] self.pathEdit.setText(path) else: E5MessageBox.critical( self, self.tr("Add Sub-repository"), self.tr("""The sub-repository path must be inside""" """ the project.""")) return
def on_addButton_clicked(self): """ Private slot to add a new entry. """ groupName = self.nameEdit.text() if not groupName: E5MessageBox.critical( self, self.tr("Add tool group entry"), self.tr("You have to give a name for the group to add.")) return if len( self.groupsList.findItems(groupName, Qt.MatchFlags(Qt.MatchExactly))): E5MessageBox.critical( self, self.tr("Add tool group entry"), self.tr("An entry for the group name {0} already exists."). format(groupName)) return self.groupsList.addItem(groupName) self.toolGroups.append([groupName, []])
def __startPluginInstall(self): """ Private slot to start the eric6 plugin installation dialog. """ proc = QProcess() applPath = os.path.join(getConfig("ericDir"), "eric6_plugininstall.py") args = [] args.append(applPath) args += self.cw.getDownloadedPlugins() if not os.path.isfile(applPath) or \ not proc.startDetached(sys.executable, args): E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( '<p>Could not start the process.<br>' 'Ensure that it is available as <b>{0}</b>.</p>' ).format(applPath), self.tr('OK')) self.close()
def on_renameButton_clicked(self): """ Private slot to rename a custom toolbar. """ oldName = self.toolbarComboBox.currentText() newName, ok = QInputDialog.getText(self, self.tr("Rename Toolbar"), self.tr("New Toolbar Name:"), QLineEdit.Normal, oldName) if ok and newName: if oldName == newName: return if self.toolbarComboBox.findText(newName) != -1: # toolbar with this name already exists E5MessageBox.critical( self, self.tr("Rename Toolbar"), self.tr("""A toolbar with the name <b>{0}</b> already""" """ exists.""").format(newName)) return index = self.toolbarComboBox.currentIndex() self.toolbarComboBox.setItemText(index, newName) tbItem = self.__toolbarItems[self.toolbarComboBox.itemData(index)] tbItem.title = newName tbItem.isChanged = True
def __flashMicroPython(self): """ Private slot to flash the default MicroPython firmware to the device. """ # Attempts to find the path on the filesystem that represents the # plugged in micro:bit board in maintenance mode. deviceDirectory = Utilities.findVolume("MAINTENANCE") if not deviceDirectory: # BBC micro:bit is not ready or not mounted E5MessageBox.critical( self.microPython, self.tr("Flash MicroPython Firmware"), self.tr('The BBC micro:bit is not ready for flashing. See the' ' <a href="https://microbit.org/guide/firmware/">' 'micro:bit web site</a> for details.')) else: downloadsPath = QStandardPaths.standardLocations( QStandardPaths.DownloadLocation)[0] firmware = E5FileDialog.getOpenFileName( self.microPython, self.tr("Flash MicroPython Firmware"), downloadsPath, self.tr("MicroPython Firmware Files (*.hex);;All Files (*)")) if firmware and os.path.exists(firmware): shutil.copy2(firmware, deviceDirectory)
def __saveImage(self): """ Private slot to handle the Save Image menu action. """ if self.mainWidget is None: E5MessageBox.critical(self, self.tr("Save Image"), self.tr("""There is no UI file loaded.""")) return defaultExt = "PNG" filters = "" formats = QImageWriter.supportedImageFormats() for format in formats: filters = "{0}*.{1} ".format(filters, bytes(format).decode().lower()) filter = self.tr("Images ({0})").format(filters[:-1]) fname = E5FileDialog.getSaveFileName(self, self.tr("Save Image"), "", filter) if not fname: return ext = QFileInfo(fname).suffix().upper() if not ext: ext = defaultExt fname.append(".{0}".format(defaultExt.lower())) if qVersion() >= "5.0.0": pix = self.mainWidget.grab() else: pix = QPixmap.grabWidget(self.mainWidget) self.__updateChildren(self.lastStyle) if not pix.save(fname, str(ext)): E5MessageBox.critical( self, self.tr("Save Image"), self.tr("""<p>The file <b>{0}</b> could not be saved.</p>"""). format(fname))
def __cleanupDownloads(self): """ Private slot to cleanup the plug-in downloads area. """ downloadPath = Preferences.getPluginManager("DownloadPath") downloads = {} # plug-in name as key, file name as value # step 1: extract plug-ins and downloaded files for pluginFile in os.listdir(downloadPath): if not os.path.isfile(os.path.join(downloadPath, pluginFile)): continue pluginName = pluginFile.rsplit("-", 1)[0] if pluginName not in downloads: downloads[pluginName] = [] downloads[pluginName].append(pluginFile) # step 2: delete old entries for pluginName in downloads: downloads[pluginName].sort() if pluginName in self.__hiddenPlugins and \ not Preferences.getPluginManager("KeepHidden"): removeFiles = downloads[pluginName] else: removeFiles = downloads[pluginName][ :-Preferences.getPluginManager("KeepGenerations")] for removeFile in removeFiles: try: os.remove(os.path.join(downloadPath, removeFile)) except (IOError, OSError) as err: E5MessageBox.critical( self, self.tr("Cleanup of Plugin Downloads"), self.tr("""<p>The plugin download <b>{0}</b> could""" """ not be deleted.</p><p>Reason: {1}</p>""") .format(removeFile, str(err)))
def start(self, fn): """ Public slot to start the svn status command. @param fn filename to show the log for (string) """ self.errorGroup.hide() self.intercept = False self.activateWindow() self.lineno = 1 dname, fname = self.vcs.splitPath(fn) self.process.kill() args = [] args.append('blame') self.vcs.addArguments(args, self.vcs.options['global']) args.append(fname) self.process.setWorkingDirectory(dname) self.process.start('svn', args) procStarted = self.process.waitForStarted(5000) if not procStarted: self.inputGroup.setEnabled(False) self.inputGroup.hide() E5MessageBox.critical( self, self.tr('Process Generation Error'), self.tr( 'The process {0} could not be started. ' 'Ensure, that it is in the search path.' ).format('svn')) else: self.inputGroup.setEnabled(True) self.inputGroup.show()