Sat, 10 Oct 2020 12:20:51 +0200
Optimized the use of Waiting Cursors by using a specialized context manager class.
--- a/eric6.e4p Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6.e4p Sat Oct 10 12:20:51 2020 +0200 @@ -149,6 +149,7 @@ <Source>eric6/E5Gui/E5MessageBox.py</Source> <Source>eric6/E5Gui/E5ModelMenu.py</Source> <Source>eric6/E5Gui/E5ModelToolBar.py</Source> + <Source>eric6/E5Gui/E5OverrideCursor.py</Source> <Source>eric6/E5Gui/E5PassivePopup.py</Source> <Source>eric6/E5Gui/E5PasswordMeter.py</Source> <Source>eric6/E5Gui/E5PathPicker.py</Source>
--- a/eric6/CondaInterface/CondaExportDialog.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/CondaInterface/CondaExportDialog.py Sat Oct 10 12:20:51 2020 +0200 @@ -18,6 +18,7 @@ from E5Gui import E5MessageBox, E5FileDialog from E5Gui.E5PathPicker import E5PathPickerModes from E5Gui.E5Application import e5App +from E5Gui.E5OverrideCursor import E5OverrideCursor from .Ui_CondaExportDialog import Ui_CondaExportDialog @@ -69,7 +70,6 @@ @param e close event @type QCloseEvent """ - QApplication.restoreOverrideCursor() e.accept() @pyqtSlot(str) @@ -131,17 +131,16 @@ self.__prefix, ] - QApplication.setOverrideCursor(Qt.WaitCursor) - success, output = self.__conda.runProcess(args) + with E5OverrideCursor(): + success, output = self.__conda.runProcess(args) + + if success: + self.requirementsEdit.setPlainText(output) + self.__requirementsAvailable = True + else: + self.requirementsEdit.setPlainText( + self.tr("No output generated by conda.")) - if success: - self.requirementsEdit.setPlainText(output) - self.__requirementsAvailable = True - else: - self.requirementsEdit.setPlainText( - self.tr("No output generated by conda.")) - - QApplication.restoreOverrideCursor() self.__updateButtons() self.__requirementsEdited = False
--- a/eric6/CondaInterface/CondaPackagesWidget.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/CondaInterface/CondaPackagesWidget.py Sat Oct 10 12:20:51 2020 +0200 @@ -11,7 +11,6 @@ import os from PyQt5.QtCore import pyqtSlot, Qt -from PyQt5.QtGui import QCursor from PyQt5.QtWidgets import ( QWidget, QToolButton, QMenu, QTreeWidgetItem, QApplication, QLineEdit, QDialog @@ -19,6 +18,7 @@ from E5Gui import E5FileDialog, E5MessageBox, E5TextInputDialog from E5Gui.E5Application import e5App +from E5Gui.E5OverrideCursor import E5OverrideCursor from .Ui_CondaPackagesWidget import Ui_CondaPackagesWidget @@ -218,51 +218,51 @@ self.packagesList.clear() prefix = self.environmentsComboBox.itemData(index) if prefix: - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.statusLabel.show() self.statusLabel.setText(self.tr("Getting installed packages...")) - QApplication.processEvents() - # 1. populate with installed packages - self.packagesList.setUpdatesEnabled(False) - installedPackages = self.__conda.getInstalledPackages( - prefix=prefix) - for package, version, build in installedPackages: - itm = QTreeWidgetItem(self.packagesList, [package, version]) - itm.setData(1, self.PackageVersionRole, version) - itm.setData(1, self.PackageBuildRole, build) - self.packagesList.setUpdatesEnabled(True) - self.statusLabel.setText(self.tr("Getting outdated packages...")) - QApplication.processEvents() - - # 2. update with update information - self.packagesList.setUpdatesEnabled(False) - updateablePackages = self.__conda.getUpdateablePackages( - prefix=prefix) - for package, version, build in updateablePackages: - items = self.packagesList.findItems( - package, Qt.MatchExactly | Qt.MatchCaseSensitive) - if items: - itm = items[0] - itm.setText(2, version) - itm.setData(2, self.PackageVersionRole, version) - itm.setData(2, self.PackageBuildRole, build) - if itm.data(1, self.PackageVersionRole) == version: - # build must be different, show in version display - itm.setText(1, self.tr("{0} (Build: {1})").format( - itm.data(1, self.PackageVersionRole), - itm.data(1, self.PackageBuildRole), - )) - itm.setText(2, self.tr("{0} (Build: {1})").format( - itm.data(2, self.PackageVersionRole), - itm.data(2, self.PackageBuildRole), - )) - - self.packagesList.sortItems(0, Qt.AscendingOrder) - for col in range(self.packagesList.columnCount()): - self.packagesList.resizeColumnToContents(col) - self.packagesList.setUpdatesEnabled(True) - QApplication.restoreOverrideCursor() + with E5OverrideCursor(): + # 1. populate with installed packages + self.packagesList.setUpdatesEnabled(False) + installedPackages = self.__conda.getInstalledPackages( + prefix=prefix) + for package, version, build in installedPackages: + itm = QTreeWidgetItem(self.packagesList, + [package, version]) + itm.setData(1, self.PackageVersionRole, version) + itm.setData(1, self.PackageBuildRole, build) + self.packagesList.setUpdatesEnabled(True) + self.statusLabel.setText( + self.tr("Getting outdated packages...")) + QApplication.processEvents() + + # 2. update with update information + self.packagesList.setUpdatesEnabled(False) + updateablePackages = self.__conda.getUpdateablePackages( + prefix=prefix) + for package, version, build in updateablePackages: + items = self.packagesList.findItems( + package, Qt.MatchExactly | Qt.MatchCaseSensitive) + if items: + itm = items[0] + itm.setText(2, version) + itm.setData(2, self.PackageVersionRole, version) + itm.setData(2, self.PackageBuildRole, build) + if itm.data(1, self.PackageVersionRole) == version: + # build must be different, show in version display + itm.setText(1, self.tr("{0} (Build: {1})").format( + itm.data(1, self.PackageVersionRole), + itm.data(1, self.PackageBuildRole), + )) + itm.setText(2, self.tr("{0} (Build: {1})").format( + itm.data(2, self.PackageVersionRole), + itm.data(2, self.PackageBuildRole), + )) + + self.packagesList.sortItems(0, Qt.AscendingOrder) + for col in range(self.packagesList.columnCount()): + self.packagesList.resizeColumnToContents(col) + self.packagesList.setUpdatesEnabled(True) self.statusLabel.hide() self.__updateActionButtons() @@ -284,17 +284,14 @@ self.environmentsComboBox.clear() self.packagesList.clear() - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() - - self.__populateEnvironments() + with E5OverrideCursor(): + self.__populateEnvironments() + + index = self.environmentsComboBox.findText( + currentEnvironment, Qt.MatchExactly | Qt.MatchCaseSensitive) + if index != -1: + self.environmentsComboBox.setCurrentIndex(index) - index = self.environmentsComboBox.findText( - currentEnvironment, Qt.MatchExactly | Qt.MatchCaseSensitive) - if index != -1: - self.environmentsComboBox.setCurrentIndex(index) - - QApplication.restoreOverrideCursor() self.__updateActionButtons() @pyqtSlot() @@ -355,56 +352,53 @@ self.searchResultList.clear() pattern = self.searchEdit.text() if pattern: - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() - - if CondaInterface.condaVersion() >= (4, 4, 0): - prefix = "" - else: - prefix = self.environmentsComboBox.itemData( - self.environmentsComboBox.currentIndex()) - ok, result = self.__conda.searchPackages( - pattern, - fullNameOnly=self.fullNameButton.isChecked(), - packageSpec=self.packageSpecButton.isChecked(), - platform=self.platformComboBox.currentText(), - prefix=prefix, - ) - - if result: + with E5OverrideCursor(): + if CondaInterface.condaVersion() >= (4, 4, 0): + prefix = "" + else: + prefix = self.environmentsComboBox.itemData( + self.environmentsComboBox.currentIndex()) + ok, result = self.__conda.searchPackages( + pattern, + fullNameOnly=self.fullNameButton.isChecked(), + packageSpec=self.packageSpecButton.isChecked(), + platform=self.platformComboBox.currentText(), + prefix=prefix, + ) + if ok: - self.searchResultList.setUpdatesEnabled(False) - for package in result: - itm = QTreeWidgetItem(self.searchResultList, [package]) - itm.setExpanded(False) - for detail in result[package]: - version = detail["version"] - build = detail["build"] - if "subdir" in detail: - platform = detail["subdir"] - elif "platform" in detail: - platform = detail["platform"] - else: - platform = "" - citm = QTreeWidgetItem( - itm, ["", version, build, platform]) - citm.setData(0, self.PackageDetailedDataRole, - detail) - - self.searchResultList.sortItems(0, Qt.AscendingOrder) - self.searchResultList.resizeColumnToContents(0) - self.searchResultList.setUpdatesEnabled(True) - else: - QApplication.restoreOverrideCursor() - try: - message = result["message"] - except KeyError: - message = result["error"] - E5MessageBox.warning( - self, - self.tr("Conda Search Package Error"), - message) - QApplication.restoreOverrideCursor() + if result: + self.searchResultList.setUpdatesEnabled(False) + for package in result: + itm = QTreeWidgetItem(self.searchResultList, + [package]) + itm.setExpanded(False) + for detail in result[package]: + version = detail["version"] + build = detail["build"] + if "subdir" in detail: + platform = detail["subdir"] + elif "platform" in detail: + platform = detail["platform"] + else: + platform = "" + citm = QTreeWidgetItem( + itm, ["", version, build, platform]) + citm.setData(0, self.PackageDetailedDataRole, + detail) + + self.searchResultList.sortItems(0, Qt.AscendingOrder) + self.searchResultList.resizeColumnToContents(0) + self.searchResultList.setUpdatesEnabled(True) + if not ok: + try: + message = result["message"] + except KeyError: + message = result["error"] + E5MessageBox.warning( + self, + self.tr("Conda Search Package Error"), + message) def __showDetails(self, item): """
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eric6/E5Gui/E5OverrideCursor.py Sat Oct 10 12:20:51 2020 +0200 @@ -0,0 +1,139 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2020 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a context manager class for an override cursor and a +QProcess class controlling an override cursor. +""" + +import contextlib + +from PyQt5.QtCore import pyqtSlot, Qt, QProcess, QEventLoop +from PyQt5.QtGui import QCursor, QGuiApplication + + +# TODO: add similar class for QMutexLocker +class E5OverrideCursor(contextlib.AbstractContextManager): + """ + Class implementing a context manager class for an override cursor. + """ + def __init__(self, cursorShape=Qt.WaitCursor): + """ + Constructor + + @param cursorShape shape of the override cursor + @type Qt.CursorShape + """ + self.__cursorShape = cursorShape + + def __enter__(self): + """ + Special method called when entering the runtime ccontext. + + @return reference to the context manager object + @rtype E5OverrideCursor + """ + QGuiApplication.setOverrideCursor(QCursor(self.__cursorShape)) + QGuiApplication.processEvents(QEventLoop.ExcludeUserInputEvents) + + return self + + def __exit__(self, exc_type, exc_value, traceback): + """ + Special method called when exiting the runtime ccontext. + + @param exc_type type of an exception raised in the runtime context + @param exc_value value of an exception raised in the runtime context + @param traceback traceback of an exception raised in the runtime + context + @return always returns None to not suppress any exception + @rtype None + """ + QGuiApplication.restoreOverrideCursor() + QGuiApplication.processEvents(QEventLoop.ExcludeUserInputEvents) + + return None + + +class E5OverridenCursor(contextlib.AbstractContextManager): + """ + Class implementing a context manager class for an overriden cursor. + + The cursor is reset upon entering the runtime context and restored + upon exiting it. + """ + def __init__(self): + """ + Constructor + """ + self.__cursor = None + + def __enter__(self): + """ + Special method called when entering the runtime ccontext. + + @return reference to the context manager object + @rtype E5OverrideCursor + """ + self.__cursor = QGuiApplication.overrideCursor() + if self.__cursor is not None: + QGuiApplication.restoreOverrideCursor() + QGuiApplication.processEvents(QEventLoop.ExcludeUserInputEvents) + + return self + + def __exit__(self, exc_type, exc_value, traceback): + """ + Special method called when exiting the runtime ccontext. + + @param exc_type type of an exception raised in the runtime context + @param exc_value value of an exception raised in the runtime context + @param traceback traceback of an exception raised in the runtime + context + @return always returns None to not suppress any exception + @rtype None + """ + if self.__cursor is not None: + QGuiApplication.setOverrideCursor(self.__cursor) + QGuiApplication.processEvents(QEventLoop.ExcludeUserInputEvents) + + return None + + +class E5OverrideCursorProcess(QProcess): + """ + Class implementing a QProcess subclass controlling an override cursor. + """ + def __init__(self, parent=None, cursorShape=Qt.WaitCursor): + """ + Constructor + + @param parent reference to the parent object + @type QObject + @param cursorShape shape of the override cursor + @type Qt.CursorShape + """ + super(E5OverrideCursorProcess, self).__init__(parent) + + self.__cursorShape = cursorShape + + self.started.connect(self.__processStarted) + self.finished.connect(self.__processFinished) + + @pyqtSlot() + def __processStarted(self): + """ + Private slot setting the cursor after the process has started. + """ + QGuiApplication.setOverrideCursor(QCursor(self.__cursorShape)) + QGuiApplication.processEvents(QEventLoop.ExcludeUserInputEvents) + + @pyqtSlot() + def __processFinished(self): + """ + Private slot resetting the cursor when the process finished. + """ + QGuiApplication.restoreOverrideCursor() + QGuiApplication.processEvents(QEventLoop.ExcludeUserInputEvents)
--- a/eric6/E5Network/E5XmlRpcClient.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/E5Network/E5XmlRpcClient.py Sat Oct 10 12:20:51 2020 +0200 @@ -10,7 +10,8 @@ import xmlrpc.client as xmlrpc -from PyQt5.QtCore import QObject, QUrl, QByteArray +from PyQt5.QtCore import Qt, QObject, QUrl, QByteArray, QEventLoop +from PyQt5.QtGui import QGuiApplication, QCursor from PyQt5.QtNetwork import ( QNetworkAccessManager, QNetworkRequest, QNetworkReply ) @@ -77,6 +78,9 @@ if not isinstance(args, tuple): raise TypeError("argument 'args' must be tuple") + QGuiApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) + QGuiApplication.processEvents(QEventLoop.ExcludeUserInputEvents) + data = xmlrpc.dumps(args, method).encode("utf-8") reply = self.__networkManager.post( self.__request, QByteArray(data)) @@ -97,6 +101,9 @@ @param reply reference to the reply object (QNetworkReply) @param errors list of SSL errors (list of QSslError) """ + QGuiApplication.restoreOverrideCursor() + QGuiApplication.processEvents(QEventLoop.ExcludeUserInputEvents) + ignored = self.__sslErrorHandler.sslErrorsReply(reply, errors)[0] if ignored == E5SslErrorHandler.NotIgnored and reply in self.__callmap: self.__callmap[reply][1](xmlrpc.TRANSPORT_ERROR, self.tr( @@ -111,6 +118,9 @@ if reply not in self.__callmap: return + QGuiApplication.restoreOverrideCursor() + QGuiApplication.processEvents(QEventLoop.ExcludeUserInputEvents) + if reply.error() != QNetworkReply.NoError: self.__callmap[reply][1](xmlrpc.TRANSPORT_ERROR, reply.errorString())
--- a/eric6/MultiProject/MultiProject.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/MultiProject/MultiProject.py Sat Oct 10 12:20:51 2020 +0200 @@ -12,9 +12,8 @@ import shutil from PyQt5.QtCore import ( - pyqtSignal, pyqtSlot, Qt, QFileInfo, QFile, QIODevice, QObject, QUuid + pyqtSignal, pyqtSlot, QFileInfo, QFile, QIODevice, QObject, QUuid ) -from PyQt5.QtGui import QCursor from PyQt5.QtWidgets import QMenu, QApplication, QDialog, QToolBar from Globals import recentNameMultiProject @@ -22,6 +21,7 @@ from E5Gui.E5Action import E5Action, createActionGroup from E5Gui import E5FileDialog, E5MessageBox, E5PathPickerDialog from E5Gui.E5PathPickerDialog import E5PathPickerModes +from E5Gui.E5OverrideCursor import E5OverrideCursor import UI.PixmapCache @@ -225,14 +225,14 @@ """ f = QFile(fn) if f.open(QIODevice.ReadOnly): - from E5XML.MultiProjectReader import MultiProjectReader - reader = MultiProjectReader(f, self) - reader.readXML() - f.close() + with E5OverrideCursor(): + 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"), @@ -553,13 +553,10 @@ QApplication.processEvents() if fn is not None: - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() self.closeMultiProject() - if self.__readMultiProject(fn): + ok = self.__readMultiProject(fn) + if ok: self.opened = True - QApplication.restoreOverrideCursor() - QApplication.processEvents() self.closeAct.setEnabled(True) self.saveasAct.setEnabled(True) @@ -571,8 +568,6 @@ if openMaster and Preferences.getMultiProject( "OpenMasterAutomatically"): self.__openMasterProject(False) - else: - QApplication.restoreOverrideCursor() def saveMultiProject(self): """
--- a/eric6/PipInterface/PipFreezeDialog.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/PipInterface/PipFreezeDialog.py Sat Oct 10 12:20:51 2020 +0200 @@ -18,6 +18,7 @@ from E5Gui import E5MessageBox, E5FileDialog from E5Gui.E5PathPicker import E5PathPickerModes from E5Gui.E5Application import e5App +from E5Gui.E5OverrideCursor import E5OverrideCursor from .Ui_PipFreezeDialog import Ui_PipFreezeDialog @@ -62,7 +63,6 @@ @param e close event @type QCloseEvent """ - QApplication.restoreOverrideCursor() e.accept() @pyqtSlot(bool) @@ -144,17 +144,16 @@ args.append("--requirement") args.append(fileName) - QApplication.setOverrideCursor(Qt.WaitCursor) - success, output = self.__pip.runProcess(args, interpreter) + with E5OverrideCursor(): + success, output = self.__pip.runProcess(args, interpreter) + + if success: + self.requirementsEdit.setPlainText(output) + self.__requirementsAvailable = True + else: + self.requirementsEdit.setPlainText( + self.tr("No output generated by 'pip freeze'.")) - if success: - self.requirementsEdit.setPlainText(output) - self.__requirementsAvailable = True - else: - self.requirementsEdit.setPlainText( - self.tr("No output generated by 'pip freeze'.")) - - QApplication.restoreOverrideCursor() self.__updateButtons() self.__requirementsEdited = False
--- a/eric6/PipInterface/PipPackagesWidget.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/PipInterface/PipPackagesWidget.py Sat Oct 10 12:20:51 2020 +0200 @@ -11,8 +11,7 @@ import textwrap import os -from PyQt5.QtCore import pyqtSlot, Qt, QEventLoop, QRegExp -from PyQt5.QtGui import QCursor +from PyQt5.QtCore import pyqtSlot, Qt, QRegExp from PyQt5.QtWidgets import ( QWidget, QToolButton, QApplication, QHeaderView, QTreeWidgetItem, QInputDialog, QMenu, QDialog @@ -20,6 +19,7 @@ from E5Gui.E5Application import e5App from E5Gui import E5MessageBox +from E5Gui.E5OverrideCursor import E5OverrideCursor from E5Network.E5XmlRpcClient import E5XmlRpcClient @@ -237,47 +237,45 @@ if venvName: interpreter = self.__pip.getVirtualenvInterpreter(venvName) if interpreter: - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.statusLabel.show() self.statusLabel.setText( self.tr("Getting installed packages...")) - QApplication.processEvents() - # 1. populate with installed packages - self.packagesList.setUpdatesEnabled(False) - installedPackages = self.__pip.getInstalledPackages( - venvName, - localPackages=self.localCheckBox.isChecked(), - notRequired=self.notRequiredCheckBox.isChecked(), - usersite=self.userCheckBox.isChecked(), - ) - for package, version in installedPackages: - QTreeWidgetItem(self.packagesList, [package, version]) - self.packagesList.setUpdatesEnabled(True) - self.statusLabel.setText( - self.tr("Getting outdated packages...")) - QApplication.processEvents() - - # 2. update with update information - self.packagesList.setUpdatesEnabled(False) - outdatedPackages = self.__pip.getOutdatedPackages( - venvName, - localPackages=self.localCheckBox.isChecked(), - notRequired=self.notRequiredCheckBox.isChecked(), - usersite=self.userCheckBox.isChecked(), - ) - for package, _version, latest in outdatedPackages: - items = self.packagesList.findItems( - package, Qt.MatchExactly | Qt.MatchCaseSensitive) - if items: - itm = items[0] - itm.setText(2, latest) - - self.packagesList.sortItems(0, Qt.AscendingOrder) - for col in range(self.packagesList.columnCount()): - self.packagesList.resizeColumnToContents(col) - self.packagesList.setUpdatesEnabled(True) - QApplication.restoreOverrideCursor() + with E5OverrideCursor(): + # 1. populate with installed packages + self.packagesList.setUpdatesEnabled(False) + installedPackages = self.__pip.getInstalledPackages( + venvName, + localPackages=self.localCheckBox.isChecked(), + notRequired=self.notRequiredCheckBox.isChecked(), + usersite=self.userCheckBox.isChecked(), + ) + for package, version in installedPackages: + QTreeWidgetItem(self.packagesList, [package, version]) + self.packagesList.setUpdatesEnabled(True) + self.statusLabel.setText( + self.tr("Getting outdated packages...")) + QApplication.processEvents() + + # 2. update with update information + self.packagesList.setUpdatesEnabled(False) + outdatedPackages = self.__pip.getOutdatedPackages( + venvName, + localPackages=self.localCheckBox.isChecked(), + notRequired=self.notRequiredCheckBox.isChecked(), + usersite=self.userCheckBox.isChecked(), + ) + for package, _version, latest in outdatedPackages: + items = self.packagesList.findItems( + package, Qt.MatchExactly | Qt.MatchCaseSensitive) + if items: + itm = items[0] + itm.setText(2, latest) + + self.packagesList.sortItems(0, Qt.AscendingOrder) + for col in range(self.packagesList.columnCount()): + self.packagesList.resizeColumnToContents(col) + self.packagesList.setUpdatesEnabled(True) self.statusLabel.hide() self.__updateActionButtons() @@ -339,54 +337,55 @@ if not interpreter: return - QApplication.setOverrideCursor(Qt.WaitCursor) - args = ["-m", "pip", "show"] if self.verboseCheckBox.isChecked(): args.append("--verbose") if self.installedFilesCheckBox.isChecked(): args.append("--files") args.append(itm.text(0)) - success, output = self.__pip.runProcess(args, interpreter) - if success and output: - mode = self.ShowProcessGeneralMode - for line in output.splitlines(): - line = line.rstrip() - if line != "---": - if mode != self.ShowProcessGeneralMode: - if line[0] == " ": - QTreeWidgetItem( - self.infoWidget, - [" ", line.strip()]) - else: - mode = self.ShowProcessGeneralMode - if mode == self.ShowProcessGeneralMode: - try: - label, info = line.split(": ", 1) - except ValueError: - label = line[:-1] - info = "" - label = label.lower() - if label in self.__infoLabels: - QTreeWidgetItem( - self.infoWidget, - [self.__infoLabels[label], info]) - if label == "files": - mode = self.ShowProcessFilesListMode - elif label == "classifiers": - mode = self.ShowProcessClassifiersMode - elif label == "entry-points": - mode = self.ShowProcessEntryPointsMode - self.infoWidget.scrollToTop() - - header = self.infoWidget.header() - header.setStretchLastSection(False) - header.resizeSections(QHeaderView.ResizeToContents) - if header.sectionSize(0) + header.sectionSize(1) < header.width(): - header.setStretchLastSection(True) - - QApplication.restoreOverrideCursor() + with E5OverrideCursor(): + success, output = self.__pip.runProcess(args, interpreter) + + if success and output: + mode = self.ShowProcessGeneralMode + for line in output.splitlines(): + line = line.rstrip() + if line != "---": + if mode != self.ShowProcessGeneralMode: + if line[0] == " ": + QTreeWidgetItem( + self.infoWidget, + [" ", line.strip()]) + else: + mode = self.ShowProcessGeneralMode + if mode == self.ShowProcessGeneralMode: + try: + label, info = line.split(": ", 1) + except ValueError: + label = line[:-1] + info = "" + label = label.lower() + if label in self.__infoLabels: + QTreeWidgetItem( + self.infoWidget, + [self.__infoLabels[label], info]) + if label == "files": + mode = self.ShowProcessFilesListMode + elif label == "classifiers": + mode = self.ShowProcessClassifiersMode + elif label == "entry-points": + mode = self.ShowProcessEntryPointsMode + self.infoWidget.scrollToTop() + + header = self.infoWidget.header() + header.setStretchLastSection(False) + header.resizeSections(QHeaderView.ResizeToContents) + if ( + header.sectionSize(0) + header.sectionSize(1) < + header.width() + ): + header.setStretchLastSection(True) self.__updateActionButtons() @@ -444,17 +443,14 @@ self.environmentsComboBox.clear() self.packagesList.clear() - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() - - self.__populateEnvironments() + with E5OverrideCursor(): + self.__populateEnvironments() + + index = self.environmentsComboBox.findText( + currentEnvironment, Qt.MatchExactly | Qt.MatchCaseSensitive) + if index != -1: + self.environmentsComboBox.setCurrentIndex(index) - index = self.environmentsComboBox.findText( - currentEnvironment, Qt.MatchExactly | Qt.MatchCaseSensitive) - if index != -1: - self.environmentsComboBox.setCurrentIndex(index) - - QApplication.restoreOverrideCursor() self.__updateActionButtons() @pyqtSlot() @@ -636,8 +632,6 @@ self.searchInfoLabel.clear() self.searchButton.setEnabled(False) - QApplication.setOverrideCursor(Qt.WaitCursor) - QApplication.processEvents(QEventLoop.ExcludeUserInputEvents) self.__queryName = [ term for term in self.searchEditName.text().strip().split() @@ -688,7 +682,6 @@ count = 0 QApplication.processEvents() else: - QApplication.restoreOverrideCursor() E5MessageBox.warning( self, self.tr("Search PyPI"), @@ -698,7 +691,6 @@ self.tr("""<p>The package search did not return""" """ anything.</p>""")) else: - QApplication.restoreOverrideCursor() E5MessageBox.warning( self, self.tr("Search PyPI"), @@ -724,8 +716,6 @@ """ Private slot performing the search finishing actions. """ - QApplication.restoreOverrideCursor() - self.__updateSearchActionButtons() self.__updateSearchButton() @@ -900,12 +890,10 @@ @param packageVersion version of the package @type str """ - QApplication.setOverrideCursor(Qt.WaitCursor) - QApplication.processEvents(QEventLoop.ExcludeUserInputEvents) + with E5OverrideCursor(): + packageData = self.__pip.getPackageDetails( + packageName, packageVersion) - packageData = self.__pip.getPackageDetails(packageName, packageVersion) - - QApplication.restoreOverrideCursor() if packageData: from .PipPackageDetailsDialog import PipPackageDetailsDialog
--- a/eric6/Plugins/VcsPlugins/vcsGit/GitBisectLogBrowserDialog.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/Plugins/VcsPlugins/vcsGit/GitBisectLogBrowserDialog.py Sat Oct 10 12:20:51 2020 +0200 @@ -11,13 +11,13 @@ import os from PyQt5.QtCore import pyqtSlot, Qt, QPoint, QProcess, QTimer -from PyQt5.QtGui import QCursor from PyQt5.QtWidgets import ( QWidget, QDialogButtonBox, QHeaderView, QTreeWidgetItem, QApplication, QLineEdit ) from E5Gui import E5MessageBox +from E5Gui.E5OverrideCursor import E5OverrideCursorProcess from .Ui_GitBisectLogBrowserDialog import Ui_GitBisectLogBrowserDialog @@ -64,10 +64,10 @@ self.__initData() self.__resetUI() - self.process = QProcess() - self.process.finished.connect(self.__procFinished) - self.process.readyReadStandardOutput.connect(self.__readStdout) - self.process.readyReadStandardError.connect(self.__readStderr) + self.__process = E5OverrideCursorProcess() + self.__process.finished.connect(self.__procFinished) + self.__process.readyReadStandardOutput.connect(self.__readStdout) + self.__process.readyReadStandardError.connect(self.__readStderr) def __initData(self): """ @@ -82,12 +82,12 @@ @param e close event (QCloseEvent) """ if ( - self.process is not None and - self.process.state() != QProcess.NotRunning + self.__process is not None and + self.__process.state() != QProcess.NotRunning ): - self.process.terminate() - QTimer.singleShot(2000, self.process.kill) - self.process.waitForFinished(3000) + self.__process.terminate() + QTimer.singleShot(2000, self.__process.kill) + self.__process.waitForFinished(3000) self.__position = self.pos() @@ -145,9 +145,6 @@ self.inputGroup.show() self.refreshButton.setEnabled(False) - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() - self.buf = [] self.cancelled = False self.errors.clear() @@ -156,15 +153,15 @@ args = self.vcs.initCommand("bisect") args.append("log") - self.process.kill() + self.__process.kill() - self.process.setWorkingDirectory(self.repodir) + self.__process.setWorkingDirectory(self.repodir) self.inputGroup.setEnabled(True) self.inputGroup.show() - self.process.start('git', args) - procStarted = self.process.waitForStarted(5000) + self.__process.start('git', args) + procStarted = self.__process.waitForStarted(5000) if not procStarted: self.inputGroup.setEnabled(False) self.inputGroup.hide() @@ -216,14 +213,12 @@ the button. """ if ( - self.process is not None and - self.process.state() != QProcess.NotRunning + self.__process is not None and + self.__process.state() != QProcess.NotRunning ): - self.process.terminate() - QTimer.singleShot(2000, self.process.kill) - self.process.waitForFinished(3000) - - QApplication.restoreOverrideCursor() + self.__process.terminate() + QTimer.singleShot(2000, self.__process.kill) + self.__process.waitForFinished(3000) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) @@ -265,10 +260,10 @@ It reads the output of the process and inserts it into a buffer. """ - self.process.setReadChannel(QProcess.StandardOutput) + self.__process.setReadChannel(QProcess.StandardOutput) - while self.process.canReadLine(): - line = str(self.process.readLine(), + while self.__process.canReadLine(): + line = str(self.__process.readLine(), Preferences.getSystem("IOEncoding"), 'replace') self.buf.append(line) @@ -280,8 +275,8 @@ It reads the error output of the process and inserts it into the error pane. """ - if self.process is not None: - s = str(self.process.readAllStandardError(), + if self.__process is not None: + s = str(self.__process.readAllStandardError(), Preferences.getSystem("IOEncoding"), 'replace') self.__showError(s) @@ -351,7 +346,7 @@ self.errors.ensureCursorVisible() self.errorGroup.show() - self.process.write(strToQByteArray(inputTxt)) + self.__process.write(strToQByteArray(inputTxt)) self.passwordCheckBox.setChecked(False) self.input.clear()
--- a/eric6/Plugins/VcsPlugins/vcsGit/GitDiffDialog.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/Plugins/VcsPlugins/vcsGit/GitDiffDialog.py Sat Oct 10 12:20:51 2020 +0200 @@ -10,8 +10,8 @@ from PyQt5.QtCore import pyqtSlot, QFileInfo, Qt -from PyQt5.QtGui import QTextCursor, QCursor -from PyQt5.QtWidgets import QWidget, QDialogButtonBox, QApplication +from PyQt5.QtGui import QTextCursor +from PyQt5.QtWidgets import QWidget, QDialogButtonBox from E5Gui import E5MessageBox, E5FileDialog from E5Gui.E5Application import e5App @@ -169,11 +169,9 @@ self.contentsGroup.setTitle( self.tr("Difference ({0})").format(msg)) - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) procStarted = self.__diffGenerator.start( fn, versions=versions, diffMode=diffMode, stashName=stashName) if not procStarted: - QApplication.restoreOverrideCursor() E5MessageBox.critical( self, self.tr('Process Generation Error'), @@ -187,7 +185,6 @@ """ Private slot connected to the finished signal. """ - QApplication.restoreOverrideCursor() self.refreshButton.setEnabled(True) diff1, diff2, errors, fileSeparators = self.__diffGenerator.getResult()
--- a/eric6/Plugins/VcsPlugins/vcsGit/GitDiffGenerator.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/Plugins/VcsPlugins/vcsGit/GitDiffGenerator.py Sat Oct 10 12:20:51 2020 +0200 @@ -13,6 +13,8 @@ from PyQt5.QtCore import pyqtSignal, QProcess, QTimer, QObject +from E5Gui.E5OverrideCursor import E5OverrideCursorProcess + import Preferences @@ -35,25 +37,25 @@ self.vcs = vcs - self.process = QProcess() - self.process.finished.connect(self.__procFinished) - self.process.readyReadStandardOutput.connect( - lambda: self.__readStdout(self.process)) - self.process.readyReadStandardError.connect( - lambda: self.__readStderr(self.process)) + self.__process = E5OverrideCursorProcess() + self.__process.finished.connect(self.__procFinished) + self.__process.readyReadStandardOutput.connect( + lambda: self.__readStdout(self.__process)) + self.__process.readyReadStandardError.connect( + lambda: self.__readStderr(self.__process)) - self.process2 = QProcess() - self.process2.finished.connect(self.__procFinished) - self.process2.readyReadStandardOutput.connect( - lambda: self.__readStdout(self.process2)) - self.process2.readyReadStandardError.connect( - lambda: self.__readStderr(self.process2)) + self.__process2 = E5OverrideCursorProcess() + self.__process2.finished.connect(self.__procFinished) + self.__process2.readyReadStandardOutput.connect( + lambda: self.__readStdout(self.__process2)) + self.__process2.readyReadStandardError.connect( + lambda: self.__readStderr(self.__process2)) def stopProcesses(self): """ Public slot to stop the diff processes. """ - for process in [self.process, self.process2]: + for process in [self.__process, self.__process2]: if ( process is not None and process.state() != QProcess.NotRunning @@ -139,18 +141,18 @@ if os.path.splitdrive(repodir)[1] == os.sep: return False - self.process.kill() - self.process.setWorkingDirectory(repodir) - self.process.start('git', args) - procStarted = self.process.waitForStarted(5000) + self.__process.kill() + self.__process.setWorkingDirectory(repodir) + self.__process.start('git', args) + procStarted = self.__process.waitForStarted(5000) if not procStarted: return False if diffMode == "work2stage2repo": - self.process2.kill() - self.process2.setWorkingDirectory(repodir) - self.process2.start('git', args2) - procStarted = self.process2.waitForStarted(5000) + self.__process2.kill() + self.__process2.setWorkingDirectory(repodir) + self.__process2.start('git', args2) + procStarted = self.__process2.waitForStarted(5000) if not procStarted: return False @@ -164,8 +166,8 @@ @param exitStatus exit status of the process (QProcess.ExitStatus) """ if ( - self.process.state() == QProcess.NotRunning and - self.process2.state() == QProcess.NotRunning + self.__process.state() == QProcess.NotRunning and + self.__process2.state() == QProcess.NotRunning ): self.finished.emit() @@ -226,7 +228,7 @@ """ process.setReadChannel(QProcess.StandardOutput) - isTopDiff = process == self.process + isTopDiff = process == self.__process while process.canReadLine(): line = str(process.readLine(), self.__ioEncoding,
--- a/eric6/Plugins/VcsPlugins/vcsGit/GitLogBrowserDialog.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/Plugins/VcsPlugins/vcsGit/GitLogBrowserDialog.py Sat Oct 10 12:20:51 2020 +0200 @@ -15,7 +15,7 @@ pyqtSlot, Qt, QDate, QProcess, QTimer, QRegExp, QSize, QPoint, QFileInfo ) from PyQt5.QtGui import ( - QCursor, QColor, QPixmap, QPainter, QPen, QIcon, QTextCursor, QPalette + QColor, QPixmap, QPainter, QPen, QIcon, QTextCursor, QPalette ) from PyQt5.QtWidgets import ( QWidget, QDialogButtonBox, QHeaderView, QTreeWidgetItem, QApplication, @@ -24,6 +24,7 @@ from E5Gui.E5Application import e5App from E5Gui import E5MessageBox, E5FileDialog +from E5Gui.E5OverrideCursor import E5OverrideCursorProcess from Globals import strToQByteArray @@ -194,10 +195,10 @@ # roles used in the file tree self.__diffFileLineRole = Qt.UserRole - self.process = QProcess() - self.process.finished.connect(self.__procFinished) - self.process.readyReadStandardOutput.connect(self.__readStdout) - self.process.readyReadStandardError.connect(self.__readStderr) + self.__process = E5OverrideCursorProcess() + self.__process.finished.connect(self.__procFinished) + self.__process.readyReadStandardOutput.connect(self.__readStdout) + self.__process.readyReadStandardError.connect(self.__readStderr) self.flags = { 'A': self.tr('Added'), @@ -383,12 +384,12 @@ @param e close event (QCloseEvent) """ if ( - self.process is not None and - self.process.state() != QProcess.NotRunning + self.__process is not None and + self.__process.state() != QProcess.NotRunning ): - self.process.terminate() - QTimer.singleShot(2000, self.process.kill) - self.process.waitForFinished(3000) + self.__process.terminate() + QTimer.singleShot(2000, self.__process.kill) + self.__process.waitForFinished(3000) self.vcs.getPlugin().setPreferences( "LogBrowserGeometry", self.saveGeometry()) @@ -782,9 +783,6 @@ self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) QApplication.processEvents() - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() - self.buf = [] self.cancelled = False self.errors.clear() @@ -810,12 +808,12 @@ args.append('--') args.append(self.__filename) - self.process.kill() + self.__process.kill() - self.process.setWorkingDirectory(self.repodir) + self.__process.setWorkingDirectory(self.repodir) - self.process.start('git', args) - procStarted = self.process.waitForStarted(5000) + self.__process.start('git', args) + procStarted = self.__process.waitForStarted(5000) if not procStarted: self.inputGroup.setEnabled(False) self.inputGroup.hide() @@ -881,14 +879,12 @@ the button. """ if ( - self.process is not None and - self.process.state() != QProcess.NotRunning + self.__process is not None and + self.__process.state() != QProcess.NotRunning ): - self.process.terminate() - QTimer.singleShot(2000, self.process.kill) - self.process.waitForFinished(3000) - - QApplication.restoreOverrideCursor() + self.__process.terminate() + QTimer.singleShot(2000, self.__process.kill) + self.__process.waitForFinished(3000) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) @@ -1052,10 +1048,10 @@ It reads the output of the process and inserts it into a buffer. """ - self.process.setReadChannel(QProcess.StandardOutput) + self.__process.setReadChannel(QProcess.StandardOutput) - while self.process.canReadLine(): - line = str(self.process.readLine(), + while self.__process.canReadLine(): + line = str(self.__process.readLine(), Preferences.getSystem("IOEncoding"), 'replace') self.buf.append(line) @@ -1067,8 +1063,8 @@ It reads the error output of the process and inserts it into the error pane. """ - if self.process is not None: - s = str(self.process.readAllStandardError(), + if self.__process is not None: + s = str(self.__process.readAllStandardError(), Preferences.getSystem("IOEncoding"), 'replace') self.__showError(s) @@ -1147,7 +1143,7 @@ self.errors.ensureCursorVisible() self.errorGroup.show() - self.process.write(strToQByteArray(inputTxt)) + self.__process.write(strToQByteArray(inputTxt)) self.passwordCheckBox.setChecked(False) self.input.clear()
--- a/eric6/Plugins/VcsPlugins/vcsGit/GitReflogBrowserDialog.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/Plugins/VcsPlugins/vcsGit/GitReflogBrowserDialog.py Sat Oct 10 12:20:51 2020 +0200 @@ -11,13 +11,13 @@ import os from PyQt5.QtCore import pyqtSlot, Qt, QProcess, QTimer, QPoint -from PyQt5.QtGui import QCursor from PyQt5.QtWidgets import ( QWidget, QDialogButtonBox, QHeaderView, QTreeWidgetItem, QApplication, QLineEdit ) from E5Gui import E5MessageBox +from E5Gui.E5OverrideCursor import E5OverrideCursorProcess from .Ui_GitReflogBrowserDialog import Ui_GitReflogBrowserDialog @@ -75,10 +75,10 @@ self.__initData() self.__resetUI() - self.process = QProcess() - self.process.finished.connect(self.__procFinished) - self.process.readyReadStandardOutput.connect(self.__readStdout) - self.process.readyReadStandardError.connect(self.__readStderr) + self.__process = E5OverrideCursorProcess() + self.__process.finished.connect(self.__procFinished) + self.__process.readyReadStandardOutput.connect(self.__readStdout) + self.__process.readyReadStandardError.connect(self.__readStderr) def __initData(self): """ @@ -95,12 +95,12 @@ @param e close event (QCloseEvent) """ if ( - self.process is not None and - self.process.state() != QProcess.NotRunning + self.__process is not None and + self.__process.state() != QProcess.NotRunning ): - self.process.terminate() - QTimer.singleShot(2000, self.process.kill) - self.process.waitForFinished(3000) + self.__process.terminate() + QTimer.singleShot(2000, self.__process.kill) + self.__process.waitForFinished(3000) self.__position = self.pos() @@ -165,9 +165,6 @@ self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) QApplication.processEvents() - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() - self.buf = [] self.cancelled = False self.errors.clear() @@ -181,15 +178,15 @@ args.append('--format={0}'.format(self.__formatTemplate)) args.append('--skip={0}'.format(skip)) - self.process.kill() + self.__process.kill() - self.process.setWorkingDirectory(self.repodir) + self.__process.setWorkingDirectory(self.repodir) self.inputGroup.setEnabled(True) self.inputGroup.show() - self.process.start('git', args) - procStarted = self.process.waitForStarted(5000) + self.__process.start('git', args) + procStarted = self.__process.waitForStarted(5000) if not procStarted: self.inputGroup.setEnabled(False) self.inputGroup.hide() @@ -242,14 +239,12 @@ the button. """ if ( - self.process is not None and - self.process.state() != QProcess.NotRunning + self.__process is not None and + self.__process.state() != QProcess.NotRunning ): - self.process.terminate() - QTimer.singleShot(2000, self.process.kill) - self.process.waitForFinished(3000) - - QApplication.restoreOverrideCursor() + self.__process.terminate() + QTimer.singleShot(2000, self.__process.kill) + self.__process.waitForFinished(3000) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) @@ -313,10 +308,10 @@ It reads the output of the process and inserts it into a buffer. """ - self.process.setReadChannel(QProcess.StandardOutput) + self.__process.setReadChannel(QProcess.StandardOutput) - while self.process.canReadLine(): - line = str(self.process.readLine(), + while self.__process.canReadLine(): + line = str(self.__process.readLine(), Preferences.getSystem("IOEncoding"), 'replace') self.buf.append(line) @@ -328,8 +323,8 @@ It reads the error output of the process and inserts it into the error pane. """ - if self.process is not None: - s = str(self.process.readAllStandardError(), + if self.__process is not None: + s = str(self.__process.readAllStandardError(), Preferences.getSystem("IOEncoding"), 'replace') self.__showError(s) @@ -399,7 +394,7 @@ self.errors.ensureCursorVisible() self.errorGroup.show() - self.process.write(strToQByteArray(inputTxt)) + self.__process.write(strToQByteArray(inputTxt)) self.passwordCheckBox.setChecked(False) self.input.clear()
--- a/eric6/Plugins/VcsPlugins/vcsGit/GitStashBrowserDialog.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/Plugins/VcsPlugins/vcsGit/GitStashBrowserDialog.py Sat Oct 10 12:20:51 2020 +0200 @@ -11,13 +11,13 @@ import os from PyQt5.QtCore import pyqtSlot, Qt, QPoint, QProcess, QTimer -from PyQt5.QtGui import QCursor from PyQt5.QtWidgets import ( QWidget, QDialogButtonBox, QTreeWidgetItem, QAbstractButton, QMenu, QHeaderView, QApplication, QLineEdit ) from E5Gui import E5MessageBox +from E5Gui.E5OverrideCursor import E5OverrideCursorProcess from .Ui_GitStashBrowserDialog import Ui_GitStashBrowserDialog @@ -69,10 +69,10 @@ self.__ioEncoding = Preferences.getSystem("IOEncoding") - self.process = QProcess() - self.process.finished.connect(self.__procFinished) - self.process.readyReadStandardOutput.connect(self.__readStdout) - self.process.readyReadStandardError.connect(self.__readStderr) + self.__process = E5OverrideCursorProcess() + self.__process.finished.connect(self.__procFinished) + self.__process.readyReadStandardOutput.connect(self.__readStdout) + self.__process.readyReadStandardError.connect(self.__readStderr) self.__contextMenu = QMenu() self.__differencesAct = self.__contextMenu.addAction( @@ -98,12 +98,12 @@ @param e close event (QCloseEvent) """ if ( - self.process is not None and - self.process.state() != QProcess.NotRunning + self.__process is not None and + self.__process.state() != QProcess.NotRunning ): - self.process.terminate() - QTimer.singleShot(2000, self.process.kill) - self.process.waitForFinished(3000) + self.__process.terminate() + QTimer.singleShot(2000, self.__process.kill) + self.__process.waitForFinished(3000) self.__position = self.pos() @@ -154,9 +154,6 @@ self.inputGroup.show() self.refreshButton.setEnabled(False) - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() - self.buf = [] self.errors.clear() self.intercept = False @@ -165,15 +162,15 @@ args.append("list") args.append("--format=format:%gd{0}%ai{0}%gs%n".format(self.Separator)) - self.process.kill() + self.__process.kill() - self.process.setWorkingDirectory(self.repodir) + self.__process.setWorkingDirectory(self.repodir) self.inputGroup.setEnabled(True) self.inputGroup.show() - self.process.start('git', args) - procStarted = self.process.waitForStarted(5000) + self.__process.start('git', args) + procStarted = self.__process.waitForStarted(5000) if not procStarted: self.inputGroup.setEnabled(False) self.inputGroup.hide() @@ -226,14 +223,12 @@ the button. """ if ( - self.process is not None and - self.process.state() != QProcess.NotRunning + self.__process is not None and + self.__process.state() != QProcess.NotRunning ): - self.process.terminate() - QTimer.singleShot(2000, self.process.kill) - self.process.waitForFinished(3000) - - QApplication.restoreOverrideCursor() + self.__process.terminate() + QTimer.singleShot(2000, self.__process.kill) + self.__process.waitForFinished(3000) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) @@ -264,10 +259,10 @@ It reads the output of the process and inserts it into a buffer. """ - self.process.setReadChannel(QProcess.StandardOutput) + self.__process.setReadChannel(QProcess.StandardOutput) - while self.process.canReadLine(): - line = str(self.process.readLine(), self.__ioEncoding, + while self.__process.canReadLine(): + line = str(self.__process.readLine(), self.__ioEncoding, 'replace').strip() if line: self.buf.append(line) @@ -279,8 +274,8 @@ It reads the error output of the process and inserts it into the error pane. """ - if self.process is not None: - s = str(self.process.readAllStandardError(), + if self.__process is not None: + s = str(self.__process.readAllStandardError(), self.__ioEncoding, 'replace') self.errorGroup.show() self.errors.insertPlainText(s) @@ -413,7 +408,7 @@ self.errors.ensureCursorVisible() self.errorGroup.show() - self.process.write(strToQByteArray(inputTxt)) + self.__process.write(strToQByteArray(inputTxt)) self.passwordCheckBox.setChecked(False) self.input.clear()
--- a/eric6/Plugins/VcsPlugins/vcsMercurial/HgConflictsListDialog.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/Plugins/VcsPlugins/vcsMercurial/HgConflictsListDialog.py Sat Oct 10 12:20:51 2020 +0200 @@ -132,8 +132,6 @@ Private slot called when the process finished or the user pressed the button. """ - QApplication.restoreOverrideCursor() - self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True)
--- a/eric6/Plugins/VcsPlugins/vcsMercurial/HgDiffDialog.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/Plugins/VcsPlugins/vcsMercurial/HgDiffDialog.py Sat Oct 10 12:20:51 2020 +0200 @@ -9,8 +9,8 @@ from PyQt5.QtCore import pyqtSlot, QFileInfo, Qt -from PyQt5.QtGui import QTextCursor, QCursor -from PyQt5.QtWidgets import QWidget, QDialogButtonBox, QApplication +from PyQt5.QtGui import QTextCursor +from PyQt5.QtWidgets import QWidget, QDialogButtonBox from E5Gui import E5MessageBox, E5FileDialog from E5Gui.E5Application import e5App @@ -95,7 +95,6 @@ self.raise_() self.activateWindow() - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) procStarted = self.__diffGenerator.start( fn, versions=versions, bundle=bundle, qdiff=qdiff) if not procStarted: @@ -111,7 +110,6 @@ """ Private slot connected to the finished signal. """ - QApplication.restoreOverrideCursor() self.refreshButton.setEnabled(True) diff, errors, fileSeparators = self.__diffGenerator.getResult()
--- a/eric6/Plugins/VcsPlugins/vcsMercurial/HgDiffGenerator.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/Plugins/VcsPlugins/vcsMercurial/HgDiffGenerator.py Sat Oct 10 12:20:51 2020 +0200 @@ -11,6 +11,8 @@ from PyQt5.QtCore import pyqtSignal, QObject +from E5Gui.E5OverrideCursor import E5OverrideCursor + class HgDiffGenerator(QObject): """ @@ -64,59 +66,60 @@ @return flag indicating a successful start of the diff command (boolean) """ - if qdiff: - args = self.vcs.initCommand("qdiff") - else: - args = self.vcs.initCommand("diff") - - if self.vcs.hasSubrepositories(): - args.append("--subrepos") - - if bundle: - args.append('--repository') - args.append(bundle) - elif self.vcs.bundleFile and os.path.exists(self.vcs.bundleFile): - args.append('--repository') - args.append(self.vcs.bundleFile) - - if versions is not None: - rev1 = self.__getVersionArg(versions[0]) - rev2 = None - if len(versions) == 2: - rev2 = self.__getVersionArg(versions[1]) + with E5OverrideCursor(): + if qdiff: + args = self.vcs.initCommand("qdiff") + else: + args = self.vcs.initCommand("diff") + + if self.vcs.hasSubrepositories(): + args.append("--subrepos") + + if bundle: + args.append('--repository') + args.append(bundle) + elif self.vcs.bundleFile and os.path.exists(self.vcs.bundleFile): + args.append('--repository') + args.append(self.vcs.bundleFile) - if rev1 is not None or rev2 is not None: - args.append('-r') - if rev1 is not None and rev2 is not None: - args.append('{0}:{1}'.format(rev1, rev2)) - elif rev2 is None: - args.append(rev1) - elif rev1 is None: - args.append(':{0}'.format(rev2)) - - if isinstance(fn, list): - dname, fnames = self.vcs.splitPathList(fn) - self.vcs.addArguments(args, fn) - else: - dname, fname = self.vcs.splitPath(fn) - args.append(fn) - - self.__oldFile = "" - self.__oldFileLine = -1 - self.__fileSeparators = [] - self.__output = [] - self.__errors = [] - - out, err = self.__hgClient.runcommand(args) - - if err: - self.__errors = err.splitlines(True) - - if out: - for line in out.splitlines(True): - self.__processOutputLine(line) - if self.__hgClient.wasCanceled(): - break + if versions is not None: + rev1 = self.__getVersionArg(versions[0]) + rev2 = None + if len(versions) == 2: + rev2 = self.__getVersionArg(versions[1]) + + if rev1 is not None or rev2 is not None: + args.append('-r') + if rev1 is not None and rev2 is not None: + args.append('{0}:{1}'.format(rev1, rev2)) + elif rev2 is None: + args.append(rev1) + elif rev1 is None: + args.append(':{0}'.format(rev2)) + + if isinstance(fn, list): + dname, fnames = self.vcs.splitPathList(fn) + self.vcs.addArguments(args, fn) + else: + dname, fname = self.vcs.splitPath(fn) + args.append(fn) + + self.__oldFile = "" + self.__oldFileLine = -1 + self.__fileSeparators = [] + self.__output = [] + self.__errors = [] + + out, err = self.__hgClient.runcommand(args) + + if err: + self.__errors = err.splitlines(True) + + if out: + for line in out.splitlines(True): + self.__processOutputLine(line) + if self.__hgClient.wasCanceled(): + break self.__finish()
--- a/eric6/Plugins/VcsPlugins/vcsMercurial/HgLogBrowserDialog.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/Plugins/VcsPlugins/vcsMercurial/HgLogBrowserDialog.py Sat Oct 10 12:20:51 2020 +0200 @@ -13,8 +13,7 @@ from PyQt5.QtCore import pyqtSlot, Qt, QDate, QRegExp, QSize, QPoint, QFileInfo from PyQt5.QtGui import ( - QCursor, QColor, QPixmap, QPainter, QPen, QBrush, QIcon, QTextCursor, - QPalette + QColor, QPixmap, QPainter, QPen, QBrush, QIcon, QTextCursor, QPalette ) from PyQt5.QtWidgets import ( QWidget, QDialogButtonBox, QHeaderView, QTreeWidgetItem, QApplication, @@ -23,6 +22,7 @@ from E5Gui.E5Application import e5App from E5Gui import E5MessageBox, E5FileDialog +from E5Gui.E5OverrideCursor import E5OverrideCursor from .Ui_HgLogBrowserDialog import Ui_HgLogBrowserDialog @@ -968,89 +968,87 @@ self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) QApplication.processEvents() - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() - - self.buf = [] - self.cancelled = False - self.errors.clear() - self.intercept = False - - if noEntries == 0: - noEntries = self.limitSpinBox.value() - - preargs = [] - args = self.vcs.initCommand(self.commandMode) - args.append('--verbose') - if self.commandMode not in ("incoming", "outgoing"): - args.append('--limit') - args.append(str(noEntries)) - if self.commandMode in ("incoming", "outgoing"): - args.append("--newest-first") - if self.vcs.hasSubrepositories(): - args.append("--subrepos") - if startRev is not None: - args.append('--rev') - args.append('{0}:0'.format(startRev)) - if ( - not self.projectMode and - not self.fname == "." and - not self.stopCheckBox.isChecked() - ): - args.append('--follow') - if self.commandMode == "log": - args.append('--copies') - args.append('--template') - args.append(os.path.join(os.path.dirname(__file__), - "templates", - "logBrowserBookmarkPhase.tmpl")) - if self.commandMode == "incoming": - if self.__bundle: - args.append(self.__bundle) - elif not self.vcs.hasSubrepositories(): - project = e5App().getObject("Project") - self.vcs.bundleFile = os.path.join( - project.getProjectManagementDir(), "hg-bundle.hg") - if os.path.exists(self.vcs.bundleFile): - os.remove(self.vcs.bundleFile) - preargs = args[:] - preargs.append("--quiet") - preargs.append('--bundle') - preargs.append(self.vcs.bundleFile) - args.append(self.vcs.bundleFile) - if not self.projectMode: - args.append(self.__filename) - - if preargs: - out, err = self.__hgClient.runcommand(preargs) - else: - err = "" - if err: + with E5OverrideCursor(): + self.buf = [] + self.cancelled = False + self.errors.clear() + self.intercept = False + + if noEntries == 0: + noEntries = self.limitSpinBox.value() + + preargs = [] + args = self.vcs.initCommand(self.commandMode) + args.append('--verbose') + if self.commandMode not in ("incoming", "outgoing"): + args.append('--limit') + args.append(str(noEntries)) + if self.commandMode in ("incoming", "outgoing"): + args.append("--newest-first") + if self.vcs.hasSubrepositories(): + args.append("--subrepos") + if startRev is not None: + args.append('--rev') + args.append('{0}:0'.format(startRev)) if ( + not self.projectMode and + not self.fname == "." and + not self.stopCheckBox.isChecked() + ): + args.append('--follow') + if self.commandMode == "log": + args.append('--copies') + args.append('--template') + args.append(os.path.join(os.path.dirname(__file__), + "templates", + "logBrowserBookmarkPhase.tmpl")) + if self.commandMode == "incoming": + if self.__bundle: + args.append(self.__bundle) + elif not self.vcs.hasSubrepositories(): + project = e5App().getObject("Project") + self.vcs.bundleFile = os.path.join( + project.getProjectManagementDir(), "hg-bundle.hg") + if os.path.exists(self.vcs.bundleFile): + os.remove(self.vcs.bundleFile) + preargs = args[:] + preargs.append("--quiet") + preargs.append('--bundle') + preargs.append(self.vcs.bundleFile) + args.append(self.vcs.bundleFile) + if not self.projectMode: + args.append(self.__filename) + + if preargs: + out, err = self.__hgClient.runcommand(preargs) + else: + err = "" + if err: + if ( + self.commandMode == "incoming" and + self.initialCommandMode == "full_log" + ): + # ignore the error + self.commandMode = "log" + else: + self.__showError(err) + elif ( + self.commandMode != "incoming" or + (self.vcs.bundleFile and + os.path.exists(self.vcs.bundleFile)) or + self.__bundle + ): + out, err = self.__hgClient.runcommand(args) + self.buf = out.splitlines(True) + if err: + self.__showError(err) + self.__processBuffer() + elif ( self.commandMode == "incoming" and self.initialCommandMode == "full_log" ): - # ignore the error + # no incoming changesets, just switch to log mode self.commandMode = "log" - else: - self.__showError(err) - elif ( - self.commandMode != "incoming" or - (self.vcs.bundleFile and - os.path.exists(self.vcs.bundleFile)) or - self.__bundle - ): - out, err = self.__hgClient.runcommand(args) - self.buf = out.splitlines(True) - if err: - self.__showError(err) - self.__processBuffer() - elif ( - self.commandMode == "incoming" and - self.initialCommandMode == "full_log" - ): - # no incoming changesets, just switch to log mode - self.commandMode = "log" self.__finish() def start(self, fn, bundle=None, isFile=False, noEntries=0): @@ -1109,8 +1107,6 @@ Private slot called when the process finished or the user pressed the button. """ - QApplication.restoreOverrideCursor() - self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True)
--- a/eric6/Plugins/VcsPlugins/vcsMercurial/ShelveExtension/HgShelveBrowserDialog.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/Plugins/VcsPlugins/vcsMercurial/ShelveExtension/HgShelveBrowserDialog.py Sat Oct 10 12:20:51 2020 +0200 @@ -10,12 +10,13 @@ import os from PyQt5.QtCore import pyqtSlot, Qt, QPoint -from PyQt5.QtGui import QCursor from PyQt5.QtWidgets import ( QWidget, QDialogButtonBox, QTreeWidgetItem, QAbstractButton, QMenu, QHeaderView, QApplication ) +from E5Gui.E5OverrideCursor import E5OverrideCursor + from .Ui_HgShelveBrowserDialog import Ui_HgShelveBrowserDialog @@ -129,9 +130,6 @@ self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) QApplication.processEvents() - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() - self.buf = [] self.errors.clear() self.intercept = False @@ -140,11 +138,12 @@ args.append("--list") args.append("--stat") - out, err = self.__hgClient.runcommand(args) - self.buf = out.splitlines(True) - if err: - self.__showError(err) - self.__processBuffer() + with E5OverrideCursor(): + out, err = self.__hgClient.runcommand(args) + self.buf = out.splitlines(True) + if err: + self.__showError(err) + self.__processBuffer() self.__finish() def start(self, projectDir): @@ -177,8 +176,6 @@ Private slot called when the process finished or the user pressed the button. """ - QApplication.restoreOverrideCursor() - self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True)
--- a/eric6/Plugins/VcsPlugins/vcsPySvn/SvnChangeListsDialog.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/Plugins/VcsPlugins/vcsPySvn/SvnChangeListsDialog.py Sat Oct 10 12:20:51 2020 +0200 @@ -7,16 +7,14 @@ Module implementing a dialog to browse the change lists. """ - import os import pysvn from PyQt5.QtCore import pyqtSlot, Qt, QMutexLocker -from PyQt5.QtGui import QCursor -from PyQt5.QtWidgets import ( - QDialog, QDialogButtonBox, QListWidgetItem, QApplication -) +from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QListWidgetItem + +from E5Gui.E5OverrideCursor import E5OverrideCursor from .SvnDialogMixin import SvnDialogMixin @@ -78,24 +76,22 @@ self.filesLabel.setText( self.tr("Files (relative to {0}):").format(path)) - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() - - locker = QMutexLocker(self.vcs.vcsExecutionMutex) - try: - entries = self.client.get_changelist( - path, depth=pysvn.depth.infinity) - for entry in entries: - file = entry[0] - changelist = entry[1] - if changelist not in self.changeListsDict: - self.changeListsDict[changelist] = [] - filename = file.replace(path + os.sep, "") - if filename not in self.changeListsDict[changelist]: - self.changeListsDict[changelist].append(filename) - except pysvn.ClientError as e: - locker.unlock() - self.__showError(e.args[0]) + with E5OverrideCursor(): + locker = QMutexLocker(self.vcs.vcsExecutionMutex) + try: + entries = self.client.get_changelist( + path, depth=pysvn.depth.infinity) + for entry in entries: + file = entry[0] + changelist = entry[1] + if changelist not in self.changeListsDict: + self.changeListsDict[changelist] = [] + filename = file.replace(path + os.sep, "") + if filename not in self.changeListsDict[changelist]: + self.changeListsDict[changelist].append(filename) + except pysvn.ClientError as e: + locker.unlock() + self.__showError(e.args[0]) self.__finish() def __finish(self): @@ -103,7 +99,6 @@ Private slot called when the user pressed the button. """ self.changeLists.addItems(sorted(self.changeListsDict.keys())) - QApplication.restoreOverrideCursor() self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False)
--- a/eric6/Plugins/VcsPlugins/vcsPySvn/SvnDialogMixin.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/Plugins/VcsPlugins/vcsPySvn/SvnDialogMixin.py Sat Oct 10 12:20:51 2020 +0200 @@ -8,9 +8,9 @@ the pysvn client. """ +from PyQt5.QtWidgets import QApplication, QDialog, QWidget -from PyQt5.QtCore import Qt -from PyQt5.QtWidgets import QApplication, QDialog, QWidget +from E5Gui.E5OverrideCursor import E5OverridenCursor class SvnDialogMixin(object): @@ -63,14 +63,12 @@ password should be saved. """ from .SvnLoginDialog import SvnLoginDialog - cursor = QApplication.overrideCursor() - if cursor is not None: - QApplication.restoreOverrideCursor() - parent = isinstance(self, QWidget) and self or None - dlg = SvnLoginDialog(realm, username, may_save, parent) - res = dlg.exec() - if cursor is not None: - QApplication.setOverrideCursor(Qt.WaitCursor) + + with E5OverridenCursor(): + parent = isinstance(self, QWidget) and self or None + dlg = SvnLoginDialog(realm, username, may_save, parent) + res = dlg.exec() + if res == QDialog.Accepted: loginData = dlg.getData() return (True, loginData[0], loginData[1], loginData[2]) @@ -90,37 +88,34 @@ """ from E5Gui import E5MessageBox - cursor = QApplication.overrideCursor() - if cursor is not None: - QApplication.restoreOverrideCursor() - parent = isinstance(self, QWidget) and self or None - msgBox = E5MessageBox.E5MessageBox( - E5MessageBox.Question, - self.tr("Subversion SSL Server Certificate"), - self.tr("""<p>Accept the following SSL certificate?</p>""" - """<table>""" - """<tr><td>Realm:</td><td>{0}</td></tr>""" - """<tr><td>Hostname:</td><td>{1}</td></tr>""" - """<tr><td>Fingerprint:</td><td>{2}</td></tr>""" - """<tr><td>Valid from:</td><td>{3}</td></tr>""" - """<tr><td>Valid until:</td><td>{4}</td></tr>""" - """<tr><td>Issuer name:</td><td>{5}</td></tr>""" - """</table>""") - .format(trust_dict["realm"], - trust_dict["hostname"], - trust_dict["finger_print"], - trust_dict["valid_from"], - trust_dict["valid_until"], - trust_dict["issuer_dname"]), - modal=True, parent=parent) - permButton = msgBox.addButton(self.tr("&Permanent accept"), - E5MessageBox.AcceptRole) - tempButton = msgBox.addButton(self.tr("&Temporary accept"), - E5MessageBox.AcceptRole) - msgBox.addButton(self.tr("&Reject"), E5MessageBox.RejectRole) - msgBox.exec() - if cursor is not None: - QApplication.setOverrideCursor(Qt.WaitCursor) + with E5OverridenCursor(): + parent = isinstance(self, QWidget) and self or None + msgBox = E5MessageBox.E5MessageBox( + E5MessageBox.Question, + self.tr("Subversion SSL Server Certificate"), + self.tr("""<p>Accept the following SSL certificate?</p>""" + """<table>""" + """<tr><td>Realm:</td><td>{0}</td></tr>""" + """<tr><td>Hostname:</td><td>{1}</td></tr>""" + """<tr><td>Fingerprint:</td><td>{2}</td></tr>""" + """<tr><td>Valid from:</td><td>{3}</td></tr>""" + """<tr><td>Valid until:</td><td>{4}</td></tr>""" + """<tr><td>Issuer name:</td><td>{5}</td></tr>""" + """</table>""") + .format(trust_dict["realm"], + trust_dict["hostname"], + trust_dict["finger_print"], + trust_dict["valid_from"], + trust_dict["valid_until"], + trust_dict["issuer_dname"]), + modal=True, parent=parent) + permButton = msgBox.addButton(self.tr("&Permanent accept"), + E5MessageBox.AcceptRole) + tempButton = msgBox.addButton(self.tr("&Temporary accept"), + E5MessageBox.AcceptRole) + msgBox.addButton(self.tr("&Reject"), E5MessageBox.RejectRole) + msgBox.exec() + if msgBox.clickedButton() == permButton: return (True, trust_dict["failures"], True) elif msgBox.clickedButton() == tempButton:
--- a/eric6/Plugins/VcsPlugins/vcsPySvn/SvnDiffDialog.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/Plugins/VcsPlugins/vcsPySvn/SvnDiffDialog.py Sat Oct 10 12:20:51 2020 +0200 @@ -14,11 +14,12 @@ import pysvn from PyQt5.QtCore import QMutexLocker, QFileInfo, QDateTime, Qt, pyqtSlot -from PyQt5.QtGui import QCursor, QTextCursor -from PyQt5.QtWidgets import QWidget, QApplication, QDialogButtonBox +from PyQt5.QtGui import QTextCursor +from PyQt5.QtWidgets import QWidget, QDialogButtonBox from E5Gui.E5Application import e5App from E5Gui import E5MessageBox, E5FileDialog +from E5Gui.E5OverrideCursor import E5OverrideCursor from .SvnDialogMixin import SvnDialogMixin from .Ui_SvnDiffDialog import Ui_SvnDiffDialog @@ -138,8 +139,6 @@ self._reset() self.errorGroup.hide() - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() self.filename = fn self.contents.clear() @@ -200,67 +199,68 @@ dname, fname = self.vcs.splitPath(fn) fnames = [fname] - locker = QMutexLocker(self.vcs.vcsExecutionMutex) - cwd = os.getcwd() - os.chdir(dname) - try: - dname = e5App().getObject('Project').getRelativePath(dname) - if dname: - dname += "/" - for name in fnames: - self.__showError( - self.tr("Processing file '{0}'...\n").format(name)) - if urls is not None: - url1 = "{0}/{1}{2}".format(urls[0], dname, name) - url2 = "{0}/{1}{2}".format(urls[1], dname, name) - if summary: - diff_summary = self.client.diff_summarize( - url1, revision1=rev1, - url_or_path2=url2, revision2=rev2, - recurse=recurse) - diff_list = [] - for diff_sum in diff_summary: - path = diff_sum['path'] - diff_list.append("{0} {1}".format( - self.__getDiffSummaryKind( - diff_sum['summarize_kind']), - path)) - diffText = os.linesep.join(diff_list) + with E5OverrideCursor(): + locker = QMutexLocker(self.vcs.vcsExecutionMutex) + cwd = os.getcwd() + os.chdir(dname) + try: + dname = e5App().getObject('Project').getRelativePath(dname) + if dname: + dname += "/" + for name in fnames: + self.__showError( + self.tr("Processing file '{0}'...\n").format(name)) + if urls is not None: + url1 = "{0}/{1}{2}".format(urls[0], dname, name) + url2 = "{0}/{1}{2}".format(urls[1], dname, name) + if summary: + diff_summary = self.client.diff_summarize( + url1, revision1=rev1, + url_or_path2=url2, revision2=rev2, + recurse=recurse) + diff_list = [] + for diff_sum in diff_summary: + path = diff_sum['path'] + diff_list.append("{0} {1}".format( + self.__getDiffSummaryKind( + diff_sum['summarize_kind']), + path)) + diffText = os.linesep.join(diff_list) + else: + diffText = self.client.diff( + tmpdir, + url1, revision1=rev1, + url_or_path2=url2, revision2=rev2, + recurse=recurse) else: - diffText = self.client.diff( - tmpdir, - url1, revision1=rev1, - url_or_path2=url2, revision2=rev2, - recurse=recurse) - else: - if pegRev is not None: - diffText = self.client.diff_peg( - tmpdir, name, - peg_revision=self.__getVersionArg(pegRev), - revision_start=rev1, revision_end=rev2, - recurse=recurse) - else: - diffText = self.client.diff( - tmpdir, name, - revision1=rev1, revision2=rev2, recurse=recurse) - counter = 0 - for line in diffText.splitlines(): - if line.startswith("--- ") or line.startswith("+++ "): - self.__processFileLine(line) - - self.__appendText("{0}{1}".format(line, os.linesep)) - counter += 1 - if counter == 30: - # check for cancel every 30 lines - counter = 0 - if self._clientCancelCallback(): - break - if self._clientCancelCallback(): - break - except pysvn.ClientError as e: - self.__showError(e.args[0]) - locker.unlock() - os.chdir(cwd) + if pegRev is not None: + diffText = self.client.diff_peg( + tmpdir, name, + peg_revision=self.__getVersionArg(pegRev), + revision_start=rev1, revision_end=rev2, + recurse=recurse) + else: + diffText = self.client.diff( + tmpdir, name, + revision1=rev1, revision2=rev2, recurse=recurse) + counter = 0 + for line in diffText.splitlines(): + if line.startswith("--- ") or line.startswith("+++ "): + self.__processFileLine(line) + + self.__appendText("{0}{1}".format(line, os.linesep)) + counter += 1 + if counter == 30: + # check for cancel every 30 lines + counter = 0 + if self._clientCancelCallback(): + break + if self._clientCancelCallback(): + break + except pysvn.ClientError as e: + self.__showError(e.args[0]) + locker.unlock() + os.chdir(cwd) self.__finish() if self.paras == 0: @@ -309,8 +309,6 @@ """ Private slot called when the user pressed the button. """ - QApplication.restoreOverrideCursor() - self.refreshButton.setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True)
--- a/eric6/Plugins/VcsPlugins/vcsPySvn/SvnLogBrowserDialog.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/Plugins/VcsPlugins/vcsPySvn/SvnLogBrowserDialog.py Sat Oct 10 12:20:51 2020 +0200 @@ -13,12 +13,12 @@ import pysvn from PyQt5.QtCore import QMutexLocker, QDate, QRegExp, Qt, pyqtSlot, QPoint -from PyQt5.QtGui import QCursor from PyQt5.QtWidgets import ( QHeaderView, QWidget, QApplication, QDialogButtonBox, QTreeWidgetItem ) from E5Gui import E5MessageBox +from E5Gui.E5OverrideCursor import E5OverrideCursor from .SvnUtilities import formatTime, dateFromTime_t from .SvnDialogMixin import SvnDialogMixin @@ -264,9 +264,6 @@ fetchLimit = 10 self._reset() - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() - limit = self.limitSpinBox.value() if startRev is None: start = pysvn.Revision(pysvn.opt_revision_kind.head) @@ -277,70 +274,71 @@ except TypeError: start = pysvn.Revision(pysvn.opt_revision_kind.head) - locker = QMutexLocker(self.vcs.vcsExecutionMutex) - cwd = os.getcwd() - os.chdir(self.dname) - try: - nextRev = 0 - fetched = 0 - logs = [] - while fetched < limit: - flimit = min(fetchLimit, limit - fetched) - if fetched == 0: - revstart = start - else: - revstart = pysvn.Revision( - pysvn.opt_revision_kind.number, nextRev) - allLogs = self.client.log( - self.fname, revision_start=revstart, - discover_changed_paths=True, limit=flimit + 1, - strict_node_history=self.stopCheckBox.isChecked()) - if len(allLogs) <= flimit or self._clientCancelCallback(): - logs.extend(allLogs) - break - else: - logs.extend(allLogs[:-1]) - nextRev = allLogs[-1]["revision"].number - fetched += fetchLimit - locker.unlock() - - for log in logs: - author = log["author"] - message = log["message"] - self.__generateLogItem( - author, log["date"], message, - log["revision"], log['changed_paths']) - dt = dateFromTime_t(log["date"]) - if ( - not self.__maxDate.isValid() and - not self.__minDate.isValid() - ): - self.__maxDate = dt - self.__minDate = dt - else: - if self.__maxDate < dt: + with E5OverrideCursor(): + locker = QMutexLocker(self.vcs.vcsExecutionMutex) + cwd = os.getcwd() + os.chdir(self.dname) + try: + nextRev = 0 + fetched = 0 + logs = [] + while fetched < limit: + flimit = min(fetchLimit, limit - fetched) + if fetched == 0: + revstart = start + else: + revstart = pysvn.Revision( + pysvn.opt_revision_kind.number, nextRev) + allLogs = self.client.log( + self.fname, revision_start=revstart, + discover_changed_paths=True, limit=flimit + 1, + strict_node_history=self.stopCheckBox.isChecked()) + if len(allLogs) <= flimit or self._clientCancelCallback(): + logs.extend(allLogs) + break + else: + logs.extend(allLogs[:-1]) + nextRev = allLogs[-1]["revision"].number + fetched += fetchLimit + locker.unlock() + + for log in logs: + author = log["author"] + message = log["message"] + self.__generateLogItem( + author, log["date"], message, + log["revision"], log['changed_paths']) + dt = dateFromTime_t(log["date"]) + if ( + not self.__maxDate.isValid() and + not self.__minDate.isValid() + ): self.__maxDate = dt - if self.__minDate > dt: self.__minDate = dt - if len(logs) < limit and not self.cancelled: - self.nextButton.setEnabled(False) - self.limitSpinBox.setEnabled(False) - self.__filterLogsEnabled = False - self.fromDate.setMinimumDate(self.__minDate) - self.fromDate.setMaximumDate(self.__maxDate) - self.fromDate.setDate(self.__minDate) - self.toDate.setMinimumDate(self.__minDate) - self.toDate.setMaximumDate(self.__maxDate) - self.toDate.setDate(self.__maxDate) - self.__filterLogsEnabled = True - - self.__resizeColumnsLog() - self.__resortLog() - self.__filterLogs() - except pysvn.ClientError as e: - locker.unlock() - self.__showError(e.args[0]) - os.chdir(cwd) + else: + if self.__maxDate < dt: + self.__maxDate = dt + if self.__minDate > dt: + self.__minDate = dt + if len(logs) < limit and not self.cancelled: + self.nextButton.setEnabled(False) + self.limitSpinBox.setEnabled(False) + self.__filterLogsEnabled = False + self.fromDate.setMinimumDate(self.__minDate) + self.fromDate.setMaximumDate(self.__maxDate) + self.fromDate.setDate(self.__minDate) + self.toDate.setMinimumDate(self.__minDate) + self.toDate.setMaximumDate(self.__maxDate) + self.toDate.setDate(self.__maxDate) + self.__filterLogsEnabled = True + + self.__resizeColumnsLog() + self.__resortLog() + self.__filterLogs() + except pysvn.ClientError as e: + locker.unlock() + self.__showError(e.args[0]) + os.chdir(cwd) self.__finish() def start(self, fn, isFile=False): @@ -370,8 +368,6 @@ """ Private slot called when the user pressed the button. """ - QApplication.restoreOverrideCursor() - self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True)
--- a/eric6/Plugins/VcsPlugins/vcsPySvn/SvnRepoBrowserDialog.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/Plugins/VcsPlugins/vcsPySvn/SvnRepoBrowserDialog.py Sat Oct 10 12:20:51 2020 +0200 @@ -11,12 +11,12 @@ import pysvn from PyQt5.QtCore import QMutexLocker, Qt, pyqtSlot -from PyQt5.QtGui import QCursor from PyQt5.QtWidgets import ( QHeaderView, QDialog, QApplication, QDialogButtonBox, QTreeWidgetItem ) from E5Gui import E5MessageBox +from E5Gui.E5OverrideCursor import E5OverrideCursor from .SvnUtilities import formatTime from .SvnDialogMixin import SvnDialogMixin @@ -150,65 +150,62 @@ @param parent reference to the item, the data should be appended to (QTreeWidget or QTreeWidgetItem) """ - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() - if parent is None: parent = self.repoTree - locker = QMutexLocker(self.vcs.vcsExecutionMutex) - - try: + with E5OverrideCursor(): + locker = QMutexLocker(self.vcs.vcsExecutionMutex) try: - entries = self.client.list(url, recurse=False) - firstTime = parent == self.repoTree - for dirent, _lock in entries: - if ( - (firstTime and dirent["path"] != url) or - (parent != self.repoTree and dirent["path"] == url) - ): - continue - if firstTime: - if dirent["repos_path"] != "/": - repoUrl = dirent["path"].replace( - dirent["repos_path"], "") - else: - repoUrl = dirent["path"] - if repoUrl != url: - self.__ignoreExpand = True - itm = self.__generateItem( - parent, "/", "", "", 0, "", - pysvn.node_kind.dir, repoUrl) - itm.setExpanded(True) - parent = itm - urlPart = repoUrl - for element in ( - dirent["repos_path"].split("/")[:-1] - ): - if element: - urlPart = "{0}/{1}".format(urlPart, - element) - itm = self.__generateItem( - parent, element, "", "", 0, "", - pysvn.node_kind.dir, urlPart) - itm.setExpanded(True) - parent = itm - self.__ignoreExpand = False - itm = self.__generateItem( - parent, dirent["repos_path"], dirent["created_rev"], - dirent["last_author"], dirent["size"], dirent["time"], - dirent["kind"], dirent["path"]) - self.__resort() - self.__resizeColumns() - except pysvn.ClientError as e: - self.__showError(e.args[0]) - except AttributeError: - self.__showError( - self.tr("The installed version of PySvn should be " - "1.4.0 or better.")) - finally: - locker.unlock() - QApplication.restoreOverrideCursor() + try: + entries = self.client.list(url, recurse=False) + firstTime = parent == self.repoTree + for dirent, _lock in entries: + if ( + (firstTime and dirent["path"] != url) or + (parent != self.repoTree and dirent["path"] == url) + ): + continue + if firstTime: + if dirent["repos_path"] != "/": + repoUrl = dirent["path"].replace( + dirent["repos_path"], "") + else: + repoUrl = dirent["path"] + if repoUrl != url: + self.__ignoreExpand = True + itm = self.__generateItem( + parent, "/", "", "", 0, "", + pysvn.node_kind.dir, repoUrl) + itm.setExpanded(True) + parent = itm + urlPart = repoUrl + for element in ( + dirent["repos_path"].split("/")[:-1] + ): + if element: + urlPart = "{0}/{1}".format(urlPart, + element) + itm = self.__generateItem( + parent, element, "", "", 0, "", + pysvn.node_kind.dir, urlPart) + itm.setExpanded(True) + parent = itm + self.__ignoreExpand = False + itm = self.__generateItem( + parent, dirent["repos_path"], + dirent["created_rev"], dirent["last_author"], + dirent["size"], dirent["time"], dirent["kind"], + dirent["path"]) + self.__resort() + self.__resizeColumns() + except pysvn.ClientError as e: + self.__showError(e.args[0]) + except AttributeError: + self.__showError( + self.tr("The installed version of PySvn should be " + "1.4.0 or better.")) + finally: + locker.unlock() def __normalizeUrl(self, url): """
--- a/eric6/Plugins/VcsPlugins/vcsPySvn/SvnStatusDialog.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/Plugins/VcsPlugins/vcsPySvn/SvnStatusDialog.py Sat Oct 10 12:20:51 2020 +0200 @@ -14,7 +14,6 @@ import pysvn from PyQt5.QtCore import QMutexLocker, Qt, pyqtSlot -from PyQt5.QtGui import QCursor from PyQt5.QtWidgets import ( QWidget, QHeaderView, QApplication, QMenu, QDialogButtonBox, QTreeWidgetItem @@ -22,6 +21,7 @@ from E5Gui.E5Application import e5App from E5Gui import E5MessageBox +from E5Gui.E5OverrideCursor import E5OverrideCursor from .SvnConst import svnStatusMap from .SvnDialogMixin import SvnDialogMixin @@ -285,9 +285,6 @@ self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.refreshButton.setEnabled(False) - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() - self.args = fn self.setWindowTitle(self.tr('Subversion Status')) @@ -312,136 +309,142 @@ hideHistoryColumn = True hideSwitchedColumn = True - locker = QMutexLocker(self.vcs.vcsExecutionMutex) - cwd = os.getcwd() - os.chdir(self.dname) - try: - for name in fnames: - # step 1: determine changelists and their files - changelistsDict = {} - if hasattr(self.client, 'get_changelist'): - if recurse: - depth = pysvn.depth.infinity - else: - depth = pysvn.depth.immediate - changelists = self.client.get_changelist(name, depth=depth) - for fpath, changelist in changelists: - fpath = Utilities.normcasepath(fpath) - changelistsDict[fpath] = changelist - hideChangelistColumn = ( - hideChangelistColumn and len(changelistsDict) == 0 - ) - - # step 2: determine status of files - allFiles = self.client.status(name, recurse=recurse, - get_all=verbose, ignore=True, - update=update) - counter = 0 - for file in allFiles: - uptodate = True - if file.repos_text_status != pysvn.wc_status_kind.none: - uptodate = ( - uptodate and - file.repos_text_status != - pysvn.wc_status_kind.modified - ) - if file.repos_prop_status != pysvn.wc_status_kind.none: - uptodate = ( - uptodate and - file.repos_prop_status != - pysvn.wc_status_kind.modified - ) - - lockState = " " - if ( - file.entry is not None and - hasattr(file.entry, 'lock_token') and - file.entry.lock_token is not None - ): - lockState = "L" - if hasattr(file, 'repos_lock') and update: - if lockState == "L" and file.repos_lock is None: - lockState = "B" - elif lockState == " " and file.repos_lock is not None: - lockState = "O" - elif ( - lockState == "L" and - file.repos_lock is not None and - file.entry.lock_token != - file.repos_lock["token"] - ): - lockState = "S" - - fpath = Utilities.normcasepath( - os.path.join(self.dname, file.path)) - if fpath in changelistsDict: - changelist = changelistsDict[fpath] - else: - changelist = "" - - hidePropertyStatusColumn = ( - hidePropertyStatusColumn and - file.prop_status in [ - pysvn.wc_status_kind.none, - pysvn.wc_status_kind.normal - ] - ) - hideLockColumns = ( - hideLockColumns and - not file.is_locked and - lockState == " " - ) - hideUpToDateColumn = hideUpToDateColumn and uptodate - hideHistoryColumn = ( - hideHistoryColumn and - not file.is_copied - ) - hideSwitchedColumn = ( - hideSwitchedColumn and - not file.is_switched + with E5OverrideCursor(): + locker = QMutexLocker(self.vcs.vcsExecutionMutex) + cwd = os.getcwd() + os.chdir(self.dname) + try: + for name in fnames: + # step 1: determine changelists and their files + changelistsDict = {} + if hasattr(self.client, 'get_changelist'): + if recurse: + depth = pysvn.depth.infinity + else: + depth = pysvn.depth.immediate + changelists = self.client.get_changelist( + name, depth=depth) + for fpath, changelist in changelists: + fpath = Utilities.normcasepath(fpath) + changelistsDict[fpath] = changelist + hideChangelistColumn = ( + hideChangelistColumn and len(changelistsDict) == 0 ) - self.__generateItem( - changelist, - file.text_status, - file.prop_status, - file.is_locked, - file.is_copied, - file.is_switched, - lockState, - uptodate, - file.entry and file.entry.revision.number or "", - file.entry and file.entry.commit_revision.number or "", - file.entry and file.entry.commit_author or "", - file.path - ) - counter += 1 - if counter == 30: - # check for cancel every 30 items - counter = 0 - if self._clientCancelCallback(): - break - if self._clientCancelCallback(): - break - except pysvn.ClientError as e: - self.__showError(e.args[0] + '\n') - - self.statusList.setColumnHidden(self.__propStatusColumn, - hidePropertyStatusColumn) - self.statusList.setColumnHidden(self.__lockedColumn, - hideLockColumns) - self.statusList.setColumnHidden(self.__lockinfoColumn, - hideLockColumns) - self.statusList.setColumnHidden(self.__upToDateColumn, - hideUpToDateColumn) - self.statusList.setColumnHidden(self.__historyColumn, - hideHistoryColumn) - self.statusList.setColumnHidden(self.__switchedColumn, - hideSwitchedColumn) - self.statusList.setColumnHidden(self.__changelistColumn, - hideChangelistColumn) - - locker.unlock() + # step 2: determine status of files + allFiles = self.client.status(name, recurse=recurse, + get_all=verbose, ignore=True, + update=update) + counter = 0 + for file in allFiles: + uptodate = True + if file.repos_text_status != pysvn.wc_status_kind.none: + uptodate = ( + uptodate and + file.repos_text_status != + pysvn.wc_status_kind.modified + ) + if file.repos_prop_status != pysvn.wc_status_kind.none: + uptodate = ( + uptodate and + file.repos_prop_status != + pysvn.wc_status_kind.modified + ) + + lockState = " " + if ( + file.entry is not None and + hasattr(file.entry, 'lock_token') and + file.entry.lock_token is not None + ): + lockState = "L" + if hasattr(file, 'repos_lock') and update: + if lockState == "L" and file.repos_lock is None: + lockState = "B" + elif ( + lockState == " " and + file.repos_lock is not None + ): + lockState = "O" + elif ( + lockState == "L" and + file.repos_lock is not None and + file.entry.lock_token != + file.repos_lock["token"] + ): + lockState = "S" + + fpath = Utilities.normcasepath( + os.path.join(self.dname, file.path)) + if fpath in changelistsDict: + changelist = changelistsDict[fpath] + else: + changelist = "" + + hidePropertyStatusColumn = ( + hidePropertyStatusColumn and + file.prop_status in [ + pysvn.wc_status_kind.none, + pysvn.wc_status_kind.normal + ] + ) + hideLockColumns = ( + hideLockColumns and + not file.is_locked and + lockState == " " + ) + hideUpToDateColumn = hideUpToDateColumn and uptodate + hideHistoryColumn = ( + hideHistoryColumn and + not file.is_copied + ) + hideSwitchedColumn = ( + hideSwitchedColumn and + not file.is_switched + ) + + self.__generateItem( + changelist, + file.text_status, + file.prop_status, + file.is_locked, + file.is_copied, + file.is_switched, + lockState, + uptodate, + file.entry.revision.number if file.entry else "", + file.entry.commit_revision.number + if file.entry else "", + file.entry.commit_author if file.entry else "", + file.path + ) + counter += 1 + if counter == 30: + # check for cancel every 30 items + counter = 0 + if self._clientCancelCallback(): + break + if self._clientCancelCallback(): + break + except pysvn.ClientError as e: + self.__showError(e.args[0] + '\n') + + self.statusList.setColumnHidden(self.__propStatusColumn, + hidePropertyStatusColumn) + self.statusList.setColumnHidden(self.__lockedColumn, + hideLockColumns) + self.statusList.setColumnHidden(self.__lockinfoColumn, + hideLockColumns) + self.statusList.setColumnHidden(self.__upToDateColumn, + hideUpToDateColumn) + self.statusList.setColumnHidden(self.__historyColumn, + hideHistoryColumn) + self.statusList.setColumnHidden(self.__switchedColumn, + hideSwitchedColumn) + self.statusList.setColumnHidden(self.__changelistColumn, + hideChangelistColumn) + + locker.unlock() self.__finish() os.chdir(cwd) @@ -450,8 +453,6 @@ Private slot called when the process finished or the user pressed the button. """ - QApplication.restoreOverrideCursor() - self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True)
--- a/eric6/Plugins/VcsPlugins/vcsSubversion/SvnLogBrowserDialog.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/Plugins/VcsPlugins/vcsSubversion/SvnLogBrowserDialog.py Sat Oct 10 12:20:51 2020 +0200 @@ -13,13 +13,13 @@ from PyQt5.QtCore import ( QTimer, QDate, QProcess, QRegExp, Qt, pyqtSlot, QPoint ) -from PyQt5.QtGui import QCursor from PyQt5.QtWidgets import ( QHeaderView, QLineEdit, QWidget, QApplication, QDialogButtonBox, QTreeWidgetItem ) from E5Gui import E5MessageBox +from E5Gui.E5OverrideCursor import E5OverrideCursorProcess from .Ui_SvnLogBrowserDialog import Ui_SvnLogBrowserDialog @@ -64,10 +64,10 @@ self.__messageRole = Qt.UserRole self.__changesRole = Qt.UserRole + 1 - self.process = QProcess() - self.process.finished.connect(self.__procFinished) - self.process.readyReadStandardOutput.connect(self.__readStdout) - self.process.readyReadStandardError.connect(self.__readStderr) + self.__process = E5OverrideCursorProcess() + self.__process.finished.connect(self.__procFinished) + self.__process.readyReadStandardOutput.connect(self.__readStdout) + self.__process.readyReadStandardError.connect(self.__readStderr) self.rx_sep1 = QRegExp('\\-+\\s*') self.rx_sep2 = QRegExp('=+\\s*') @@ -136,12 +136,12 @@ @param e close event (QCloseEvent) """ if ( - self.process is not None and - self.process.state() != QProcess.NotRunning + self.__process is not None and + self.__process.state() != QProcess.NotRunning ): - self.process.terminate() - QTimer.singleShot(2000, self.process.kill) - self.process.waitForFinished(3000) + self.__process.terminate() + QTimer.singleShot(2000, self.__process.kill) + self.__process.waitForFinished(3000) self.__position = self.pos() @@ -277,11 +277,8 @@ self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) QApplication.processEvents() - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() - self.intercept = False - self.process.kill() + self.__process.kill() self.buf = [] self.cancelled = False @@ -301,13 +298,13 @@ args.append('--stop-on-copy') args.append(self.fname) - self.process.setWorkingDirectory(self.dname) + self.__process.setWorkingDirectory(self.dname) self.inputGroup.setEnabled(True) self.inputGroup.show() - self.process.start('svn', args) - procStarted = self.process.waitForStarted(5000) + self.__process.start('svn', args) + procStarted = self.__process.waitForStarted(5000) if not procStarted: self.inputGroup.setEnabled(False) self.inputGroup.hide() @@ -361,14 +358,12 @@ button. """ if ( - self.process is not None and - self.process.state() != QProcess.NotRunning + self.__process is not None and + self.__process.state() != QProcess.NotRunning ): - self.process.terminate() - QTimer.singleShot(2000, self.process.kill) - self.process.waitForFinished(3000) - - QApplication.restoreOverrideCursor() + self.__process.terminate() + QTimer.singleShot(2000, self.__process.kill) + self.__process.waitForFinished(3000) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) @@ -471,10 +466,10 @@ It reads the output of the process and inserts it into a buffer. """ - self.process.setReadChannel(QProcess.StandardOutput) + self.__process.setReadChannel(QProcess.StandardOutput) - while self.process.canReadLine(): - line = str(self.process.readLine(), + while self.__process.canReadLine(): + line = str(self.__process.readLine(), Preferences.getSystem("IOEncoding"), 'replace') self.buf.append(line) @@ -486,9 +481,9 @@ It reads the error output of the process and inserts it into the error pane. """ - if self.process is not None: + if self.__process is not None: self.errorGroup.show() - s = str(self.process.readAllStandardError(), + s = str(self.__process.readAllStandardError(), Preferences.getSystem("IOEncoding"), 'replace') self.errors.insertPlainText(s) @@ -753,7 +748,7 @@ self.errors.ensureCursorVisible() self.errorGroup.show() - self.process.write(strToQByteArray(inputTxt)) + self.__process.write(strToQByteArray(inputTxt)) self.passwordCheckBox.setChecked(False) self.input.clear()
--- a/eric6/Plugins/VcsPlugins/vcsSubversion/SvnRepoBrowserDialog.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/Plugins/VcsPlugins/vcsSubversion/SvnRepoBrowserDialog.py Sat Oct 10 12:20:51 2020 +0200 @@ -10,7 +10,6 @@ import os -from PyQt5.QtGui import QCursor from PyQt5.QtWidgets import ( QHeaderView, QLineEdit, QDialog, QApplication, QDialogButtonBox, QTreeWidgetItem @@ -18,6 +17,7 @@ from PyQt5.QtCore import QTimer, QProcess, QRegExp, Qt, pyqtSlot from E5Gui import E5MessageBox +from E5Gui.E5OverrideCursor import E5OverrideCursorProcess from .Ui_SvnRepoBrowserDialog import Ui_SvnRepoBrowserDialog @@ -49,10 +49,10 @@ self.vcs = vcs self.mode = mode - self.process = QProcess() - self.process.finished.connect(self.__procFinished) - self.process.readyReadStandardOutput.connect(self.__readStdout) - self.process.readyReadStandardError.connect(self.__readStderr) + self.__process = E5OverrideCursorProcess() + self.__process.finished.connect(self.__procFinished) + self.__process.readyReadStandardOutput.connect(self.__readStdout) + self.__process.readyReadStandardError.connect(self.__readStderr) if self.mode == "select": self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) @@ -82,12 +82,12 @@ @param e close event (QCloseEvent) """ if ( - self.process is not None and - self.process.state() != QProcess.NotRunning + self.__process is not None and + self.__process.state() != QProcess.NotRunning ): - self.process.terminate() - QTimer.singleShot(2000, self.process.kill) - self.process.waitForFinished(3000) + self.__process.terminate() + QTimer.singleShot(2000, self.__process.kill) + self.__process.waitForFinished(3000) e.accept() @@ -195,7 +195,6 @@ self.errors.insertPlainText(error) self.errors.ensureCursorVisible() else: - QApplication.restoreOverrideCursor() E5MessageBox.critical( self, self.tr('Process Generation Error'), @@ -215,9 +214,6 @@ """ self.errorGroup.hide() - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() - self.repoUrl = url if parent is None: @@ -250,7 +246,7 @@ self.intercept = False - self.process.kill() + self.__process.kill() args = [] args.append('list') @@ -259,8 +255,8 @@ args.append('--verbose') args.append(url) - self.process.start('svn', args) - procStarted = self.process.waitForStarted(5000) + self.__process.start('svn', args) + procStarted = self.__process.waitForStarted(5000) if not procStarted: self.__finish() self.inputGroup.setEnabled(False) @@ -370,19 +366,18 @@ button. """ if ( - self.process is not None and - self.process.state() != QProcess.NotRunning + self.__process is not None and + self.__process.state() != QProcess.NotRunning ): - self.process.terminate() - QTimer.singleShot(2000, self.process.kill) - self.process.waitForFinished(3000) + self.__process.terminate() + QTimer.singleShot(2000, self.__process.kill) + self.__process.waitForFinished(3000) self.inputGroup.setEnabled(False) self.inputGroup.hide() self.__resizeColumns() self.__resort() - QApplication.restoreOverrideCursor() def __procFinished(self, exitCode, exitStatus): """ @@ -400,11 +395,11 @@ It reads the output of the process, formats it and inserts it into the contents pane. """ - if self.process is not None: - self.process.setReadChannel(QProcess.StandardOutput) + if self.__process is not None: + self.__process.setReadChannel(QProcess.StandardOutput) - while self.process.canReadLine(): - s = str(self.process.readLine(), + while self.__process.canReadLine(): + s = str(self.__process.readLine(), Preferences.getSystem("IOEncoding"), 'replace') if self.__rx_dir.exactMatch(s): @@ -438,8 +433,8 @@ It reads the error output of the process and inserts it into the error pane. """ - if self.process is not None: - s = str(self.process.readAllStandardError(), + if self.__process is not None: + s = str(self.__process.readAllStandardError(), Preferences.getSystem("IOEncoding"), 'replace') self.errors.insertPlainText(s) @@ -472,7 +467,7 @@ self.errors.insertPlainText(inputTxt) self.errors.ensureCursorVisible() - self.process.write(strToQByteArray(inputTxt)) + self.__process.write(strToQByteArray(inputTxt)) self.passwordCheckBox.setChecked(False) self.input.clear()
--- a/eric6/Plugins/WizardPlugins/SetupWizard/SetupWizardDialog.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/Plugins/WizardPlugins/SetupWizard/SetupWizardDialog.py Sat Oct 10 12:20:51 2020 +0200 @@ -13,13 +13,14 @@ from PyQt5.QtCore import pyqtSlot, Qt, QUrl from PyQt5.QtWidgets import ( - QDialog, QDialogButtonBox, QTreeWidgetItem, QListWidgetItem, QApplication + QDialog, QDialogButtonBox, QTreeWidgetItem, QListWidgetItem ) from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply from E5Gui.E5Application import e5App from E5Gui import E5MessageBox, E5FileDialog from E5Gui.E5Completers import E5DirCompleter +from E5Gui.E5OverrideCursor import E5OverrideCursor from .Ui_SetupWizardDialog import Ui_SetupWizardDialog @@ -555,16 +556,15 @@ """ Private slot to discover packages automatically. """ - self.autodiscoverPackagesButton.setEnabled(False) - QApplication.setOverrideCursor(Qt.WaitCursor) - startDir = self.packageRootEdit.text() or self.__getStartDir() - if startDir: - self.packagesList.clear() - for dirpath, _dirnames, filenames in os.walk(startDir): - if "__init__.py" in filenames: - self.__addPackage(dirpath) - self.autodiscoverPackagesButton.setEnabled(True) - QApplication.restoreOverrideCursor() + with E5OverrideCursor(): + self.autodiscoverPackagesButton.setEnabled(False) + startDir = self.packageRootEdit.text() or self.__getStartDir() + if startDir: + self.packagesList.clear() + for dirpath, _dirnames, filenames in os.walk(startDir): + if "__init__.py" in filenames: + self.__addPackage(dirpath) + self.autodiscoverPackagesButton.setEnabled(True) @pyqtSlot() def on_packageRootDirButton_clicked(self):
--- a/eric6/Preferences/ConfigurationPages/EmailPage.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/Preferences/ConfigurationPages/EmailPage.py Sat Oct 10 12:20:51 2020 +0200 @@ -12,12 +12,11 @@ import socket import sys -from PyQt5.QtCore import pyqtSlot, Qt -from PyQt5.QtGui import QCursor -from PyQt5.QtWidgets import QApplication +from PyQt5.QtCore import pyqtSlot from E5Gui import E5MessageBox from E5Gui.E5Application import e5App +from E5Gui.E5OverrideCursor import E5OverrideCursor from E5Network.E5GoogleMailHelpers import getInstallCommand, RequiredPackages @@ -200,49 +199,26 @@ """ Private slot to test the mail server login data. """ - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() try: - if self.useSslButton.isChecked(): - server = smtplib.SMTP_SSL(self.mailServerEdit.text(), + with E5OverrideCursor(): + if self.useSslButton.isChecked(): + server = smtplib.SMTP_SSL(self.mailServerEdit.text(), + self.portSpin.value(), + timeout=10) + else: + server = smtplib.SMTP(self.mailServerEdit.text(), self.portSpin.value(), timeout=10) - else: - server = smtplib.SMTP(self.mailServerEdit.text(), - self.portSpin.value(), - timeout=10) - if self.useTlsButton.isChecked(): - server.starttls() - try: + if self.useTlsButton.isChecked(): + server.starttls() 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() + server.quit() + 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): @@ -257,7 +233,8 @@ E5MessageBox.critical( self, self.tr("Login Test"), - self.tr("""<p>The login test failed.<br>Reason: {0}</p>""") + self.tr( + """<p>The login test failed.<br>Reason: {0}</p>""") .format(errorStr)) @pyqtSlot()
--- a/eric6/Preferences/ProgramsDialog.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/Preferences/ProgramsDialog.py Sat Oct 10 12:20:51 2020 +0200 @@ -13,12 +13,12 @@ import sys from PyQt5.QtCore import pyqtSlot, Qt, QProcess -from PyQt5.QtGui import QCursor from PyQt5.QtWidgets import ( QApplication, QTreeWidgetItem, QHeaderView, QDialog, QDialogButtonBox ) from E5Gui.E5Application import e5App +from E5Gui.E5OverrideCursor import E5OverrideCursor from .Ui_ProgramsDialog import Ui_ProgramsDialog @@ -81,224 +81,224 @@ """ Private slot to search for all supported/required programs. """ - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() - self.programsList.clear() header = self.programsList.header() header.setSortIndicator(0, Qt.AscendingOrder) header.setSortIndicatorShown(False) - # 1. do the Qt5 programs - # 1a. Translation Converter - exe = ( - Utilities.isWindowsPlatform() and - "{0}.exe".format(Utilities.generateQtToolName("lrelease")) or - Utilities.generateQtToolName("lrelease") - ) - exe = os.path.join(Utilities.getQtBinariesPath(), exe) - version = self.__createProgramEntry( - self.tr("Translation Converter (Qt)"), exe, '-version', - 'lrelease', -1) - # 1b. Qt Designer - if Utilities.isWindowsPlatform(): - exe = os.path.join( - Utilities.getQtBinariesPath(), - "{0}.exe".format(Utilities.generateQtToolName("designer"))) - elif Utilities.isMacPlatform(): - exe = Utilities.getQtMacBundle("designer") - else: - exe = os.path.join( - Utilities.getQtBinariesPath(), - Utilities.generateQtToolName("designer")) - self.__createProgramEntry( - self.tr("Qt Designer"), exe, version=version) - # 1c. Qt Linguist - if Utilities.isWindowsPlatform(): - exe = os.path.join( - Utilities.getQtBinariesPath(), - "{0}.exe".format(Utilities.generateQtToolName("linguist"))) - elif Utilities.isMacPlatform(): - exe = Utilities.getQtMacBundle("linguist") - else: - exe = os.path.join( - Utilities.getQtBinariesPath(), - Utilities.generateQtToolName("linguist")) - self.__createProgramEntry( - self.tr("Qt Linguist"), exe, version=version) - # 1d. Qt Assistant - if Utilities.isWindowsPlatform(): - exe = os.path.join( - Utilities.getQtBinariesPath(), - "{0}.exe".format(Utilities.generateQtToolName("assistant"))) - elif Utilities.isMacPlatform(): - exe = Utilities.getQtMacBundle("assistant") - else: - exe = os.path.join( - Utilities.getQtBinariesPath(), - Utilities.generateQtToolName("assistant")) - self.__createProgramEntry( - self.tr("Qt Assistant"), exe, version=version) - - # 2. do the PyQt programs - # 2.1 do the PyQt5 programs - # 2.1a. Translation Extractor PyQt5 - self.__createProgramEntry( - self.tr("Translation Extractor (Python, PyQt5)"), - Utilities.generatePyQtToolPath("pylupdate5"), - '-version', 'pylupdate', -1) - # 2.1b. Forms Compiler PyQt5 - self.__createProgramEntry( - self.tr("Forms Compiler (Python, PyQt5)"), - Utilities.generatePyQtToolPath("pyuic5", ["py3uic5"]), - '--version', 'Python User', 4) - # 2.1c. Resource Compiler PyQt5 - self.__createProgramEntry( - self.tr("Resource Compiler (Python, PyQt5)"), - Utilities.generatePyQtToolPath("pyrcc5"), - '-version', '', -1, versionRe='Resource Compiler|pyrcc5') - - # 3. do the PySide programs - # 3.1 do the PySide2 programs - # 3.1a. Translation Extractor PySide2 - self.__createProgramEntry( - self.tr("Translation Extractor (Python, PySide2)"), - Utilities.generatePySideToolPath("pyside2-lupdate"), - '-version', '', -1, versionRe='lupdate') - # 3.1b. Forms Compiler PySide2 - self.__createProgramEntry( - self.tr("Forms Compiler (Python, PySide2)"), - Utilities.generatePySideToolPath("pyside2-uic"), - '--version', '', -1, versionRe='uic') - # 3.1c Resource Compiler PySide2 - self.__createProgramEntry( - self.tr("Resource Compiler (Python, PySide2)"), - Utilities.generatePySideToolPath("pyside2-rcc"), - '-version', '', -1, versionRe='rcc') - - # 4. do the Conda program(s) - exe = Preferences.getConda("CondaExecutable") - if not exe: - exe = "conda" + with E5OverrideCursor(): + # 1. do the Qt5 programs + # 1a. Translation Converter + exe = ( + Utilities.isWindowsPlatform() and + "{0}.exe".format(Utilities.generateQtToolName("lrelease")) or + Utilities.generateQtToolName("lrelease") + ) + exe = os.path.join(Utilities.getQtBinariesPath(), exe) + version = self.__createProgramEntry( + self.tr("Translation Converter (Qt)"), exe, '-version', + 'lrelease', -1) + # 1b. Qt Designer + if Utilities.isWindowsPlatform(): + exe = os.path.join( + Utilities.getQtBinariesPath(), + "{0}.exe".format(Utilities.generateQtToolName("designer"))) + elif Utilities.isMacPlatform(): + exe = Utilities.getQtMacBundle("designer") + else: + exe = os.path.join( + Utilities.getQtBinariesPath(), + Utilities.generateQtToolName("designer")) + self.__createProgramEntry( + self.tr("Qt Designer"), exe, version=version) + # 1c. Qt Linguist + if Utilities.isWindowsPlatform(): + exe = os.path.join( + Utilities.getQtBinariesPath(), + "{0}.exe".format(Utilities.generateQtToolName("linguist"))) + elif Utilities.isMacPlatform(): + exe = Utilities.getQtMacBundle("linguist") + else: + exe = os.path.join( + Utilities.getQtBinariesPath(), + Utilities.generateQtToolName("linguist")) + self.__createProgramEntry( + self.tr("Qt Linguist"), exe, version=version) + # 1d. Qt Assistant if Utilities.isWindowsPlatform(): - exe += ".exe" - self.__createProgramEntry( - self.tr("conda Manager"), exe, '--version', 'conda', -1) - - # 5. do the pip program(s) - virtualenvManager = e5App().getObject("VirtualEnvManager") - for venvName in virtualenvManager.getVirtualenvNames(): - interpreter = virtualenvManager.getVirtualenvInterpreter(venvName) + exe = os.path.join( + Utilities.getQtBinariesPath(), + "{0}.exe".format( + Utilities.generateQtToolName("assistant"))) + elif Utilities.isMacPlatform(): + exe = Utilities.getQtMacBundle("assistant") + else: + exe = os.path.join( + Utilities.getQtBinariesPath(), + Utilities.generateQtToolName("assistant")) + self.__createProgramEntry( + self.tr("Qt Assistant"), exe, version=version) + + # 2. do the PyQt programs + # 2.1 do the PyQt5 programs + # 2.1a. Translation Extractor PyQt5 + self.__createProgramEntry( + self.tr("Translation Extractor (Python, PyQt5)"), + Utilities.generatePyQtToolPath("pylupdate5"), + '-version', 'pylupdate', -1) + # 2.1b. Forms Compiler PyQt5 + self.__createProgramEntry( + self.tr("Forms Compiler (Python, PyQt5)"), + Utilities.generatePyQtToolPath("pyuic5", ["py3uic5"]), + '--version', 'Python User', 4) + # 2.1c. Resource Compiler PyQt5 + self.__createProgramEntry( + self.tr("Resource Compiler (Python, PyQt5)"), + Utilities.generatePyQtToolPath("pyrcc5"), + '-version', '', -1, versionRe='Resource Compiler|pyrcc5') + + # 3. do the PySide programs + # 3.1 do the PySide2 programs + # 3.1a. Translation Extractor PySide2 + self.__createProgramEntry( + self.tr("Translation Extractor (Python, PySide2)"), + Utilities.generatePySideToolPath("pyside2-lupdate"), + '-version', '', -1, versionRe='lupdate') + # 3.1b. Forms Compiler PySide2 + self.__createProgramEntry( + self.tr("Forms Compiler (Python, PySide2)"), + Utilities.generatePySideToolPath("pyside2-uic"), + '--version', '', -1, versionRe='uic') + # 3.1c Resource Compiler PySide2 + self.__createProgramEntry( + self.tr("Resource Compiler (Python, PySide2)"), + Utilities.generatePySideToolPath("pyside2-rcc"), + '-version', '', -1, versionRe='rcc') + + # 4. do the Conda program(s) + exe = Preferences.getConda("CondaExecutable") + if not exe: + exe = "conda" + if Utilities.isWindowsPlatform(): + exe += ".exe" self.__createProgramEntry( - self.tr("PyPI Package Management"), interpreter, '--version', - 'pip', 1, exeModule=["-m", "pip"]) - - # 6. do the CORBA and Protobuf programs - # 6a. omniORB - exe = Preferences.getCorba("omniidl") - if not exe: - exe = "omniidl" - if Utilities.isWindowsPlatform(): - exe += ".exe" - self.__createProgramEntry( - self.tr("CORBA IDL Compiler"), exe, '-V', 'omniidl', -1) - # 6b. protobuf - exe = Preferences.getProtobuf("protoc") - if not exe: - exe = "protoc" - if Utilities.isWindowsPlatform(): - exe += ".exe" - self.__createProgramEntry( - self.tr("Protobuf Compiler"), exe, '--version', 'libprotoc', -1) - # 6c. grpc - exe = Preferences.getProtobuf("grpcPython") - if not exe: - exe = sys.executable - self.__createProgramEntry( - self.tr("gRPC Compiler"), exe, '--version', 'libprotoc', -1, - exeModule=['-m', 'grpc_tools.protoc']) - - # 7. do the spell checking entry - try: - import enchant + self.tr("conda Manager"), exe, '--version', 'conda', -1) + + # 5. do the pip program(s) + virtualenvManager = e5App().getObject("VirtualEnvManager") + for venvName in virtualenvManager.getVirtualenvNames(): + interpreter = virtualenvManager.getVirtualenvInterpreter( + venvName) + self.__createProgramEntry( + self.tr("PyPI Package Management"), interpreter, + '--version', 'pip', 1, exeModule=["-m", "pip"]) + + # 6. do the CORBA and Protobuf programs + # 6a. omniORB + exe = Preferences.getCorba("omniidl") + if not exe: + exe = "omniidl" + if Utilities.isWindowsPlatform(): + exe += ".exe" + self.__createProgramEntry( + self.tr("CORBA IDL Compiler"), exe, '-V', 'omniidl', -1) + # 6b. protobuf + exe = Preferences.getProtobuf("protoc") + if not exe: + exe = "protoc" + if Utilities.isWindowsPlatform(): + exe += ".exe" + self.__createProgramEntry( + self.tr("Protobuf Compiler"), exe, '--version', 'libprotoc', + -1) + # 6c. grpc + exe = Preferences.getProtobuf("grpcPython") + if not exe: + exe = sys.executable + self.__createProgramEntry( + self.tr("gRPC Compiler"), exe, '--version', 'libprotoc', -1, + exeModule=['-m', 'grpc_tools.protoc']) + + # 7. do the spell checking entry try: - text = os.path.dirname(enchant.__file__) - except AttributeError: + import enchant + try: + text = os.path.dirname(enchant.__file__) + except AttributeError: + text = "enchant" + try: + version = enchant.__version__ + except AttributeError: + version = self.tr("(unknown)") + except (ImportError, AttributeError, OSError): text = "enchant" - try: - version = enchant.__version__ - except AttributeError: - version = self.tr("(unknown)") - except (ImportError, AttributeError, OSError): - text = "enchant" - version = "" - self.__createEntry( - self.tr("Spell Checker - PyEnchant"), text, version) - - # 8. do the pygments entry - try: - import pygments - try: - text = os.path.dirname(pygments.__file__) - except AttributeError: - text = "pygments" + version = "" + self.__createEntry( + self.tr("Spell Checker - PyEnchant"), text, version) + + # 8. do the pygments entry try: - version = pygments.__version__ - except AttributeError: - version = self.tr("(unknown)") - except (ImportError, AttributeError, OSError): - text = "pygments" - version = "" - self.__createEntry( - self.tr("Source Highlighter - Pygments"), text, version) - - # 9. do the MicroPython related entries - exe = Preferences.getMicroPython("MpyCrossCompiler") - if not exe: - exe = "mpy-cross" - self.__createProgramEntry( - self.tr("MicroPython - MPY Cross Compiler"), exe, '--version', - 'MicroPython', 1) - self.__createProgramEntry( - self.tr("MicroPython - ESP Tool"), sys.executable, 'version', - 'esptool', -1, exeModule=['-m', 'esptool']) - exe = Preferences.getMicroPython("DfuUtilPath") - if not exe: - exe = "dfu-util" - self.__createProgramEntry( - self.tr("MicroPython - PyBoard Flasher"), exe, '--version', - 'dfu-util', -1) - - # 10. do the plugin related programs - pm = e5App().getObject("PluginManager") - for info in pm.getPluginExeDisplayData(): - if info["programEntry"]: - if "exeModule" not in info: - info["exeModule"] = None - if "versionRe" not in info: - info["versionRe"] = None - self.__createProgramEntry( - info["header"], - info["exe"], - versionCommand=info["versionCommand"], - versionStartsWith=info["versionStartsWith"], - versionPosition=info["versionPosition"], - version=info["version"], - versionCleanup=info["versionCleanup"], - versionRe=info["versionRe"], - exeModule=info["exeModule"], - ) - else: - self.__createEntry( - info["header"], - info["text"], - info["version"] - ) - - self.programsList.sortByColumn(0, Qt.AscendingOrder) - self.on_showComboBox_currentIndexChanged( - self.showComboBox.currentIndex()) - QApplication.restoreOverrideCursor() + import pygments + try: + text = os.path.dirname(pygments.__file__) + except AttributeError: + text = "pygments" + try: + version = pygments.__version__ + except AttributeError: + version = self.tr("(unknown)") + except (ImportError, AttributeError, OSError): + text = "pygments" + version = "" + self.__createEntry( + self.tr("Source Highlighter - Pygments"), text, version) + + # 9. do the MicroPython related entries + exe = Preferences.getMicroPython("MpyCrossCompiler") + if not exe: + exe = "mpy-cross" + self.__createProgramEntry( + self.tr("MicroPython - MPY Cross Compiler"), exe, '--version', + 'MicroPython', 1) + self.__createProgramEntry( + self.tr("MicroPython - ESP Tool"), sys.executable, 'version', + 'esptool', -1, exeModule=['-m', 'esptool']) + exe = Preferences.getMicroPython("DfuUtilPath") + if not exe: + exe = "dfu-util" + self.__createProgramEntry( + self.tr("MicroPython - PyBoard Flasher"), exe, '--version', + 'dfu-util', -1) + + # 10. do the plugin related programs + pm = e5App().getObject("PluginManager") + for info in pm.getPluginExeDisplayData(): + if info["programEntry"]: + if "exeModule" not in info: + info["exeModule"] = None + if "versionRe" not in info: + info["versionRe"] = None + self.__createProgramEntry( + info["header"], + info["exe"], + versionCommand=info["versionCommand"], + versionStartsWith=info["versionStartsWith"], + versionPosition=info["versionPosition"], + version=info["version"], + versionCleanup=info["versionCleanup"], + versionRe=info["versionRe"], + exeModule=info["exeModule"], + ) + else: + self.__createEntry( + info["header"], + info["text"], + info["version"] + ) + + self.programsList.sortByColumn(0, Qt.AscendingOrder) + self.on_showComboBox_currentIndexChanged( + self.showComboBox.currentIndex()) self.__hasSearched = True
--- a/eric6/Project/Project.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/Project/Project.py Sat Oct 10 12:20:51 2020 +0200 @@ -18,9 +18,9 @@ from PyQt5.QtCore import ( pyqtSlot, QFile, QFileInfo, pyqtSignal, QCryptographicHash, QIODevice, - QByteArray, QObject, Qt, QProcess + QByteArray, QObject, QProcess ) -from PyQt5.QtGui import QCursor, QKeySequence +from PyQt5.QtGui import QKeySequence from PyQt5.QtWidgets import ( QLineEdit, QToolBar, QDialog, QInputDialog, QApplication, QMenu, QAction ) @@ -30,6 +30,7 @@ from E5Gui import E5FileDialog, E5MessageBox from E5Gui.E5ListSelectionDialog import E5ListSelectionDialog from E5Gui.E5ProgressDialog import E5ProgressDialog +from E5Gui.E5OverrideCursor import E5OverrideCursor, E5OverridenCursor from Globals import recentNameProject @@ -778,7 +779,6 @@ res = not reader.hasError() f.close() else: - QApplication.restoreOverrideCursor() E5MessageBox.critical( self.ui, self.tr("Read project file"), @@ -2617,91 +2617,90 @@ # Show the file type associations for the user to change self.__showFiletypeAssociations() - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() - - # search the project directory for files with known extensions - filespecs = list(self.pdata["FILETYPES"].keys()) - for filespec in filespecs: - files = Utilities.direntries(self.ppath, True, filespec) - for file in files: - self.appendFile(file) - - # special handling for translation files - if self.translationsRoot: - tpd = os.path.join(self.ppath, self.translationsRoot) - if not self.translationsRoot.endswith(os.sep): - tpd = os.path.dirname(tpd) - else: - tpd = self.ppath - tslist = [] - if self.pdata["TRANSLATIONPATTERN"]: - pattern = os.path.basename(self.pdata["TRANSLATIONPATTERN"]) - if "%language%" in pattern: - pattern = pattern.replace("%language%", "*") + with E5OverrideCursor(): + # search the project directory for files with known extensions + filespecs = list(self.pdata["FILETYPES"].keys()) + for filespec in filespecs: + files = Utilities.direntries(self.ppath, True, filespec) + for file in files: + self.appendFile(file) + + # special handling for translation files + if self.translationsRoot: + tpd = os.path.join(self.ppath, self.translationsRoot) + if not self.translationsRoot.endswith(os.sep): + tpd = os.path.dirname(tpd) else: - tpd = self.pdata["TRANSLATIONPATTERN"].split( - "%language%")[0] - else: - pattern = "*.ts" - tslist.extend(Utilities.direntries(tpd, True, pattern)) - pattern = self.__binaryTranslationFile(pattern) - if pattern: + tpd = self.ppath + tslist = [] + if self.pdata["TRANSLATIONPATTERN"]: + pattern = os.path.basename(self.pdata["TRANSLATIONPATTERN"]) + if "%language%" in pattern: + pattern = pattern.replace("%language%", "*") + else: + tpd = self.pdata["TRANSLATIONPATTERN"].split( + "%language%")[0] + else: + pattern = "*.ts" tslist.extend(Utilities.direntries(tpd, True, pattern)) - if tslist: - if '_' in os.path.basename(tslist[0]): - # the first entry determines the mainscript name - mainscriptname = ( - os.path.splitext(mainscript)[0] or - os.path.basename(tslist[0]).split('_')[0] - ) - self.pdata["TRANSLATIONPATTERN"] = os.path.join( - os.path.dirname(tslist[0]), - "{0}_%language%{1}".format( - os.path.basename(tslist[0]).split('_')[0], - os.path.splitext(tslist[0])[1])) - else: - mainscriptname = "" - pattern, ok = QInputDialog.getText( - None, - self.tr("Translation Pattern"), - self.tr( - "Enter the path pattern for translation files " - "(use '%language%' in place of the language code):"), - # __IGNORE_WARNING_M601__ - QLineEdit.Normal, - tslist[0]) - if pattern: - self.pdata["TRANSLATIONPATTERN"] = pattern - if self.pdata["TRANSLATIONPATTERN"]: - self.pdata["TRANSLATIONPATTERN"] = self.getRelativePath( - self.pdata["TRANSLATIONPATTERN"]) - pattern = self.pdata["TRANSLATIONPATTERN"].replace( - "%language%", "*") - for ts in tslist: - if fnmatch.fnmatch(ts, pattern): - self.pdata["TRANSLATIONS"].append(ts) - self.projectLanguageAdded.emit(ts) - if self.pdata["TRANSLATIONSBINPATH"]: - tpd = os.path.join(self.ppath, - self.pdata["TRANSLATIONSBINPATH"]) - pattern = os.path.basename( - self.pdata["TRANSLATIONPATTERN"]).replace( + pattern = self.__binaryTranslationFile(pattern) + if pattern: + tslist.extend(Utilities.direntries(tpd, True, pattern)) + if tslist: + if '_' in os.path.basename(tslist[0]): + # the first entry determines the mainscript name + mainscriptname = ( + os.path.splitext(mainscript)[0] or + os.path.basename(tslist[0]).split('_')[0] + ) + self.pdata["TRANSLATIONPATTERN"] = os.path.join( + os.path.dirname(tslist[0]), + "{0}_%language%{1}".format( + os.path.basename(tslist[0]).split('_')[0], + os.path.splitext(tslist[0])[1])) + else: + mainscriptname = "" + pattern, ok = QInputDialog.getText( + None, + self.tr("Translation Pattern"), + self.tr( + "Enter the path pattern for translation files " + "(use '%language%' in place of the language" + " code):"), + QLineEdit.Normal, + tslist[0]) + if pattern: + self.pdata["TRANSLATIONPATTERN"] = pattern + if self.pdata["TRANSLATIONPATTERN"]: + self.pdata["TRANSLATIONPATTERN"] = self.getRelativePath( + self.pdata["TRANSLATIONPATTERN"]) + pattern = self.pdata["TRANSLATIONPATTERN"].replace( "%language%", "*") - pattern = self.__binaryTranslationFile(pattern) - qmlist = Utilities.direntries(tpd, True, pattern) - for qm in qmlist: - self.pdata["TRANSLATIONS"].append(qm) - self.projectLanguageAdded.emit(qm) - if not self.pdata["MAINSCRIPT"] and bool(mainscriptname): - if self.pdata["PROGLANGUAGE"] in [ - "Python3", "MicroPython" - ]: - self.pdata["MAINSCRIPT"] = '{0}.py'.format(mainscriptname) - elif self.pdata["PROGLANGUAGE"] == "Ruby": - self.pdata["MAINSCRIPT"] = '{0}.rb'.format(mainscriptname) - self.setDirty(True) - QApplication.restoreOverrideCursor() + for ts in tslist: + if fnmatch.fnmatch(ts, pattern): + self.pdata["TRANSLATIONS"].append(ts) + self.projectLanguageAdded.emit(ts) + if self.pdata["TRANSLATIONSBINPATH"]: + tpd = os.path.join(self.ppath, + self.pdata["TRANSLATIONSBINPATH"]) + pattern = os.path.basename( + self.pdata["TRANSLATIONPATTERN"]).replace( + "%language%", "*") + pattern = self.__binaryTranslationFile(pattern) + qmlist = Utilities.direntries(tpd, True, pattern) + for qm in qmlist: + self.pdata["TRANSLATIONS"].append(qm) + self.projectLanguageAdded.emit(qm) + if not self.pdata["MAINSCRIPT"] and bool(mainscriptname): + if self.pdata["PROGLANGUAGE"] in [ + "Python3", "MicroPython" + ]: + self.pdata["MAINSCRIPT"] = '{0}.py'.format( + mainscriptname) + elif self.pdata["PROGLANGUAGE"] == "Ruby": + self.pdata["MAINSCRIPT"] = '{0}.rb'.format( + mainscriptname) + self.setDirty(True) def __showProperties(self): """ @@ -2895,18 +2894,15 @@ if fn: if self.closeProject(): - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() - if self.__readProject(fn): + with E5OverrideCursor(): + ok = self.__readProject(fn) + if ok: self.opened = True if not self.pdata["FILETYPES"]: self.initFileTypes() else: self.updateFileTypes() - QApplication.restoreOverrideCursor() - QApplication.processEvents() - try: # create management directory if not present self.createProjectManagementDir() @@ -2923,94 +2919,88 @@ # read a user specific project file self.__readUserProperties() - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() - - oldState = self.isDirty() - self.vcs = self.initVCS() - if self.vcs is None and self.isDirty() == oldState: - # check, if project is version controlled - pluginManager = e5App().getObject("PluginManager") - for indicator, vcsData in ( - pluginManager.getVcsSystemIndicators().items() - ): - if os.path.exists( - os.path.join(self.ppath, indicator)): - if len(vcsData) > 1: - vcsList = [] - for _vcsSystemStr, vcsSystemDisplay in ( - vcsData - ): - vcsList.append(vcsSystemDisplay) - QApplication.restoreOverrideCursor() - res, vcs_ok = QInputDialog.getItem( - None, - self.tr("New Project"), - self.tr( - "Select Version Control System"), - vcsList, - 0, False) - QApplication.setOverrideCursor( - QCursor(Qt.WaitCursor)) - QApplication.processEvents() - if vcs_ok: - for vcsSystemStr, vcsSystemDisplay in ( - vcsData - ): - if res == vcsSystemDisplay: - vcsSystem = vcsSystemStr - break + with E5OverrideCursor(): + oldState = self.isDirty() + self.vcs = self.initVCS() + if self.vcs is None and self.isDirty() == oldState: + # check, if project is version controlled + pluginManager = e5App().getObject("PluginManager") + for indicator, vcsData in ( + pluginManager.getVcsSystemIndicators().items() + ): + if os.path.exists( + os.path.join(self.ppath, indicator)): + if len(vcsData) > 1: + vcsList = [] + for ( + _vcsSystemStr, vcsSystemDisplay + ) in vcsData: + vcsList.append(vcsSystemDisplay) + with E5OverridenCursor(): + res, vcs_ok = QInputDialog.getItem( + None, + self.tr("New Project"), + self.tr( + "Select Version Control" + " System"), + vcsList, + 0, False) + if vcs_ok: + for ( + vcsSystemStr, vcsSystemDisplay + ) in vcsData: + if res == vcsSystemDisplay: + vcsSystem = vcsSystemStr + break + else: + vcsSystem = "None" else: vcsSystem = "None" else: - vcsSystem = "None" - else: - vcsSystem = vcsData[0][0] - self.pdata["VCS"] = vcsSystem - self.vcs = self.initVCS() - self.setDirty(True) - if ( - self.vcs is not None and - (self.vcs.vcsRegisteredState(self.ppath) != - self.vcs.canBeCommitted) - ): - self.pdata["VCS"] = 'None' - self.vcs = self.initVCS() - self.closeAct.setEnabled(True) - self.saveasAct.setEnabled(True) - self.actGrp2.setEnabled(True) - self.propsAct.setEnabled(True) - self.userPropsAct.setEnabled(True) - self.filetypesAct.setEnabled(True) - self.lexersAct.setEnabled(True) - self.sessActGrp.setEnabled(True) - self.dbgActGrp.setEnabled(True) - self.menuDebuggerAct.setEnabled(True) - self.menuSessionAct.setEnabled(True) - self.menuCheckAct.setEnabled(True) - self.menuShowAct.setEnabled(True) - self.menuDiagramAct.setEnabled(True) - self.menuApidocAct.setEnabled(True) - self.menuPackagersAct.setEnabled(True) - self.pluginGrp.setEnabled( - self.pdata["PROJECTTYPE"] in ["E6Plugin"]) - self.addLanguageAct.setEnabled( - bool(self.pdata["TRANSLATIONPATTERN"])) - self.makeGrp.setEnabled( - self.pdata["MAKEPARAMS"]["MakeEnabled"]) - self.menuMakeAct.setEnabled( - self.pdata["MAKEPARAMS"]["MakeEnabled"]) - - # open a project debugger properties file being quiet - # about errors - if Preferences.getProject("AutoLoadDbgProperties"): - self.__readDebugProperties(True) - - self.__model.projectOpened() - self.projectOpenedHooks.emit() - self.projectOpened.emit() - - QApplication.restoreOverrideCursor() + vcsSystem = vcsData[0][0] + self.pdata["VCS"] = vcsSystem + self.vcs = self.initVCS() + self.setDirty(True) + if ( + self.vcs is not None and + (self.vcs.vcsRegisteredState(self.ppath) != + self.vcs.canBeCommitted) + ): + self.pdata["VCS"] = 'None' + self.vcs = self.initVCS() + self.closeAct.setEnabled(True) + self.saveasAct.setEnabled(True) + self.actGrp2.setEnabled(True) + self.propsAct.setEnabled(True) + self.userPropsAct.setEnabled(True) + self.filetypesAct.setEnabled(True) + self.lexersAct.setEnabled(True) + self.sessActGrp.setEnabled(True) + self.dbgActGrp.setEnabled(True) + self.menuDebuggerAct.setEnabled(True) + self.menuSessionAct.setEnabled(True) + self.menuCheckAct.setEnabled(True) + self.menuShowAct.setEnabled(True) + self.menuDiagramAct.setEnabled(True) + self.menuApidocAct.setEnabled(True) + self.menuPackagersAct.setEnabled(True) + self.pluginGrp.setEnabled( + self.pdata["PROJECTTYPE"] in ["E6Plugin"]) + self.addLanguageAct.setEnabled( + bool(self.pdata["TRANSLATIONPATTERN"])) + self.makeGrp.setEnabled( + self.pdata["MAKEPARAMS"]["MakeEnabled"]) + self.menuMakeAct.setEnabled( + self.pdata["MAKEPARAMS"]["MakeEnabled"]) + + # open a project debugger properties file being quiet + # about errors + if Preferences.getProject("AutoLoadDbgProperties"): + self.__readDebugProperties(True) + + self.__model.projectOpened() + self.projectOpenedHooks.emit() + self.projectOpened.emit() if Preferences.getProject("SearchNewFiles"): self.__doSearchNewFiles() @@ -3050,8 +3040,6 @@ self.vcsStatusMonitorInfo) self.vcs.vcsStatusChanged.connect( self.__vcsStatusChanged) - else: - QApplication.restoreOverrideCursor() def reopenProject(self): """ @@ -4774,10 +4762,11 @@ if not self.isOpen(): return - name = self.getRelativePath(fullname) - self.prepareRepopulateItem.emit(name) - self.__model.repopulateItem(name) - self.completeRepopulateItem.emit(name) + with E5OverrideCursor(): + name = self.getRelativePath(fullname) + self.prepareRepopulateItem.emit(name) + self.__model.repopulateItem(name) + self.completeRepopulateItem.emit(name) ############################################################## ## Below is the VCS interface @@ -4825,25 +4814,26 @@ if not vcsExists: if override: # override failed, revert to original - QApplication.restoreOverrideCursor() + with E5OverridenCursor(): + E5MessageBox.critical( + self.ui, + self.tr("Version Control System"), + self.tr( + "<p>The selected VCS <b>{0}</b> could not be" + " found. <br/>Reverting override.</p><p>{1}" + "</p>") + .format(vcsSystem, msg)) + self.pudata["VCSOVERRIDE"] = "" + return self.initVCS(nooverride=True) + + with E5OverridenCursor(): E5MessageBox.critical( self.ui, self.tr("Version Control System"), self.tr( "<p>The selected VCS <b>{0}</b> could not be" - " found. <br/>Reverting override.</p><p>{1}</p>") - .format(vcsSystem, msg)) - self.pudata["VCSOVERRIDE"] = "" - return self.initVCS(nooverride=True) - - QApplication.restoreOverrideCursor() - E5MessageBox.critical( - self.ui, - self.tr("Version Control System"), - self.tr( - "<p>The selected VCS <b>{0}</b> could not be" - " found.<br/>Disabling version control.</p>" - "<p>{1}</p>").format(vcsSystem, msg)) + " found.<br/>Disabling version control.</p>" + "<p>{1}</p>").format(vcsSystem, msg)) vcs = None if forProject: self.pdata["VCS"] = 'None' @@ -5843,3 +5833,6 @@ "CompressionDisable": False, "PathPrefix": "", } + +# +# eflag: noqa = M601
--- a/eric6/Project/ProjectBaseBrowser.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/Project/ProjectBaseBrowser.py Sat Oct 10 12:20:51 2020 +0200 @@ -14,13 +14,13 @@ QModelIndex, pyqtSignal, Qt, QCoreApplication, QItemSelectionModel, QItemSelection, QElapsedTimer ) -from PyQt5.QtGui import QCursor from PyQt5.QtWidgets import ( QTreeView, QApplication, QMenu, QDialog, QAbstractItemView ) from E5Gui.E5Application import e5App from E5Gui import E5MessageBox +from E5Gui.E5OverrideCursor import E5OverrideCursor from UI.Browser import Browser from UI.BrowserModel import BrowserDirectoryItem, BrowserFileItem @@ -366,54 +366,50 @@ Protected slot to handle the 'Expand all directories' menu action. """ self._disconnectExpandedCollapsed() - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() - index = self.model().index(0, 0) - while index.isValid(): - itm = self.model().item(index) - if ( - isinstance( - itm, - (ProjectBrowserSimpleDirectoryItem, - ProjectBrowserDirectoryItem)) and - not self.isExpanded(index) - ): - self.expand(index) - index = self.indexBelow(index) - self.layoutDisplay() + with E5OverrideCursor(): + index = self.model().index(0, 0) + while index.isValid(): + itm = self.model().item(index) + if ( + isinstance( + itm, + (ProjectBrowserSimpleDirectoryItem, + ProjectBrowserDirectoryItem)) and + not self.isExpanded(index) + ): + self.expand(index) + index = self.indexBelow(index) + self.layoutDisplay() self._connectExpandedCollapsed() - QApplication.restoreOverrideCursor() def _collapseAllDirs(self): """ Protected slot to handle the 'Collapse all directories' menu action. """ self._disconnectExpandedCollapsed() - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() - # step 1: find last valid index - vindex = QModelIndex() - index = self.model().index(0, 0) - while index.isValid(): - vindex = index - index = self.indexBelow(index) - - # step 2: go up collapsing all directory items - index = vindex - while index.isValid(): - itm = self.model().item(index) - if ( - isinstance( - itm, - (ProjectBrowserSimpleDirectoryItem, - ProjectBrowserDirectoryItem)) and - self.isExpanded(index) - ): - self.collapse(index) - index = self.indexAbove(index) - self.layoutDisplay() + with E5OverrideCursor(): + # step 1: find last valid index + vindex = QModelIndex() + index = self.model().index(0, 0) + while index.isValid(): + vindex = index + index = self.indexBelow(index) + + # step 2: go up collapsing all directory items + index = vindex + while index.isValid(): + itm = self.model().item(index) + if ( + isinstance( + itm, + (ProjectBrowserSimpleDirectoryItem, + ProjectBrowserDirectoryItem)) and + self.isExpanded(index) + ): + self.collapse(index) + index = self.indexAbove(index) + self.layoutDisplay() self._connectExpandedCollapsed() - QApplication.restoreOverrideCursor() def _showContextMenu(self, menu): """ @@ -506,41 +502,37 @@ # 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) - ): + with E5OverrideCursor(): + # 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 ( - startIndex is not None and - startIndex.parent() != index.parent() + self.wantedItem(itm, filterList) and + compareString == itm.data(1) ): - 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 ( + 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) if selectedEntries == 0: E5MessageBox.information( @@ -628,8 +620,6 @@ @param name relative name of file item to be repopulated (string) """ - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() itm = self.currentItem() if itm is not None: self.currentItemName = itm.data(0) @@ -684,8 +674,6 @@ self._selectSingleItem(index) self.expandedNames = [] self.currentItemName = None - QApplication.restoreOverrideCursor() - QApplication.processEvents() self._resort() def currentItem(self):
--- a/eric6/QScintilla/Editor.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/QScintilla/Editor.py Sat Oct 10 12:20:51 2020 +0200 @@ -16,7 +16,7 @@ QDir, QTimer, QModelIndex, QFileInfo, pyqtSignal, pyqtSlot, QCryptographicHash, QEvent, QDateTime, QRegExp, Qt, QPoint ) -from PyQt5.QtGui import QCursor, QPalette, QFont, QPixmap, QPainter +from PyQt5.QtGui import QPalette, QFont, QPixmap, QPainter from PyQt5.QtWidgets import ( QLineEdit, QActionGroup, QDialog, QInputDialog, QApplication, QMenu ) @@ -25,6 +25,8 @@ from E5Gui.E5Application import e5App from E5Gui import E5FileDialog, E5MessageBox +from E5Gui.E5OverrideCursor import E5OverrideCursor + from E5Utilities.E5Cache import E5Cache from .QsciScintillaCompat import QsciScintillaCompat @@ -3077,56 +3079,52 @@ @keyparam encoding encoding to be used to read the file (string) (Note: this parameter overrides encoding detection) """ - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - self.__loadEditorConfig(fileName=fn) try: - if createIt and not os.path.exists(fn): - f = open(fn, "w") - f.close() - if encoding == "": - encoding = self.__getEditorConfig("DefaultEncoding", - nodefault=True) - if encoding: - txt, self.encoding = Utilities.readEncodedFileWithEncoding( - fn, encoding) - else: - txt, self.encoding = Utilities.readEncodedFile(fn) + with E5OverrideCursor(): + if createIt and not os.path.exists(fn): + f = open(fn, "w") + f.close() + if encoding == "": + encoding = self.__getEditorConfig("DefaultEncoding", + nodefault=True) + if encoding: + txt, self.encoding = Utilities.readEncodedFileWithEncoding( + fn, encoding) + else: + txt, self.encoding = Utilities.readEncodedFile(fn) except (UnicodeDecodeError, IOError) as why: - QApplication.restoreOverrideCursor() E5MessageBox.critical( self.vm, self.tr('Open File'), self.tr('<p>The file <b>{0}</b> could not be opened.</p>' '<p>Reason: {1}</p>') .format(fn, str(why))) - QApplication.restoreOverrideCursor() raise - modified = False - - self.setText(txt) - - # get eric specific flags - self.__processFlags() - - # perform automatic EOL conversion - if ( - self.__getEditorConfig("EOLMode", nodefault=True) or - Preferences.getEditor("AutomaticEOLConversion") - ): - self.convertEols(self.eolMode()) - else: - fileEol = self.detectEolString(txt) - self.setEolModeByEolString(fileEol) - - self.extractTasks() - - QApplication.restoreOverrideCursor() - - self.setModified(modified) - self.lastModified = QFileInfo(self.fileName).lastModified() + with E5OverrideCursor(): + modified = False + + self.setText(txt) + + # get eric specific flags + self.__processFlags() + + # perform automatic EOL conversion + if ( + self.__getEditorConfig("EOLMode", nodefault=True) or + Preferences.getEditor("AutomaticEOLConversion") + ): + self.convertEols(self.eolMode()) + else: + fileEol = self.detectEolString(txt) + self.setEolModeByEolString(fileEol) + + self.extractTasks() + + self.setModified(modified) + self.lastModified = QFileInfo(self.fileName).lastModified() def __convertTabs(self): """
--- a/eric6/QScintilla/Exporters/ExporterHTML.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/QScintilla/Exporters/ExporterHTML.py Sat Oct 10 12:20:51 2020 +0200 @@ -15,12 +15,12 @@ import sys import io -from PyQt5.QtCore import Qt -from PyQt5.QtGui import QCursor, QFontInfo -from PyQt5.QtWidgets import QApplication, QInputDialog +from PyQt5.QtGui import QFontInfo +from PyQt5.QtWidgets import QInputDialog from PyQt5.Qsci import QsciScintilla from E5Gui import E5MessageBox +from E5Gui.E5OverrideCursor import E5OverrideCursor from .ExporterBase import ExporterBase @@ -392,60 +392,56 @@ if not filename: return - try: - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() - - fn = self.editor.getFileName() - if fn: - extension = os.path.normcase(os.path.splitext(fn)[1][1:]) + fn = self.editor.getFileName() + if fn: + extension = os.path.normcase(os.path.splitext(fn)[1][1:]) + else: + extension = "" + + if ( + extension in Preferences.getEditor( + "PreviewMarkdownFileNameExtensions") or + self.editor.getLanguage().lower() == "markdown" + ): + # export markdown to HTML + colorSchemes = [ + self.tr("Light Background Color"), + self.tr("Dark Background Color"), + ] + colorScheme, ok = QInputDialog.getItem( + None, + self.tr("Markdown Export"), + self.tr("Select color scheme:"), + colorSchemes, + 0, False) + if ok: + colorSchemeIndex = colorSchemes.index(colorScheme) else: - extension = "" + # light background as default + colorSchemeIndex = 0 + with E5OverrideCursor(): + html = self.__generateFromMarkdown(colorSchemeIndex == 1) + elif ( + extension in Preferences.getEditor( + "PreviewRestFileNameExtensions") or + self.editor.getLanguage().lower() == "restructuredtext" + ): + # export ReST to HTML + with E5OverrideCursor(): + html = self.__generateFromReSTDocutils() + else: + tabSize = self.editor.getEditorConfig("TabWidth") + if tabSize == 0: + tabSize = 4 + wysiwyg = Preferences.getEditorExporter("HTML/WYSIWYG") + folding = Preferences.getEditorExporter("HTML/Folding") + onlyStylesUsed = Preferences.getEditorExporter( + "HTML/OnlyStylesUsed") + titleFullPath = Preferences.getEditorExporter( + "HTML/FullPathAsTitle") + tabs = Preferences.getEditorExporter("HTML/UseTabs") - if ( - extension in Preferences.getEditor( - "PreviewMarkdownFileNameExtensions") or - self.editor.getLanguage().lower() == "markdown" - ): - # export markdown to HTML - colorSchemes = [ - self.tr("Light Background Color"), - self.tr("Dark Background Color"), - ] - QApplication.restoreOverrideCursor() - colorScheme, ok = QInputDialog.getItem( - None, - self.tr("Markdown Export"), - self.tr("Select color scheme:"), - colorSchemes, - 0, False) - if ok: - colorSchemeIndex = colorSchemes.index(colorScheme) - else: - # light background as default - colorSchemeIndex = 0 - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() - html = self.__generateFromMarkdown(colorSchemeIndex == 1) - elif ( - extension in Preferences.getEditor( - "PreviewRestFileNameExtensions") or - self.editor.getLanguage().lower() == "restructuredtext" - ): - # export ReST to HTML - html = self.__generateFromReSTDocutils() - else: - tabSize = self.editor.getEditorConfig("TabWidth") - if tabSize == 0: - tabSize = 4 - wysiwyg = Preferences.getEditorExporter("HTML/WYSIWYG") - folding = Preferences.getEditorExporter("HTML/Folding") - onlyStylesUsed = Preferences.getEditorExporter( - "HTML/OnlyStylesUsed") - titleFullPath = Preferences.getEditorExporter( - "HTML/FullPathAsTitle") - tabs = Preferences.getEditorExporter("HTML/UseTabs") - + with E5OverrideCursor(): generator = HTMLGenerator(self.editor) html = generator.generate( tabSize=tabSize, @@ -455,33 +451,30 @@ onlyStylesUsed=onlyStylesUsed, titleFullPath=titleFullPath ) - - if html: - try: + + if html: + try: + with E5OverrideCursor(): f = open(filename, "w", encoding="utf-8") f.write(html) f.close() - except IOError as err: - QApplication.restoreOverrideCursor() - E5MessageBox.critical( - self.editor, - self.tr("Export source"), - self.tr( - """<p>The source could not be exported to""" - """ <b>{0}</b>.</p><p>Reason: {1}</p>""") - .format(filename, str(err))) - else: - QApplication.restoreOverrideCursor() + except IOError as err: E5MessageBox.critical( self.editor, self.tr("Export source"), self.tr( """<p>The source could not be exported to""" - """ <b>{0}</b>.</p><p>Reason: No HTML code""" - """ generated.</p>""") - .format(filename)) - finally: - QApplication.restoreOverrideCursor() + """ <b>{0}</b>.</p><p>Reason: {1}</p>""") + .format(filename, str(err))) + else: + E5MessageBox.critical( + self.editor, + self.tr("Export source"), + self.tr( + """<p>The source could not be exported to""" + """ <b>{0}</b>.</p><p>Reason: No HTML code""" + """ generated.</p>""") + .format(filename)) def __generateFromReSTDocutils(self): """
--- a/eric6/QScintilla/Exporters/ExporterODT.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/QScintilla/Exporters/ExporterODT.py Sat Oct 10 12:20:51 2020 +0200 @@ -8,11 +8,10 @@ """ -from PyQt5.QtCore import Qt -from PyQt5.QtGui import QCursor, QTextDocument, QTextDocumentWriter -from PyQt5.QtWidgets import QApplication +from PyQt5.QtGui import QTextDocument, QTextDocumentWriter from E5Gui import E5MessageBox +from E5Gui.E5OverrideCursor import E5OverrideCursor from .ExporterBase import ExporterBase from .ExporterHTML import HTMLGenerator @@ -41,9 +40,6 @@ if not filename: return - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() - tabSize = self.editor.getEditorConfig("TabWidth") if tabSize == 0: tabSize = 4 @@ -51,23 +47,24 @@ 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 - ) + with E5OverrideCursor(): + # 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) - # 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,
--- a/eric6/QScintilla/Exporters/ExporterPDF.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/QScintilla/Exporters/ExporterPDF.py Sat Oct 10 12:20:51 2020 +0200 @@ -11,12 +11,11 @@ # This code is a port of the C++ code found in SciTE 1.74 # Original code: Copyright 1998-2006 by Neil Hodgson <neilh@scintilla.org> -from PyQt5.QtCore import Qt -from PyQt5.QtGui import QCursor, QFontInfo -from PyQt5.QtWidgets import QApplication +from PyQt5.QtGui import QFontInfo from PyQt5.Qsci import QsciScintilla from E5Gui import E5MessageBox +from E5Gui.E5OverrideCursor import E5OverrideCursor from .ExporterBase import ExporterBase @@ -437,116 +436,113 @@ if not filename: return + self.editor.recolor(0, -1) + lex = self.editor.getLexer() + + tabSize = self.editor.getEditorConfig("TabWidth") + if tabSize == 0: + tabSize = 4 + + # get magnification value to add to default screen font size + self.pr.fontSize = Preferences.getEditorExporter( + "PDF/Magnification") + + # set font family according to face name + fontName = Preferences.getEditorExporter("PDF/Font") + self.pr.fontSet = PDF_FONT_DEFAULT + if fontName == "Courier": + self.pr.fontSet = 0 + elif fontName == "Helvetica": + self.pr.fontSet = 1 + elif fontName == "Times": + self.pr.fontSet = 2 + + # page size: height, width, + pageSize = Preferences.getEditorExporter("PDF/PageSize") try: - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() - - self.editor.recolor(0, -1) - lex = self.editor.getLexer() - - tabSize = self.editor.getEditorConfig("TabWidth") - if tabSize == 0: - tabSize = 4 - - # get magnification value to add to default screen font size - self.pr.fontSize = Preferences.getEditorExporter( - "PDF/Magnification") - - # set font family according to face name - fontName = Preferences.getEditorExporter("PDF/Font") - self.pr.fontSet = PDF_FONT_DEFAULT - if fontName == "Courier": - self.pr.fontSet = 0 - elif fontName == "Helvetica": - self.pr.fontSet = 1 - elif fontName == "Times": - self.pr.fontSet = 2 + pageDimensions = PDFpageSizes[pageSize] + except KeyError: + pageDimensions = PDFpageSizes["A4"] + self.pr.pageHeight = pageDimensions[0] + self.pr.pageWidth = pageDimensions[1] + + # page margins: left, right, top, bottom + # < 0 to use PDF default values + val = Preferences.getEditorExporter("PDF/MarginLeft") + if val < 0: + self.pr.pageMargins["left"] = PDF_MARGIN_DEFAULT + else: + self.pr.pageMargins["left"] = val + val = Preferences.getEditorExporter("PDF/MarginRight") + if val < 0: + self.pr.pageMargins["right"] = PDF_MARGIN_DEFAULT + else: + self.pr.pageMargins["right"] = val + val = Preferences.getEditorExporter("PDF/MarginTop") + if val < 0: + self.pr.pageMargins["top"] = PDF_MARGIN_DEFAULT + else: + self.pr.pageMargins["top"] = val + val = Preferences.getEditorExporter("PDF/MarginBottom") + if val < 0: + self.pr.pageMargins["bottom"] = PDF_MARGIN_DEFAULT + else: + self.pr.pageMargins["bottom"] = val + + # collect all styles available for that 'language' + # or the default style if no language is available... + if lex: + istyle = 0 + while istyle <= QsciScintilla.STYLE_MAX: + if (istyle <= QsciScintilla.STYLE_DEFAULT or + istyle > QsciScintilla.STYLE_LASTPREDEFINED): + if ( + lex.description(istyle) or + istyle == QsciScintilla.STYLE_DEFAULT + ): + style = PDFStyle() + + font = lex.font(istyle) + if font.italic(): + style.font |= 2 + if font.bold(): + style.font |= 1 + + colour = lex.color(istyle) + style.fore = self.__getPDFRGB(colour) + self.pr.style[istyle] = style + + # grab font size from default style + if istyle == QsciScintilla.STYLE_DEFAULT: + fontSize = QFontInfo(font).pointSize() + if fontSize > 0: + self.pr.fontSize += fontSize + else: + self.pr.fontSize = PDF_FONTSIZE_DEFAULT + + istyle += 1 + else: + style = PDFStyle() - # page size: height, width, - pageSize = Preferences.getEditorExporter("PDF/PageSize") - try: - pageDimensions = PDFpageSizes[pageSize] - except KeyError: - pageDimensions = PDFpageSizes["A4"] - self.pr.pageHeight = pageDimensions[0] - self.pr.pageWidth = pageDimensions[1] + font = Preferences.getEditorOtherFonts("DefaultFont") + if font.italic(): + style.font |= 2 + if font.bold(): + style.font |= 1 - # page margins: left, right, top, bottom - # < 0 to use PDF default values - val = Preferences.getEditorExporter("PDF/MarginLeft") - if val < 0: - self.pr.pageMargins["left"] = PDF_MARGIN_DEFAULT - else: - self.pr.pageMargins["left"] = val - val = Preferences.getEditorExporter("PDF/MarginRight") - if val < 0: - self.pr.pageMargins["right"] = PDF_MARGIN_DEFAULT - else: - self.pr.pageMargins["right"] = val - val = Preferences.getEditorExporter("PDF/MarginTop") - if val < 0: - self.pr.pageMargins["top"] = PDF_MARGIN_DEFAULT - else: - self.pr.pageMargins["top"] = val - val = Preferences.getEditorExporter("PDF/MarginBottom") - if val < 0: - self.pr.pageMargins["bottom"] = PDF_MARGIN_DEFAULT + colour = self.editor.color() + style.fore = self.__getPDFRGB(colour) + self.pr.style[0] = style + self.pr.style[QsciScintilla.STYLE_DEFAULT] = style + + fontSize = QFontInfo(font).pointSize() + if fontSize > 0: + self.pr.fontSize += fontSize else: - self.pr.pageMargins["bottom"] = val - - # collect all styles available for that 'language' - # or the default style if no language is available... - if lex: - istyle = 0 - while istyle <= QsciScintilla.STYLE_MAX: - if (istyle <= QsciScintilla.STYLE_DEFAULT or - istyle > QsciScintilla.STYLE_LASTPREDEFINED): - if ( - lex.description(istyle) or - istyle == QsciScintilla.STYLE_DEFAULT - ): - style = PDFStyle() - - font = lex.font(istyle) - if font.italic(): - style.font |= 2 - if font.bold(): - style.font |= 1 - - colour = lex.color(istyle) - style.fore = self.__getPDFRGB(colour) - self.pr.style[istyle] = style - - # grab font size from default style - if istyle == QsciScintilla.STYLE_DEFAULT: - fontSize = QFontInfo(font).pointSize() - if fontSize > 0: - self.pr.fontSize += fontSize - else: - self.pr.fontSize = PDF_FONTSIZE_DEFAULT - - istyle += 1 - else: - style = PDFStyle() - - font = Preferences.getEditorOtherFonts("DefaultFont") - if font.italic(): - style.font |= 2 - if font.bold(): - style.font |= 1 - - colour = self.editor.color() - style.fore = self.__getPDFRGB(colour) - self.pr.style[0] = style - self.pr.style[QsciScintilla.STYLE_DEFAULT] = style - - fontSize = QFontInfo(font).pointSize() - if fontSize > 0: - self.pr.fontSize += fontSize - else: - self.pr.fontSize = PDF_FONTSIZE_DEFAULT - - try: + self.pr.fontSize = PDF_FONTSIZE_DEFAULT + + try: + with E5OverrideCursor(): # save file in win ansi using cp1250 f = open(filename, "w", encoding="cp1250", errors="backslashreplace") @@ -616,14 +612,11 @@ # write required stuff and close the PDF file self.pr.endPDF() f.close() - except IOError as err: - QApplication.restoreOverrideCursor() - E5MessageBox.critical( - self.editor, - self.tr("Export source"), - self.tr( - """<p>The source could not be exported to""" - """ <b>{0}</b>.</p><p>Reason: {1}</p>""") - .format(filename, str(err))) - finally: - QApplication.restoreOverrideCursor() + except IOError as err: + E5MessageBox.critical( + self.editor, + self.tr("Export source"), + self.tr( + """<p>The source could not be exported to""" + """ <b>{0}</b>.</p><p>Reason: {1}</p>""") + .format(filename, str(err)))
--- a/eric6/QScintilla/Exporters/ExporterRTF.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/QScintilla/Exporters/ExporterRTF.py Sat Oct 10 12:20:51 2020 +0200 @@ -13,12 +13,11 @@ import time -from PyQt5.QtCore import Qt -from PyQt5.QtGui import QCursor, QFontInfo -from PyQt5.QtWidgets import QApplication +from PyQt5.QtGui import QFontInfo from PyQt5.Qsci import QsciScintilla from E5Gui import E5MessageBox +from E5Gui.E5OverrideCursor import E5OverrideCursor from .ExporterBase import ExporterBase @@ -120,40 +119,37 @@ if not filename: return + self.editor.recolor(0, -1) + lex = self.editor.getLexer() + + tabSize = self.editor.getEditorConfig("TabWidth") + if tabSize == 0: + tabSize = 4 + wysiwyg = Preferences.getEditorExporter("RTF/WYSIWYG") + if wysiwyg: + if lex: + defaultFont = lex.font(QsciScintilla.STYLE_DEFAULT) + else: + defaultFont = Preferences.getEditorOtherFonts( + "DefaultFont") + else: + defaultFont = Preferences.getEditorExporter("RTF/Font") + fontface = defaultFont.family() + fontsize = QFontInfo(defaultFont).pointSize() << 1 + if fontsize == 0: + fontsize = 10 << 1 + characterset = QsciScintilla.SC_CHARSET_DEFAULT + tabs = Preferences.getEditorExporter("RTF/UseTabs") + + if lex: + fgColour = lex.color(QsciScintilla.STYLE_DEFAULT) + bgColour = lex.paper(QsciScintilla.STYLE_DEFAULT) + else: + fgColour = self.editor.color() + bgColour = self.editor.paper() + try: - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() - - self.editor.recolor(0, -1) - lex = self.editor.getLexer() - - tabSize = self.editor.getEditorConfig("TabWidth") - if tabSize == 0: - tabSize = 4 - wysiwyg = Preferences.getEditorExporter("RTF/WYSIWYG") - if wysiwyg: - if lex: - defaultFont = lex.font(QsciScintilla.STYLE_DEFAULT) - else: - defaultFont = Preferences.getEditorOtherFonts( - "DefaultFont") - else: - defaultFont = Preferences.getEditorExporter("RTF/Font") - fontface = defaultFont.family() - fontsize = QFontInfo(defaultFont).pointSize() << 1 - if fontsize == 0: - fontsize = 10 << 1 - characterset = QsciScintilla.SC_CHARSET_DEFAULT - tabs = Preferences.getEditorExporter("RTF/UseTabs") - - if lex: - fgColour = lex.color(QsciScintilla.STYLE_DEFAULT) - bgColour = lex.paper(QsciScintilla.STYLE_DEFAULT) - else: - fgColour = self.editor.color() - bgColour = self.editor.paper() - - try: + with E5OverrideCursor(): f = open(filename, "w", encoding="utf-8") styles = {} @@ -366,14 +362,11 @@ f.write(self.RTF_BODYCLOSE) f.close() - except IOError as err: - QApplication.restoreOverrideCursor() - E5MessageBox.critical( - self.editor, - self.tr("Export source"), - self.tr( - """<p>The source could not be exported to""" - """ <b>{0}</b>.</p><p>Reason: {1}</p>""") - .format(filename, str(err))) - finally: - QApplication.restoreOverrideCursor() + except IOError as err: + E5MessageBox.critical( + self.editor, + self.tr("Export source"), + self.tr( + """<p>The source could not be exported to""" + """ <b>{0}</b>.</p><p>Reason: {1}</p>""") + .format(filename, str(err)))
--- a/eric6/QScintilla/Exporters/ExporterTEX.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/QScintilla/Exporters/ExporterTEX.py Sat Oct 10 12:20:51 2020 +0200 @@ -13,12 +13,10 @@ import os -from PyQt5.QtCore import Qt -from PyQt5.QtGui import QCursor -from PyQt5.QtWidgets import QApplication from PyQt5.Qsci import QsciScintilla from E5Gui import E5MessageBox +from E5Gui.E5OverrideCursor import E5OverrideCursor from .ExporterBase import ExporterBase @@ -115,54 +113,51 @@ if not filename: return + self.editor.recolor(0, -1) + + tabSize = self.editor.getEditorConfig("TabWidth") + if tabSize == 0: + tabSize = 4 + + onlyStylesUsed = Preferences.getEditorExporter( + "TeX/OnlyStylesUsed") + titleFullPath = Preferences.getEditorExporter( + "TeX/FullPathAsTitle") + + lex = self.editor.getLexer() + self.defaultPaper = ( + lex and + lex.paper(QsciScintilla.STYLE_DEFAULT) or + self.editor.paper().name() + ) + self.defaultColor = ( + lex and + lex.color(QsciScintilla.STYLE_DEFAULT) or + self.editor.color().name() + ) + self.defaultFont = ( + lex and + lex.color(QsciScintilla.STYLE_DEFAULT) or + Preferences.getEditorOtherFonts("DefaultFont") + ) + + lengthDoc = self.editor.length() + styleIsUsed = {} + if onlyStylesUsed: + for index in range(QsciScintilla.STYLE_MAX + 1): + styleIsUsed[index] = False + # check the used styles + pos = 0 + while pos < lengthDoc: + styleIsUsed[self.editor.styleAt(pos) & 0x7F] = True + pos += 1 + else: + for index in range(QsciScintilla.STYLE_MAX + 1): + styleIsUsed[index] = True + styleIsUsed[QsciScintilla.STYLE_DEFAULT] = True + try: - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() - - self.editor.recolor(0, -1) - - tabSize = self.editor.getEditorConfig("TabWidth") - if tabSize == 0: - tabSize = 4 - - onlyStylesUsed = Preferences.getEditorExporter( - "TeX/OnlyStylesUsed") - titleFullPath = Preferences.getEditorExporter( - "TeX/FullPathAsTitle") - - lex = self.editor.getLexer() - self.defaultPaper = ( - lex and - lex.paper(QsciScintilla.STYLE_DEFAULT) or - self.editor.paper().name() - ) - self.defaultColor = ( - lex and - lex.color(QsciScintilla.STYLE_DEFAULT) or - self.editor.color().name() - ) - self.defaultFont = ( - lex and - lex.color(QsciScintilla.STYLE_DEFAULT) or - Preferences.getEditorOtherFonts("DefaultFont") - ) - - lengthDoc = self.editor.length() - styleIsUsed = {} - if onlyStylesUsed: - for index in range(QsciScintilla.STYLE_MAX + 1): - styleIsUsed[index] = False - # check the used styles - pos = 0 - while pos < lengthDoc: - styleIsUsed[self.editor.styleAt(pos) & 0x7F] = True - pos += 1 - else: - for index in range(QsciScintilla.STYLE_MAX + 1): - styleIsUsed[index] = True - styleIsUsed[QsciScintilla.STYLE_DEFAULT] = True - - try: + with E5OverrideCursor(): f = open(filename, "w", encoding="utf-8") f.write("\\documentclass[a4paper]{article}\n") @@ -279,14 +274,11 @@ # close last empty style macros and document too f.write("}\n} %end tiny\n\n\\end{document}\n") f.close() - except IOError as err: - QApplication.restoreOverrideCursor() - E5MessageBox.critical( - self.editor, - self.tr("Export source"), - self.tr( - """<p>The source could not be exported to""" - """ <b>{0}</b>.</p><p>Reason: {1}</p>""") - .format(filename, str(err))) - finally: - QApplication.restoreOverrideCursor() + except IOError as err: + E5MessageBox.critical( + self.editor, + self.tr("Export source"), + self.tr( + """<p>The source could not be exported to""" + """ <b>{0}</b>.</p><p>Reason: {1}</p>""") + .format(filename, str(err)))
--- a/eric6/QScintilla/MiniEditor.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/QScintilla/MiniEditor.py Sat Oct 10 12:20:51 2020 +0200 @@ -15,7 +15,7 @@ QSignalMapper, QPoint, QTimer, QFileInfo, pyqtSignal, QSize, QRegExp, Qt, QCoreApplication ) -from PyQt5.QtGui import QCursor, QKeySequence, QPalette, QFont, QPixmap +from PyQt5.QtGui import QKeySequence, QPalette, QFont, QPixmap from PyQt5.QtWidgets import ( QWidget, QWhatsThis, QActionGroup, QDialog, QInputDialog, QApplication, QMenu, QVBoxLayout, QHBoxLayout, QLabel @@ -28,6 +28,7 @@ from E5Gui.E5MainWindow import E5MainWindow from E5Gui.E5ClickableLabel import E5ClickableLabel from E5Gui.E5ZoomWidget import E5ZoomWidget +from E5Gui.E5OverrideCursor import E5OverrideCursor from .QsciScintillaCompat import QsciScintillaCompat @@ -2519,48 +2520,45 @@ @param fileName name of the file to load (string) @param filetype type of the source file (string) """ - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - self.__loadEditorConfig(fileName=fileName) try: - encoding = self.__getEditorConfig("DefaultEncoding", - nodefault=True) - if encoding: - txt, self.encoding = Utilities.readEncodedFileWithEncoding( - fileName, encoding) - else: - txt, self.encoding = Utilities.readEncodedFile(fileName) + with E5OverrideCursor(): + encoding = self.__getEditorConfig("DefaultEncoding", + nodefault=True) + if encoding: + txt, self.encoding = Utilities.readEncodedFileWithEncoding( + fileName, encoding) + else: + txt, self.encoding = Utilities.readEncodedFile(fileName) except (UnicodeDecodeError, IOError) as why: - QApplication.restoreOverrideCursor() E5MessageBox.critical( self, self.tr('Open File'), self.tr('<p>The file <b>{0}</b> could not be opened.</p>' '<p>Reason: {1}</p>') .format(fileName, str(why))) - QApplication.restoreOverrideCursor() return - self.__textEdit.setText(txt) - QApplication.restoreOverrideCursor() - - if filetype is None: - self.filetype = "" - else: - self.filetype = filetype - self.__setCurrentFile(fileName) - - self.__textEdit.setModified(False) - self.setWindowModified(False) - - self.__convertTabs() - - eolMode = self.__getEditorConfig("EOLMode", nodefault=True) - if eolMode is None: - fileEol = self.__textEdit.detectEolString(txt) - self.__textEdit.setEolModeByEolString(fileEol) - else: - self.__textEdit.convertEols(eolMode) + with E5OverrideCursor(): + self.__textEdit.setText(txt) + + if filetype is None: + self.filetype = "" + else: + self.filetype = filetype + self.__setCurrentFile(fileName) + + self.__textEdit.setModified(False) + self.setWindowModified(False) + + self.__convertTabs() + + eolMode = self.__getEditorConfig("EOLMode", nodefault=True) + if eolMode is None: + fileEol = self.__textEdit.detectEolString(txt) + self.__textEdit.setEolModeByEolString(fileEol) + else: + self.__textEdit.convertEols(eolMode) self.__statusBar.showMessage(self.tr("File loaded"), 2000) @@ -2612,8 +2610,6 @@ @return flag indicating success @rtype bool """ - QApplication.setOverrideCursor(Qt.WaitCursor) - config = self.__loadEditorConfigObject(fileName) eol = self.__getEditorConfig("EOLMode", nodefault=True, config=config) @@ -2636,13 +2632,13 @@ # now write text to the file try: - editorConfigEncoding = self.__getEditorConfig( - "DefaultEncoding", nodefault=True, config=config) - self.encoding = Utilities.writeEncodedFile( - fileName, txt, self.encoding, - forcedEncoding=editorConfigEncoding) + with E5OverrideCursor(): + editorConfigEncoding = self.__getEditorConfig( + "DefaultEncoding", nodefault=True, config=config) + self.encoding = Utilities.writeEncodedFile( + fileName, txt, self.encoding, + forcedEncoding=editorConfigEncoding) except (IOError, Utilities.CodingError, UnicodeError) as why: - QApplication.restoreOverrideCursor() E5MessageBox.critical( self, self.tr('Save File'), self.tr('<p>The file <b>{0}</b> could not be saved.<br/>' @@ -2650,7 +2646,6 @@ .format(fileName, str(why))) return False - QApplication.restoreOverrideCursor() self.__statusBar.showMessage(self.tr("File saved"), 2000) return True
--- a/eric6/Snapshot/SnapWidget.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/Snapshot/SnapWidget.py Sat Oct 10 12:20:51 2020 +0200 @@ -315,7 +315,6 @@ Private method to redisplay the window. """ self.__updatePreview() - QApplication.restoreOverrideCursor() if not self.__savedPosition.isNull(): self.move(self.__savedPosition) self.show()
--- a/eric6/Tools/UIPreviewer.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/Tools/UIPreviewer.py Sat Oct 10 12:20:51 2020 +0200 @@ -9,7 +9,7 @@ from PyQt5.QtCore import QDir, QFileInfo, QEvent, QSize, Qt -from PyQt5.QtGui import QCursor, QKeySequence, QImageWriter, QPainter +from PyQt5.QtGui import QKeySequence, QImageWriter, QPainter from PyQt5.QtWidgets import ( QSizePolicy, QSpacerItem, QWidget, QHBoxLayout, QWhatsThis, QDialog, QScrollArea, QApplication, QStyleFactory, QFrame, QMainWindow, @@ -22,6 +22,7 @@ from E5Gui import E5MessageBox, E5FileDialog from E5Gui.E5MainWindow import E5MainWindow from E5Gui.E5Application import e5App +from E5Gui.E5OverrideCursor import E5OverrideCursor import Preferences import UI.PixmapCache @@ -376,26 +377,25 @@ @param sstyle name of the selected style (string) """ - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - qstyle = QStyleFactory.create(sstyle) - self.mainWidget.setStyle(qstyle) - - lst = self.mainWidget.findChildren(QWidget) - for obj in lst: - try: - obj.setStyle(qstyle) - except AttributeError: - pass - del lst - - self.mainWidget.hide() - self.mainWidget.show() - - self.lastQStyle = qstyle - self.lastStyle = sstyle - Preferences.Prefs.settings.setValue( - 'UIPreviewer/style', self.styleCombo.currentIndex()) - QApplication.restoreOverrideCursor() + with E5OverrideCursor(): + qstyle = QStyleFactory.create(sstyle) + self.mainWidget.setStyle(qstyle) + + lst = self.mainWidget.findChildren(QWidget) + for obj in lst: + try: + obj.setStyle(qstyle) + except AttributeError: + pass + del lst + + self.mainWidget.hide() + self.mainWidget.show() + + self.lastQStyle = qstyle + self.lastStyle = sstyle + Preferences.Prefs.settings.setValue( + 'UIPreviewer/style', self.styleCombo.currentIndex()) def __updateActions(self): """
--- a/eric6/UI/EmailDialog.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/UI/EmailDialog.py Sat Oct 10 12:20:51 2020 +0200 @@ -7,20 +7,20 @@ Module implementing a dialog to send bug reports or feature requests. """ - import os import mimetypes import smtplib import socket from PyQt5.QtCore import Qt, pyqtSlot -from PyQt5.QtGui import QCursor, QTextOption +from PyQt5.QtGui import QTextOption from PyQt5.QtWidgets import ( - QHeaderView, QLineEdit, QDialog, QInputDialog, QApplication, - QDialogButtonBox, QTreeWidgetItem + QHeaderView, QLineEdit, QDialog, QInputDialog, QDialogButtonBox, + QTreeWidgetItem ) from E5Gui import E5MessageBox, E5FileDialog +from E5Gui.E5OverrideCursor import E5OverrideCursor from .Ui_EmailDialog import Ui_EmailDialog @@ -350,14 +350,11 @@ else: return False - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() - server.sendmail(Preferences.getUser("Email"), self.__toAddress, - msg) - server.quit() - QApplication.restoreOverrideCursor() + with E5OverrideCursor(): + server.sendmail(Preferences.getUser("Email"), self.__toAddress, + msg) + server.quit() except (smtplib.SMTPException, socket.error) as e: - QApplication.restoreOverrideCursor() if isinstance(e, smtplib.SMTPResponseException): errorStr = e.smtp_error.decode() elif isinstance(e, smtplib.SMTPException):
--- a/eric6/UI/PythonAstViewer.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/UI/PythonAstViewer.py Sat Oct 10 12:20:51 2020 +0200 @@ -11,14 +11,15 @@ import ast from PyQt5.QtCore import pyqtSlot, Qt, QTimer -from PyQt5.QtGui import QCursor, QBrush +from PyQt5.QtGui import QBrush from PyQt5.QtWidgets import ( - QTreeWidget, QApplication, QTreeWidgetItem, QAbstractItemView, QWidget, - QVBoxLayout + QTreeWidget, QTreeWidgetItem, QAbstractItemView, QWidget, QVBoxLayout ) from ThirdParty.asttokens.asttokens import ASTTokens +from E5Gui.E5OverrideCursor import E5OverrideCursor + import Preferences @@ -229,27 +230,25 @@ )) return - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - try: - # generate the AST - root = ast.parse(source, self.__editor.getFileName(), "exec") - self.__markTextRanges(root, source) - astValid = True - except Exception as exc: - self.__createErrorItem(str(exc)) - astValid = False - - if astValid: - self.setUpdatesEnabled(False) + with E5OverrideCursor(): + try: + # generate the AST + root = ast.parse(source, self.__editor.getFileName(), "exec") + self.__markTextRanges(root, source) + astValid = True + except Exception as exc: + self.__createErrorItem(str(exc)) + astValid = False - # populate the AST tree - self.__populateNode(self.tr("Module"), root, self.__astWidget) - self.__selectItemForEditorSelection() - QTimer.singleShot(0, self.__resizeColumns) - - self.setUpdatesEnabled(True) - - QApplication.restoreOverrideCursor() + if astValid: + self.setUpdatesEnabled(False) + + # populate the AST tree + self.__populateNode(self.tr("Module"), root, self.__astWidget) + self.__selectItemForEditorSelection() + QTimer.singleShot(0, self.__resizeColumns) + + self.setUpdatesEnabled(True) self.__grabFocus()
--- a/eric6/UI/PythonDisViewer.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/UI/PythonDisViewer.py Sat Oct 10 12:20:51 2020 +0200 @@ -15,12 +15,13 @@ from PyQt5.QtCore import pyqtSlot, Qt, QTimer -from PyQt5.QtGui import QCursor, QBrush +from PyQt5.QtGui import QBrush from PyQt5.QtWidgets import ( - QApplication, QTreeWidgetItem, QAbstractItemView, QWidget, QMenu + QTreeWidgetItem, QAbstractItemView, QWidget, QMenu ) from E5Gui.E5Application import e5App +from E5Gui.E5OverrideCursor import E5OverrideCursor import Preferences @@ -478,24 +479,22 @@ else: filename = "<dis>" - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - try: - codeObject = self.__tryCompile(source, filename) - except Exception as exc: - codeObject = None - self.__createErrorItem(str(exc)) - - if codeObject: - self.setUpdatesEnabled(False) - block = self.disWidget.blockSignals(True) + with E5OverrideCursor(): + try: + codeObject = self.__tryCompile(source, filename) + except Exception as exc: + codeObject = None + self.__createErrorItem(str(exc)) - self.__disassembleObject(codeObject, self.disWidget, filename) - QTimer.singleShot(0, self.__resizeDisColumns) - - self.disWidget.blockSignals(block) - self.setUpdatesEnabled(True) - - QApplication.restoreOverrideCursor() + if codeObject: + self.setUpdatesEnabled(False) + block = self.disWidget.blockSignals(True) + + self.__disassembleObject(codeObject, self.disWidget, filename) + QTimer.singleShot(0, self.__resizeDisColumns) + + self.disWidget.blockSignals(block) + self.setUpdatesEnabled(True) @pyqtSlot(dict) def showDisassembly(self, disassembly):
--- a/eric6/WebBrowser/AdBlock/AdBlockTreeWidget.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/WebBrowser/AdBlock/AdBlockTreeWidget.py Sat Oct 10 12:20:51 2020 +0200 @@ -16,6 +16,7 @@ ) from E5Gui.E5TreeWidget import E5TreeWidget +from E5Gui.E5OverrideCursor import E5OverrideCursor class AdBlockTreeWidget(E5TreeWidget): @@ -79,35 +80,33 @@ """ Public method to refresh the tree. """ - QApplication.setOverrideCursor(Qt.WaitCursor) - self.__itemChangingBlock = True - self.clear() - - boldFont = QFont() - boldFont.setBold(True) - - self.__topItem = QTreeWidgetItem(self) - self.__topItem.setText(0, self.__subscription.title()) - self.__topItem.setFont(0, boldFont) - self.addTopLevelItem(self.__topItem) - - allRules = self.__subscription.allRules() - - index = 0 - for rule in allRules: - item = QTreeWidgetItem(self.__topItem) - item.setText(0, rule.filter()) - item.setData(0, Qt.UserRole, index) - if self.__subscription.canEditRules(): - item.setFlags(item.flags() | Qt.ItemIsEditable) - self.__adjustItemFeatures(item, rule) - index += 1 - - self.expandAll() - self.showRule(None) - self.__itemChangingBlock = False - QApplication.restoreOverrideCursor() - QApplication.processEvents() + with E5OverrideCursor(): + self.__itemChangingBlock = True + self.clear() + + boldFont = QFont() + boldFont.setBold(True) + + self.__topItem = QTreeWidgetItem(self) + self.__topItem.setText(0, self.__subscription.title()) + self.__topItem.setFont(0, boldFont) + self.addTopLevelItem(self.__topItem) + + allRules = self.__subscription.allRules() + + index = 0 + for rule in allRules: + item = QTreeWidgetItem(self.__topItem) + item.setText(0, rule.filter()) + item.setData(0, Qt.UserRole, index) + if self.__subscription.canEditRules(): + item.setFlags(item.flags() | Qt.ItemIsEditable) + self.__adjustItemFeatures(item, rule) + index += 1 + + self.expandAll() + self.showRule(None) + self.__itemChangingBlock = False def addRule(self, filterRule=""): """
--- a/eric6/WebBrowser/FlashCookieManager/FlashCookieManagerDialog.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/WebBrowser/FlashCookieManager/FlashCookieManagerDialog.py Sat Oct 10 12:20:51 2020 +0200 @@ -14,6 +14,7 @@ ) from E5Gui import E5MessageBox +from E5Gui.E5OverrideCursor import E5OverrideCursor from .Ui_FlashCookieManagerDialog import Ui_FlashCookieManagerDialog @@ -336,58 +337,55 @@ """ Private slot to refresh the cookies list. """ - QApplication.setOverrideCursor(Qt.WaitCursor) - - cookies = self.__manager.flashCookies() - self.cookiesList.clear() - - counter = 0 - originDict = {} - for cookie in cookies: - cookieOrigin = cookie.origin - if cookieOrigin.startswith("."): - cookieOrigin = cookieOrigin[1:] - - if cookieOrigin in originDict: - itm = QTreeWidgetItem(originDict[cookieOrigin]) - else: - newParent = QTreeWidgetItem(self.cookiesList) - newParent.setText(0, cookieOrigin) - newParent.setIcon(0, UI.PixmapCache.getIcon("dirOpen")) - self.cookiesList.addTopLevelItem(newParent) - originDict[cookieOrigin] = newParent - - itm = QTreeWidgetItem(newParent) + with E5OverrideCursor(): + cookies = self.__manager.flashCookies() + self.cookiesList.clear() - suffix = "" - if cookie.path.startswith( - self.__manager.flashPlayerDataPath() + - "/macromedia.com/support/flashplayer/sys"): - suffix = self.tr(" (settings)") - - if cookie.path + "/" + cookie.name in ( - self.__manager.newCookiesList() - ): - suffix += self.tr(" [new]") - font = itm.font(0) - font.setBold(True) - itm.setFont(font) - itm.parent().setExpanded(True) + counter = 0 + originDict = {} + for cookie in cookies: + cookieOrigin = cookie.origin + if cookieOrigin.startswith("."): + cookieOrigin = cookieOrigin[1:] + + if cookieOrigin in originDict: + itm = QTreeWidgetItem(originDict[cookieOrigin]) + else: + newParent = QTreeWidgetItem(self.cookiesList) + newParent.setText(0, cookieOrigin) + newParent.setIcon(0, UI.PixmapCache.getIcon("dirOpen")) + self.cookiesList.addTopLevelItem(newParent) + originDict[cookieOrigin] = newParent + + itm = QTreeWidgetItem(newParent) + + suffix = "" + if cookie.path.startswith( + self.__manager.flashPlayerDataPath() + + "/macromedia.com/support/flashplayer/sys"): + suffix = self.tr(" (settings)") + + if cookie.path + "/" + cookie.name in ( + self.__manager.newCookiesList() + ): + suffix += self.tr(" [new]") + font = itm.font(0) + font.setBold(True) + itm.setFont(font) + itm.parent().setExpanded(True) + + itm.setText(0, self.tr("{0}{1}", "name and suffix").format( + cookie.name, suffix)) + itm.setData(0, Qt.UserRole, cookie) + + counter += 1 + if counter > 100: + QApplication.processEvents() + counter = 0 - itm.setText(0, self.tr("{0}{1}", "name and suffix").format( - cookie.name, suffix)) - itm.setData(0, Qt.UserRole, cookie) - - counter += 1 - if counter > 100: - QApplication.processEvents() - counter = 0 - - self.removeAllButton.setEnabled( - self.cookiesList.topLevelItemCount() > 0) - self.removeButton.setEnabled(False) - - QApplication.restoreOverrideCursor() + self.removeAllButton.setEnabled( + self.cookiesList.topLevelItemCount() > 0) + self.removeButton.setEnabled(False) @pyqtSlot() def __refreshFilterLists(self):
--- a/eric6/WebBrowser/SafeBrowsing/SafeBrowsingDialog.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/WebBrowser/SafeBrowsing/SafeBrowsingDialog.py Sat Oct 10 12:20:51 2020 +0200 @@ -10,10 +10,11 @@ from PyQt5.QtCore import pyqtSlot, Qt, QUrl, QDateTime from PyQt5.QtWidgets import ( - QDialog, QDialogButtonBox, QAbstractButton, QApplication + QDialog, QDialogButtonBox, QAbstractButton ) from E5Gui import E5MessageBox +from E5Gui.E5OverrideCursor import E5OverrideCursor from .Ui_SafeBrowsingDialog import Ui_SafeBrowsingDialog @@ -167,7 +168,6 @@ @return flag indicating safe to close @rtype bool """ - QApplication.restoreOverrideCursor() if self.__isModified(): res = E5MessageBox.okToClearData( self, @@ -200,10 +200,9 @@ 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() + with E5OverrideCursor(): + ok, error = self.__manager.updateHashPrefixCache() + self.__resetProgress() if not ok: if error: E5MessageBox.critical( @@ -229,9 +228,8 @@ self.tr("""Do you really want to clear the Safe Browsing cache?""" """ Re-populating it might take some time.""")) if res: - QApplication.setOverrideCursor(Qt.WaitCursor) - self.__manager.fullCacheCleanup() - QApplication.restoreOverrideCursor() + with E5OverrideCursor(): + self.__manager.fullCacheCleanup() @pyqtSlot(str, int) def __setProgressMessage(self, message, maximum):
--- a/eric6/WebBrowser/Session/SessionManager.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/WebBrowser/Session/SessionManager.py Sat Oct 10 12:20:51 2020 +0200 @@ -21,6 +21,7 @@ ) from E5Gui import E5MessageBox +from E5Gui.E5OverrideCursor import E5OverrideCursor import Utilities import Preferences @@ -439,28 +440,27 @@ if window is None: window = WebBrowserWindow.mainWindow() - QApplication.setOverrideCursor(Qt.WaitCursor) - # restore session for first window - data = sessionData["Windows"].pop(0) - window.tabWidget().loadFromSessionData(data) - if "WindowGeometry" in data: - geometry = QByteArray.fromBase64( - data["WindowGeometry"].encode("ascii")) - window.restoreGeometry(geometry) - QApplication.processEvents() - - # restore additional windows - for data in sessionData["Windows"]: - window = ( - WebBrowserWindow.mainWindow().newWindow(restoreSession=True) - ) + with E5OverrideCursor(): + # restore session for first window + data = sessionData["Windows"].pop(0) window.tabWidget().loadFromSessionData(data) if "WindowGeometry" in data: geometry = QByteArray.fromBase64( data["WindowGeometry"].encode("ascii")) window.restoreGeometry(geometry) QApplication.processEvents() - QApplication.restoreOverrideCursor() + + # restore additional windows + for data in sessionData["Windows"]: + window = ( + WebBrowserWindow.mainWindow().newWindow(restoreSession=True) + ) + window.tabWidget().loadFromSessionData(data) + if "WindowGeometry" in data: + geometry = QByteArray.fromBase64( + data["WindowGeometry"].encode("ascii")) + window.restoreGeometry(geometry) + QApplication.processEvents() if "CurrentWindowIndex" in sessionData: currentWindowIndex = sessionData["CurrentWindowIndex"]
--- a/eric6/WebBrowser/WebBrowserTabWidget.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/WebBrowser/WebBrowserTabWidget.py Sat Oct 10 12:20:51 2020 +0200 @@ -13,13 +13,14 @@ from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QUrl, QFile, QFileDevice from PyQt5.QtGui import QIcon, QPixmap, QPainter from PyQt5.QtWidgets import ( - QWidget, QHBoxLayout, QMenu, QToolButton, QDialog, QApplication + QWidget, QHBoxLayout, QMenu, QToolButton, QDialog ) from PyQt5.QtPrintSupport import QPrinter, QPrintDialog, QAbstractPrintDialog from E5Gui.E5TabWidget import E5TabWidget from E5Gui import E5MessageBox from E5Gui.E5Application import e5App +from E5Gui.E5OverrideCursor import E5OverrideCursor from .WebBrowserView import WebBrowserView from .WebBrowserPage import WebBrowserPage @@ -807,9 +808,8 @@ @param browser reference to the browser to be printed @type WebBrowserView """ - QApplication.setOverrideCursor(Qt.WaitCursor) - browser.page().execPrintPage(printer, 10 * 1000) - QApplication.restoreOverrideCursor() + with E5OverrideCursor(): + browser.page().execPrintPage(printer, 10 * 1000) def __sourceChanged(self, url, browser): """
--- a/eric6/WebBrowser/WebBrowserWindow.py Fri Oct 09 17:19:29 2020 +0200 +++ b/eric6/WebBrowser/WebBrowserWindow.py Sat Oct 10 12:20:51 2020 +0200 @@ -35,6 +35,7 @@ from E5Gui.E5MainWindow import E5MainWindow from E5Gui.E5Application import e5App from E5Gui.E5ZoomWidget import E5ZoomWidget +from E5Gui.E5OverrideCursor import E5OverrideCursor from E5Network.E5NetworkIcon import E5NetworkIcon @@ -3454,13 +3455,12 @@ Private slot to synchronize the TOC with the currently shown page. """ if WebBrowserWindow._useQtHelp: - QApplication.setOverrideCursor(Qt.WaitCursor) - url = self.currentBrowser().source() - self.__showTocWindow() - if not self.__tocWindow.syncToContent(url): - self.statusBar().showMessage( - self.tr("Could not find an associated content."), 5000) - QApplication.restoreOverrideCursor() + with E5OverrideCursor(): + url = self.currentBrowser().source() + self.__showTocWindow() + if not self.__tocWindow.syncToContent(url): + self.statusBar().showMessage( + self.tr("Could not find an associated content."), 5000) def __showTocWindow(self): """