Skip to content
Permalink
Browse files

Messy mockup of feature

  • Loading branch information
nyalldawson committed Sep 14, 2018
1 parent 34e29b5 commit 681d44f11fea7286f90efb6c3c4b0eb199ff714c
@@ -44,6 +44,7 @@ Abstract base class for processing algorithms.
FlagRequiresMatchingCrs,
FlagNoThreading,
FlagDisplayNameIsLiteral,
FlagSupportsInPlaceEdits,
FlagDeprecated,
};
typedef QFlags<QgsProcessingAlgorithm::Flag> Flags;
@@ -853,6 +854,9 @@ algorithm in "chains", avoiding the need for temporary outputs in multi-step mod
Constructor for QgsProcessingFeatureBasedAlgorithm.
%End

virtual QgsProcessingAlgorithm::Flags flags() const;


protected:

virtual void initAlgorithm( const QVariantMap &configuration = QVariantMap() );
@@ -379,6 +379,7 @@ the results.
{
FilterToolbox,
FilterModeler,
FilterInPlace,
};
typedef QFlags<QgsProcessingToolboxProxyModel::Filter> Filters;

@@ -417,6 +418,8 @@ Returns any filters that affect how toolbox content is filtered.
.. seealso:: :py:func:`setFilters`
%End

void setInPlaceLayerType( QgsWkbTypes::GeometryType type );

void setFilterString( const QString &filter );
%Docstring
Sets a ``filter`` string, such that only algorithms matching the
@@ -73,6 +73,8 @@ if no algorithm is currently selected.
Sets ``filters`` controlling the view's contents.
%End

void setInPlaceLayerType( QgsWkbTypes::GeometryType type );

public slots:

void setFilterString( const QString &filter );
@@ -35,6 +35,7 @@
QgsDataItemProvider,
QgsDataProvider,
QgsDataItem,
QgsMapLayer,
QgsMimeDataUtils)
from qgis.gui import (QgsOptionsWidgetFactory,
QgsCustomDropHandler)
@@ -48,7 +49,8 @@
from processing.gui.HistoryDialog import HistoryDialog
from processing.gui.ConfigDialog import ConfigOptionsPage
from processing.gui.ResultsDock import ResultsDock
from processing.gui.AlgorithmLocatorFilter import AlgorithmLocatorFilter
from processing.gui.AlgorithmLocatorFilter import (AlgorithmLocatorFilter,
InPlaceAlgorithmLocatorFilter)
from processing.modeler.ModelerDialog import ModelerDialog
from processing.tools.system import tempHelpFolder
from processing.gui.menus import removeMenus, initializeMenus, createMenus
@@ -168,6 +170,8 @@ def __init__(self, iface):
QgsApplication.dataItemProviderRegistry().addProvider(self.item_provider)
self.locator_filter = AlgorithmLocatorFilter()
iface.registerLocatorFilter(self.locator_filter)
self.edit_features_locator_filter = InPlaceAlgorithmLocatorFilter()
iface.registerLocatorFilter(self.edit_features_locator_filter)
Processing.initialize()

def initGui(self):
@@ -233,6 +237,14 @@ def initGui(self):
self.optionsAction.triggered.connect(self.openProcessingOptions)
self.toolbox.processingToolbar.addAction(self.optionsAction)

self.editSelectedAction = QAction(
QgsApplication.getThemeIcon("/mActionToggleEditing.svg"),
self.tr('Edit Selected Features'), self.iface.mainWindow())
self.editSelectedAction.setObjectName('editSelectedFeatures')
self.editSelectedAction.setCheckable(True)
self.editSelectedAction.toggled.connect(self.editSelected)
self.toolbox.processingToolbar.addAction(self.editSelectedAction)

menuBar = self.iface.mainWindow().menuBar()
menuBar.insertMenu(
self.iface.firstRightStandardMenu().menuAction(), self.menu)
@@ -242,6 +254,15 @@ def initGui(self):
initializeMenus()
createMenus()

self.iface.currentLayerChanged.connect(self.layer_changed)

def layer_changed(self, layer):
if layer is None or layer.type() != QgsMapLayer.VectorLayer or not layer.isEditable() or not layer.selectedFeatureCount():
self.editSelectedAction.setChecked(False)
self.editSelectedAction.setEnabled(False)
else:
self.editSelectedAction.setEnabled(True)

