diff --git a/python/plugins/processing/ProcessingPlugin.py b/python/plugins/processing/ProcessingPlugin.py index 310180ee40d..67a805f3d82 100644 --- a/python/plugins/processing/ProcessingPlugin.py +++ b/python/plugins/processing/ProcessingPlugin.py @@ -40,13 +40,13 @@ from processing.core.Processing import Processing from processing.gui.ProcessingToolbox import ProcessingToolbox from processing.gui.HistoryDialog import HistoryDialog from processing.gui.ConfigDialog import ConfigDialog -from processing.gui.ResultsDialog import ResultsDialog +from processing.gui.ResultsDock import ResultsDock from processing.gui.CommanderWindow import CommanderWindow from processing.modeler.ModelerDialog import ModelerDialog from processing.tools.system import tempFolder from processing.gui.menus import removeMenus, initializeMenus, createMenus from processing.core.alglist import algList - +from processing.core.ProcessingResults import resultsList cmd_folder = os.path.split(inspect.getfile(inspect.currentframe()))[0] if cmd_folder not in sys.path: @@ -65,6 +65,12 @@ class ProcessingPlugin(object): self.iface.addDockWidget(Qt.RightDockWidgetArea, self.toolbox) self.toolbox.hide() + self.resultsDock = ResultsDock() + self.iface.addDockWidget(Qt.RightDockWidgetArea, self.resultsDock) + self.resultsDock.hide() + + resultsList.resultAdded.connect(self.resultsDock.fillTree) + self.menu = QMenu(self.iface.mainWindow().menuBar()) self.menu.setObjectName('processing') self.menu.setTitle(self.tr('Pro&cessing')) @@ -93,11 +99,11 @@ class ProcessingPlugin(object): self.iface.registerMainWindowAction(self.historyAction, 'Ctrl+Alt+H') self.menu.addAction(self.historyAction) - self.resultsAction = QAction( - QIcon(os.path.join(cmd_folder, 'images', 'results.svg')), - self.tr('&Results Viewer...'), self.iface.mainWindow()) + self.resultsAction = self.resultsDock.toggleViewAction() self.resultsAction.setObjectName('resultsAction') - self.resultsAction.triggered.connect(self.openResults) + self.resultsAction.setIcon( + QIcon(os.path.join(cmd_folder, 'images', 'results.svg'))) + self.resultsAction.setText(self.tr('&Results Viewer...')) self.iface.registerMainWindowAction(self.resultsAction, 'Ctrl+Alt+R') self.menu.addAction(self.resultsAction) @@ -132,6 +138,10 @@ class ProcessingPlugin(object): def unload(self): self.toolbox.setVisible(False) self.iface.removeDockWidget(self.toolbox) + + self.resultsDock.setVisible(False) + self.iface.removeDockWidget(self.resultsDock) + self.menu.deleteLater() # delete temporary output files @@ -171,9 +181,10 @@ class ProcessingPlugin(object): algList.reloadProvider('model') def openResults(self): - dlg = ResultsDialog() - dlg.show() - dlg.exec_() + if self.resultsDock.isVisible(): + self.resultsDock.hide() + else: + self.resultsDock.show() def openHistory(self): dlg = HistoryDialog() diff --git a/python/plugins/processing/core/ProcessingResults.py b/python/plugins/processing/core/ProcessingResults.py index 98654195d02..2ca0d1800d3 100644 --- a/python/plugins/processing/core/ProcessingResults.py +++ b/python/plugins/processing/core/ProcessingResults.py @@ -26,22 +26,29 @@ __copyright__ = '(C) 2012, Victor Olaya' __revision__ = '$Format:%H$' +from qgis.PyQt.QtCore import QObject, pyqtSignal -class ProcessingResults(object): + +class ProcessingResults(QObject): + + resultAdded = pyqtSignal() results = [] - @staticmethod - def addResult(name, result): - ProcessingResults.results.append(Result(name, result)) + def addResult(self, icon, name, result): + self.results.append(Result(icon, name, result)) + self.resultAdded.emit() - @staticmethod - def getResults(): - return ProcessingResults.results + def getResults(self): + return self.results class Result(object): - def __init__(self, name, filename): + def __init__(self, icon, name, filename): + self.icon = icon self.name = name self.filename = filename + + +resultsList = ProcessingResults() diff --git a/python/plugins/processing/gui/Postprocessing.py b/python/plugins/processing/gui/Postprocessing.py index 29d80a88f69..74e984fbc08 100644 --- a/python/plugins/processing/gui/Postprocessing.py +++ b/python/plugins/processing/gui/Postprocessing.py @@ -34,10 +34,10 @@ from qgis.core import (QgsProject, QgsProcessingFeedback) from processing.core.ProcessingConfig import ProcessingConfig -from processing.core.ProcessingResults import ProcessingResults +from processing.core.ProcessingResults import resultsList from processing.core.ProcessingLog import ProcessingLog -from processing.gui.ResultsDialog import ResultsDialog +#from processing.gui.ResultsDock import ResultsDock from processing.gui.RenderingStyles import RenderingStyles from processing.core.outputs import OutputRaster @@ -78,7 +78,7 @@ def handleAlgorithmResults(alg, feedback=None, showResults=True): "Error loading result layer:\n" + traceback.format_exc()) wrongLayers.append(out.description) elif isinstance(out, OutputHTML): - ProcessingResults.addResult(out.description, out.value) + resultsList.addResult(alg.getIcon(), out.description, out.value) htmlResults = True i += 1 @@ -89,8 +89,8 @@ def handleAlgorithmResults(alg, feedback=None, showResults=True): msg += "You can check the log messages to find more information about the execution of the algorithm" feedback.reportError(msg) - if showResults and htmlResults and not wrongLayers: - dlg = ResultsDialog() - dlg.exec_() + #~ if showResults and htmlResults and not wrongLayers: + #~ dlg = ResultsDialog() + #~ dlg.exec_() return len(wrongLayers) == 0 diff --git a/python/plugins/processing/gui/ResultsDialog.py b/python/plugins/processing/gui/ResultsDock.py similarity index 58% rename from python/plugins/processing/gui/ResultsDialog.py rename to python/plugins/processing/gui/ResultsDock.py index 9a00eea7fe1..75cbfbded0c 100644 --- a/python/plugins/processing/gui/ResultsDialog.py +++ b/python/plugins/processing/gui/ResultsDock.py @@ -2,7 +2,7 @@ """ *************************************************************************** - ResultsDialog.py + ResultsDock.py --------------------- Date : August 2012 Copyright : (C) 2012 by Victor Olaya @@ -30,57 +30,49 @@ import codecs from qgis.PyQt import uic from qgis.PyQt.QtCore import QUrl -from qgis.PyQt.QtGui import QIcon -from qgis.PyQt.QtWidgets import QStyle, QTreeWidgetItem +from qgis.PyQt.QtGui import QDesktopServices +from qgis.PyQt.QtWidgets import QTreeWidgetItem -from processing.core.ProcessingResults import ProcessingResults +from processing.core.ProcessingResults import resultsList pluginPath = os.path.split(os.path.dirname(__file__))[0] WIDGET, BASE = uic.loadUiType( - os.path.join(pluginPath, 'ui', 'DlgResults.ui')) + os.path.join(pluginPath, 'ui', 'resultsdockbase.ui')) -class ResultsDialog(BASE, WIDGET): +class ResultsDock(BASE, WIDGET): def __init__(self): - super(ResultsDialog, self).__init__(None) + super(ResultsDock, self).__init__(None) self.setupUi(self) - self.keyIcon = QIcon() - self.keyIcon.addPixmap(self.style().standardPixmap(QStyle.SP_FileIcon)) - - self.tree.currentItemChanged.connect(self.changeResult) + self.treeResults.currentItemChanged.connect(self.updateDescription) + self.treeResults.itemDoubleClicked.connect(self.openResult) self.fillTree() - if self.lastUrl: - self.txtResults.setHtml(self.loadResults(self.lastUrl)) - def fillTree(self): - elements = ProcessingResults.getResults() - if len(elements) == 0: - self.lastUrl = None - return + self.treeResults.blockSignals(True) + self.treeResults.clear() + elements = resultsList.getResults() for element in elements: item = TreeResultItem(element) - item.setIcon(0, self.keyIcon) - self.tree.addTopLevelItem(item) - self.lastUrl = elements[-1].filename + self.treeResults.addTopLevelItem(item) + self.treeResults.blockSignals(False) - def changeResult(self): - item = self.tree.currentItem() - if isinstance(item, TreeResultItem): - self.txtResults.setHtml(self.loadResults(item.filename)) + def updateDescription(self, current, previous): + if isinstance(current, TreeResultItem): + html = 'Algorithm: {}
File path: {}'.format(current.text(0), current.filename) + self.txtDescription.setHtml(html) - def loadResults(self, fileName): - with codecs.open(fileName, encoding='utf-8') as f: - content = f.read() - return content + def openResult(self, item, column): + QDesktopServices.openUrl(QUrl.fromLocalFile(item.filename)) class TreeResultItem(QTreeWidgetItem): def __init__(self, result): QTreeWidgetItem.__init__(self) - self.filename = result.filename + self.setIcon(0, result.icon) self.setText(0, result.name) + self.filename = result.filename diff --git a/python/plugins/processing/ui/DlgResults.ui b/python/plugins/processing/ui/DlgResults.ui deleted file mode 100644 index b9e6c3917e6..00000000000 --- a/python/plugins/processing/ui/DlgResults.ui +++ /dev/null @@ -1,82 +0,0 @@ - - - DlgResults - - - - 0 - 0 - 623 - 515 - - - - Results - - - - - - Qt::Horizontal - - - - false - - - - 1 - - - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Close - - - - - - - - - buttonBox - accepted() - DlgResults - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - DlgResults - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff --git a/python/plugins/processing/ui/resultsdockbase.ui b/python/plugins/processing/ui/resultsdockbase.ui new file mode 100644 index 00000000000..289c4c03467 --- /dev/null +++ b/python/plugins/processing/ui/resultsdockbase.ui @@ -0,0 +1,56 @@ + + + DockWidget + + + + 0 + 0 + 274 + 303 + + + + Processing results viewer + + + + + + + Qt::Vertical + + + + + 0 + 0 + + + + QAbstractItemView::NoEditTriggers + + + false + + + false + + + false + + + + 1 + + + + + + + + + + + +