def openProcessingOptions(self):
self.iface.showOptionsDialog(self.iface.mainWindow(), currentPage='processingOptions')

@@ -273,6 +294,7 @@ def unload(self):

self.iface.unregisterOptionsWidgetFactory(self.options_factory)
self.iface.deregisterLocatorFilter(self.locator_filter)
self.iface.deregisterLocatorFilter(self.edit_features_locator_filter)
self.iface.unregisterCustomDropHandler(self.drop_handler)
QgsApplication.dataItemProviderRegistry().removeProvider(self.item_provider)

@@ -306,3 +328,6 @@ def openHistory(self):

def tr(self, message):
return QCoreApplication.translate('ProcessingPlugin', message)

def editSelected(self, enabled):
self.toolbox.set_in_place_edit_mode(enabled)
@@ -28,6 +28,7 @@
from qgis.PyQt.QtCore import QVariant
from qgis.core import (QgsField,
QgsProcessing,
QgsProcessingAlgorithm,
QgsProcessingParameterString,
QgsProcessingParameterNumber,
QgsProcessingParameterEnum,
@@ -57,6 +58,9 @@ def __init__(self):
self.tr('String')]
self.field = None

def flags(self):
return super().flags() & ~QgsProcessingAlgorithm.FlagSupportsInPlaceEdits

def initParameters(self, config=None):
self.addParameter(QgsProcessingParameterString(self.FIELD_NAME,
self.tr('Field name')))
@@ -29,6 +29,7 @@

from qgis.core import (QgsProcessingParameterField,
QgsProcessing,
QgsProcessingAlgorithm,
QgsProcessingFeatureSource)
from processing.algs.qgis.QgisAlgorithm import QgisFeatureBasedAlgorithm

@@ -37,6 +38,9 @@ class DeleteColumn(QgisFeatureBasedAlgorithm):

COLUMNS = 'COLUMN'

def flags(self):
return super().flags() & ~QgsProcessingAlgorithm.FlagSupportsInPlaceEdits

def tags(self):
return self.tr('drop,delete,remove,fields,columns,attributes').split(',')

@@ -29,6 +29,7 @@
QgsExpression,
QgsGeometry,
QgsProcessing,
QgsProcessingAlgorithm,
QgsProcessingException,
QgsProcessingParameterBoolean,
QgsProcessingParameterEnum,
@@ -51,6 +52,9 @@ def group(self):
def groupId(self):
return 'vectorgeometry'

def flags(self):
return super().flags() & ~QgsProcessingAlgorithm.FlagSupportsInPlaceEdits

def __init__(self):
super().__init__()
self.geometry_types = [self.tr('Polygon'),
@@ -57,7 +57,7 @@
from processing.gui.ParametersPanel import ParametersPanel
from processing.gui.BatchAlgorithmDialog import BatchAlgorithmDialog
from processing.gui.AlgorithmDialogBase import AlgorithmDialogBase
from processing.gui.AlgorithmExecutor import executeIterating, execute
from processing.gui.AlgorithmExecutor import executeIterating, execute, execute_in_place
from processing.gui.Postprocessing import handleAlgorithmResults
from processing.gui.wrappers import WidgetWrapper

@@ -66,19 +66,25 @@

class AlgorithmDialog(QgsProcessingAlgorithmDialogBase):

def __init__(self, alg):
def __init__(self, alg, in_place=False):
super().__init__()
self.feedback_dialog = None
self.in_place = in_place

self.setAlgorithm(alg)
self.setMainWidget(self.getParametersPanel(alg, self))

self.runAsBatchButton = QPushButton(QCoreApplication.translate("AlgorithmDialog", "Run as Batch Process…"))
self.runAsBatchButton.clicked.connect(self.runAsBatch)
self.buttonBox().addButton(self.runAsBatchButton, QDialogButtonBox.ResetRole) # reset role to ensure left alignment
if not self.in_place:
self.runAsBatchButton = QPushButton(QCoreApplication.translate("AlgorithmDialog", "Run as Batch Process…"))
self.runAsBatchButton.clicked.connect(self.runAsBatch)
self.buttonBox().addButton(self.runAsBatchButton, QDialogButtonBox.ResetRole) # reset role to ensure left alignment
else:
self.runAsBatchButton = None
self.buttonBox().button(QDialogButtonBox.Ok).setText('Modify Selected Features')
self.buttonBox().button(QDialogButtonBox.Close).setText('Cancel')

def getParametersPanel(self, alg, parent):
return ParametersPanel(parent, alg)
return ParametersPanel(parent, alg, self.in_place)

def runAsBatch(self):
self.close()
@@ -118,10 +124,23 @@ def getParameterValues(self):

value = wrapper.parameterValue()
parameters[param.name()] = value
if self.in_place and param.name() == 'INPUT':
parameters[param.name()] = iface.activeLayer()
continue

wrapper = self.mainWidget().wrappers[param.name()]
value = None
if wrapper.widget is not None:
value = wrapper.value()
parameters[param.name()] = value

if not param.checkValueIsAcceptable(value):
raise AlgorithmDialogBase.InvalidParameterValue(param, widget)
else:
if self.in_place and param.name() == 'OUTPUT':
parameters[param.name()] = 'memory:'
continue

dest_project = None
if not param.flags() & QgsProcessingParameterDefinition.FlagHidden and \
isinstance(param, (QgsProcessingParameterRasterDestination,
@@ -226,9 +245,12 @@ def on_complete(ok, results):

self.cancelButton().setEnabled(False)

self.finish(ok, results, context, feedback)
if not self.in_place:
self.finish(ok, results, context, feedback)
elif ok:
self.close()

if not (self.algorithm().flags() & QgsProcessingAlgorithm.FlagNoThreading):
if not self.in_place and not (self.algorithm().flags() & QgsProcessingAlgorithm.FlagNoThreading):
# Make sure the Log tab is visible before executing the algorithm
self.showLog()

@@ -241,7 +263,10 @@ def on_complete(ok, results):
feedback.progressChanged.connect(self.proxy_progress.setProxyProgress)
self.feedback_dialog = self.createProgressDialog()
self.feedback_dialog.show()
ok, results = execute(self.algorithm(), parameters, context, feedback)
if self.in_place:
ok, results = execute_in_place(self.algorithm(), parameters, context, feedback)
else:
ok, results = execute(self.algorithm(), parameters, context, feedback)
feedback.progressChanged.disconnect()
self.proxy_progress.finalize(ok)
on_complete(ok, results)
@@ -33,9 +33,11 @@
QgsProcessingUtils,
QgsMessageLog,
QgsProcessingException,
QgsProcessingFeatureSourceDefinition,
QgsProcessingParameters)
from processing.gui.Postprocessing import handleAlgorithmResults
from processing.tools import dataobjects
from qgis.utils import iface


def execute(alg, parameters, context=None, feedback=None):
@@ -61,6 +63,40 @@ def execute(alg, parameters, context=None, feedback=None):
return False, {}


def execute_in_place(alg, parameters, context=None, feedback=None):

if feedback is None:
feedback = QgsProcessingFeedback()
if context is None:
context = dataobjects.createContext(feedback)

parameters['INPUT'] = QgsProcessingFeatureSourceDefinition(iface.activeLayer().id(), True)

parameters['OUTPUT'] = 'memory:'

try:
results, ok = alg.run(parameters, context, feedback)

layer = QgsProcessingUtils.mapLayerFromString(results['OUTPUT'], context)
iface.activeLayer().beginEditCommand('Edit features')
iface.activeLayer().deleteFeatures(iface.activeLayer().selectedFeatureIds())
features = []
for f in layer.getFeatures():
features.append(f)
iface.activeLayer().addFeatures(features)
new_selection = [f.id() for f in features]
iface.activeLayer().endEditCommand()
#iface.activeLayer().selectByIds(new_selection)
iface.activeLayer().triggerRepaint()

return ok, results
except QgsProcessingException as e:
QgsMessageLog.logMessage(str(sys.exc_info()[0]), 'Processing', Qgis.Critical)
if feedback is not None:
feedback.reportError(e.msg)
return False, {}


def executeIterating(alg, parameters, paramToIter, context, feedback):
# Generate all single-feature layers
parameter_definition = alg.parameterDefinition(paramToIter)

0 comments on commit 681d44f

Please sign in to comment.
You can’t perform that action at this time.