mirror of
https://github.com/qgis/QGIS.git
synced 2025-06-06 00:04:01 -04:00
Messy mockup of feature
This commit is contained in:
parent
34e29b545b
commit
681d44f11f
@ -44,6 +44,7 @@ Abstract base class for processing algorithms.
|
|||||||
FlagRequiresMatchingCrs,
|
FlagRequiresMatchingCrs,
|
||||||
FlagNoThreading,
|
FlagNoThreading,
|
||||||
FlagDisplayNameIsLiteral,
|
FlagDisplayNameIsLiteral,
|
||||||
|
FlagSupportsInPlaceEdits,
|
||||||
FlagDeprecated,
|
FlagDeprecated,
|
||||||
};
|
};
|
||||||
typedef QFlags<QgsProcessingAlgorithm::Flag> Flags;
|
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.
|
Constructor for QgsProcessingFeatureBasedAlgorithm.
|
||||||
%End
|
%End
|
||||||
|
|
||||||
|
virtual QgsProcessingAlgorithm::Flags flags() const;
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual void initAlgorithm( const QVariantMap &configuration = QVariantMap() );
|
virtual void initAlgorithm( const QVariantMap &configuration = QVariantMap() );
|
||||||
|
@ -379,6 +379,7 @@ the results.
|
|||||||
{
|
{
|
||||||
FilterToolbox,
|
FilterToolbox,
|
||||||
FilterModeler,
|
FilterModeler,
|
||||||
|
FilterInPlace,
|
||||||
};
|
};
|
||||||
typedef QFlags<QgsProcessingToolboxProxyModel::Filter> Filters;
|
typedef QFlags<QgsProcessingToolboxProxyModel::Filter> Filters;
|
||||||
|
|
||||||
@ -417,6 +418,8 @@ Returns any filters that affect how toolbox content is filtered.
|
|||||||
.. seealso:: :py:func:`setFilters`
|
.. seealso:: :py:func:`setFilters`
|
||||||
%End
|
%End
|
||||||
|
|
||||||
|
void setInPlaceLayerType( QgsWkbTypes::GeometryType type );
|
||||||
|
|
||||||
void setFilterString( const QString &filter );
|
void setFilterString( const QString &filter );
|
||||||
%Docstring
|
%Docstring
|
||||||
Sets a ``filter`` string, such that only algorithms matching the
|
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.
|
Sets ``filters`` controlling the view's contents.
|
||||||
%End
|
%End
|
||||||
|
|
||||||
|
void setInPlaceLayerType( QgsWkbTypes::GeometryType type );
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
void setFilterString( const QString &filter );
|
void setFilterString( const QString &filter );
|
||||||
|
@ -35,6 +35,7 @@ from qgis.core import (QgsApplication,
|
|||||||
QgsDataItemProvider,
|
QgsDataItemProvider,
|
||||||
QgsDataProvider,
|
QgsDataProvider,
|
||||||
QgsDataItem,
|
QgsDataItem,
|
||||||
|
QgsMapLayer,
|
||||||
QgsMimeDataUtils)
|
QgsMimeDataUtils)
|
||||||
from qgis.gui import (QgsOptionsWidgetFactory,
|
from qgis.gui import (QgsOptionsWidgetFactory,
|
||||||
QgsCustomDropHandler)
|
QgsCustomDropHandler)
|
||||||
@ -48,7 +49,8 @@ from processing.gui.ProcessingToolbox import ProcessingToolbox
|
|||||||
from processing.gui.HistoryDialog import HistoryDialog
|
from processing.gui.HistoryDialog import HistoryDialog
|
||||||
from processing.gui.ConfigDialog import ConfigOptionsPage
|
from processing.gui.ConfigDialog import ConfigOptionsPage
|
||||||
from processing.gui.ResultsDock import ResultsDock
|
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.modeler.ModelerDialog import ModelerDialog
|
||||||
from processing.tools.system import tempHelpFolder
|
from processing.tools.system import tempHelpFolder
|
||||||
from processing.gui.menus import removeMenus, initializeMenus, createMenus
|
from processing.gui.menus import removeMenus, initializeMenus, createMenus
|
||||||
@ -168,6 +170,8 @@ class ProcessingPlugin:
|
|||||||
QgsApplication.dataItemProviderRegistry().addProvider(self.item_provider)
|
QgsApplication.dataItemProviderRegistry().addProvider(self.item_provider)
|
||||||
self.locator_filter = AlgorithmLocatorFilter()
|
self.locator_filter = AlgorithmLocatorFilter()
|
||||||
iface.registerLocatorFilter(self.locator_filter)
|
iface.registerLocatorFilter(self.locator_filter)
|
||||||
|
self.edit_features_locator_filter = InPlaceAlgorithmLocatorFilter()
|
||||||
|
iface.registerLocatorFilter(self.edit_features_locator_filter)
|
||||||
Processing.initialize()
|
Processing.initialize()
|
||||||
|
|
||||||
def initGui(self):
|
def initGui(self):
|
||||||
@ -233,6 +237,14 @@ class ProcessingPlugin:
|
|||||||
self.optionsAction.triggered.connect(self.openProcessingOptions)
|
self.optionsAction.triggered.connect(self.openProcessingOptions)
|
||||||
self.toolbox.processingToolbar.addAction(self.optionsAction)
|
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 = self.iface.mainWindow().menuBar()
|
||||||
menuBar.insertMenu(
|
menuBar.insertMenu(
|
||||||
self.iface.firstRightStandardMenu().menuAction(), self.menu)
|
self.iface.firstRightStandardMenu().menuAction(), self.menu)
|
||||||
@ -242,6 +254,15 @@ class ProcessingPlugin:
|
|||||||
initializeMenus()
|
initializeMenus()
|
||||||
createMenus()
|
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):
|
def openProcessingOptions(self):
|
||||||
self.iface.showOptionsDialog(self.iface.mainWindow(), currentPage='processingOptions')
|
self.iface.showOptionsDialog(self.iface.mainWindow(), currentPage='processingOptions')
|
||||||
|
|
||||||
@ -273,6 +294,7 @@ class ProcessingPlugin:
|
|||||||
|
|
||||||
self.iface.unregisterOptionsWidgetFactory(self.options_factory)
|
self.iface.unregisterOptionsWidgetFactory(self.options_factory)
|
||||||
self.iface.deregisterLocatorFilter(self.locator_filter)
|
self.iface.deregisterLocatorFilter(self.locator_filter)
|
||||||
|
self.iface.deregisterLocatorFilter(self.edit_features_locator_filter)
|
||||||
self.iface.unregisterCustomDropHandler(self.drop_handler)
|
self.iface.unregisterCustomDropHandler(self.drop_handler)
|
||||||
QgsApplication.dataItemProviderRegistry().removeProvider(self.item_provider)
|
QgsApplication.dataItemProviderRegistry().removeProvider(self.item_provider)
|
||||||
|
|
||||||
@ -306,3 +328,6 @@ class ProcessingPlugin:
|
|||||||
|
|
||||||
def tr(self, message):
|
def tr(self, message):
|
||||||
return QCoreApplication.translate('ProcessingPlugin', message)
|
return QCoreApplication.translate('ProcessingPlugin', message)
|
||||||
|
|
||||||
|
def editSelected(self, enabled):
|
||||||
|
self.toolbox.set_in_place_edit_mode(enabled)
|
||||||
|
@ -28,6 +28,7 @@ __revision__ = '$Format:%H$'
|
|||||||
from qgis.PyQt.QtCore import QVariant
|
from qgis.PyQt.QtCore import QVariant
|
||||||
from qgis.core import (QgsField,
|
from qgis.core import (QgsField,
|
||||||
QgsProcessing,
|
QgsProcessing,
|
||||||
|
QgsProcessingAlgorithm,
|
||||||
QgsProcessingParameterString,
|
QgsProcessingParameterString,
|
||||||
QgsProcessingParameterNumber,
|
QgsProcessingParameterNumber,
|
||||||
QgsProcessingParameterEnum,
|
QgsProcessingParameterEnum,
|
||||||
@ -57,6 +58,9 @@ class AddTableField(QgisFeatureBasedAlgorithm):
|
|||||||
self.tr('String')]
|
self.tr('String')]
|
||||||
self.field = None
|
self.field = None
|
||||||
|
|
||||||
|
def flags(self):
|
||||||
|
return super().flags() & ~QgsProcessingAlgorithm.FlagSupportsInPlaceEdits
|
||||||
|
|
||||||
def initParameters(self, config=None):
|
def initParameters(self, config=None):
|
||||||
self.addParameter(QgsProcessingParameterString(self.FIELD_NAME,
|
self.addParameter(QgsProcessingParameterString(self.FIELD_NAME,
|
||||||
self.tr('Field name')))
|
self.tr('Field name')))
|
||||||
|
@ -29,6 +29,7 @@ from qgis.PyQt.QtCore import QCoreApplication
|
|||||||
|
|
||||||
from qgis.core import (QgsProcessingParameterField,
|
from qgis.core import (QgsProcessingParameterField,
|
||||||
QgsProcessing,
|
QgsProcessing,
|
||||||
|
QgsProcessingAlgorithm,
|
||||||
QgsProcessingFeatureSource)
|
QgsProcessingFeatureSource)
|
||||||
from processing.algs.qgis.QgisAlgorithm import QgisFeatureBasedAlgorithm
|
from processing.algs.qgis.QgisAlgorithm import QgisFeatureBasedAlgorithm
|
||||||
|
|
||||||
@ -37,6 +38,9 @@ class DeleteColumn(QgisFeatureBasedAlgorithm):
|
|||||||
|
|
||||||
COLUMNS = 'COLUMN'
|
COLUMNS = 'COLUMN'
|
||||||
|
|
||||||
|
def flags(self):
|
||||||
|
return super().flags() & ~QgsProcessingAlgorithm.FlagSupportsInPlaceEdits
|
||||||
|
|
||||||
def tags(self):
|
def tags(self):
|
||||||
return self.tr('drop,delete,remove,fields,columns,attributes').split(',')
|
return self.tr('drop,delete,remove,fields,columns,attributes').split(',')
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ from qgis.core import (QgsWkbTypes,
|
|||||||
QgsExpression,
|
QgsExpression,
|
||||||
QgsGeometry,
|
QgsGeometry,
|
||||||
QgsProcessing,
|
QgsProcessing,
|
||||||
|
QgsProcessingAlgorithm,
|
||||||
QgsProcessingException,
|
QgsProcessingException,
|
||||||
QgsProcessingParameterBoolean,
|
QgsProcessingParameterBoolean,
|
||||||
QgsProcessingParameterEnum,
|
QgsProcessingParameterEnum,
|
||||||
@ -51,6 +52,9 @@ class GeometryByExpression(QgisFeatureBasedAlgorithm):
|
|||||||
def groupId(self):
|
def groupId(self):
|
||||||
return 'vectorgeometry'
|
return 'vectorgeometry'
|
||||||
|
|
||||||
|
def flags(self):
|
||||||
|
return super().flags() & ~QgsProcessingAlgorithm.FlagSupportsInPlaceEdits
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.geometry_types = [self.tr('Polygon'),
|
self.geometry_types = [self.tr('Polygon'),
|
||||||
|
@ -57,7 +57,7 @@ from processing.core.ProcessingResults import resultsList
|
|||||||
from processing.gui.ParametersPanel import ParametersPanel
|
from processing.gui.ParametersPanel import ParametersPanel
|
||||||
from processing.gui.BatchAlgorithmDialog import BatchAlgorithmDialog
|
from processing.gui.BatchAlgorithmDialog import BatchAlgorithmDialog
|
||||||
from processing.gui.AlgorithmDialogBase import AlgorithmDialogBase
|
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.Postprocessing import handleAlgorithmResults
|
||||||
from processing.gui.wrappers import WidgetWrapper
|
from processing.gui.wrappers import WidgetWrapper
|
||||||
|
|
||||||
@ -66,19 +66,25 @@ from processing.tools import dataobjects
|
|||||||
|
|
||||||
class AlgorithmDialog(QgsProcessingAlgorithmDialogBase):
|
class AlgorithmDialog(QgsProcessingAlgorithmDialogBase):
|
||||||
|
|
||||||
def __init__(self, alg):
|
def __init__(self, alg, in_place=False):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.feedback_dialog = None
|
self.feedback_dialog = None
|
||||||
|
self.in_place = in_place
|
||||||
|
|
||||||
self.setAlgorithm(alg)
|
self.setAlgorithm(alg)
|
||||||
self.setMainWidget(self.getParametersPanel(alg, self))
|
self.setMainWidget(self.getParametersPanel(alg, self))
|
||||||
|
|
||||||
self.runAsBatchButton = QPushButton(QCoreApplication.translate("AlgorithmDialog", "Run as Batch Process…"))
|
if not self.in_place:
|
||||||
self.runAsBatchButton.clicked.connect(self.runAsBatch)
|
self.runAsBatchButton = QPushButton(QCoreApplication.translate("AlgorithmDialog", "Run as Batch Process…"))
|
||||||
self.buttonBox().addButton(self.runAsBatchButton, QDialogButtonBox.ResetRole) # reset role to ensure left alignment
|
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):
|
def getParametersPanel(self, alg, parent):
|
||||||
return ParametersPanel(parent, alg)
|
return ParametersPanel(parent, alg, self.in_place)
|
||||||
|
|
||||||
def runAsBatch(self):
|
def runAsBatch(self):
|
||||||
self.close()
|
self.close()
|
||||||
@ -118,10 +124,23 @@ class AlgorithmDialog(QgsProcessingAlgorithmDialogBase):
|
|||||||
|
|
||||||
value = wrapper.parameterValue()
|
value = wrapper.parameterValue()
|
||||||
parameters[param.name()] = value
|
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):
|
if not param.checkValueIsAcceptable(value):
|
||||||
raise AlgorithmDialogBase.InvalidParameterValue(param, widget)
|
raise AlgorithmDialogBase.InvalidParameterValue(param, widget)
|
||||||
else:
|
else:
|
||||||
|
if self.in_place and param.name() == 'OUTPUT':
|
||||||
|
parameters[param.name()] = 'memory:'
|
||||||
|
continue
|
||||||
|
|
||||||
dest_project = None
|
dest_project = None
|
||||||
if not param.flags() & QgsProcessingParameterDefinition.FlagHidden and \
|
if not param.flags() & QgsProcessingParameterDefinition.FlagHidden and \
|
||||||
isinstance(param, (QgsProcessingParameterRasterDestination,
|
isinstance(param, (QgsProcessingParameterRasterDestination,
|
||||||
@ -226,9 +245,12 @@ class AlgorithmDialog(QgsProcessingAlgorithmDialogBase):
|
|||||||
|
|
||||||
self.cancelButton().setEnabled(False)
|
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
|
# Make sure the Log tab is visible before executing the algorithm
|
||||||
self.showLog()
|
self.showLog()
|
||||||
|
|
||||||
@ -241,7 +263,10 @@ class AlgorithmDialog(QgsProcessingAlgorithmDialogBase):
|
|||||||
feedback.progressChanged.connect(self.proxy_progress.setProxyProgress)
|
feedback.progressChanged.connect(self.proxy_progress.setProxyProgress)
|
||||||
self.feedback_dialog = self.createProgressDialog()
|
self.feedback_dialog = self.createProgressDialog()
|
||||||
self.feedback_dialog.show()
|
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()
|
feedback.progressChanged.disconnect()
|
||||||
self.proxy_progress.finalize(ok)
|
self.proxy_progress.finalize(ok)
|
||||||
on_complete(ok, results)
|
on_complete(ok, results)
|
||||||
|
@ -33,9 +33,11 @@ from qgis.core import (Qgis,
|
|||||||
QgsProcessingUtils,
|
QgsProcessingUtils,
|
||||||
QgsMessageLog,
|
QgsMessageLog,
|
||||||
QgsProcessingException,
|
QgsProcessingException,
|
||||||
|
QgsProcessingFeatureSourceDefinition,
|
||||||
QgsProcessingParameters)
|
QgsProcessingParameters)
|
||||||
from processing.gui.Postprocessing import handleAlgorithmResults
|
from processing.gui.Postprocessing import handleAlgorithmResults
|
||||||
from processing.tools import dataobjects
|
from processing.tools import dataobjects
|
||||||
|
from qgis.utils import iface
|
||||||
|
|
||||||
|
|
||||||
def execute(alg, parameters, context=None, feedback=None):
|
def execute(alg, parameters, context=None, feedback=None):
|
||||||
@ -61,6 +63,40 @@ def execute(alg, parameters, context=None, feedback=None):
|
|||||||
return False, {}
|
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):
|
def executeIterating(alg, parameters, paramToIter, context, feedback):
|
||||||
# Generate all single-feature layers
|
# Generate all single-feature layers
|
||||||
parameter_definition = alg.parameterDefinition(paramToIter)
|
parameter_definition = alg.parameterDefinition(paramToIter)
|
||||||
|
@ -28,10 +28,16 @@ __revision__ = '$Format:%H$'
|
|||||||
|
|
||||||
from qgis.core import (QgsApplication,
|
from qgis.core import (QgsApplication,
|
||||||
QgsProcessingAlgorithm,
|
QgsProcessingAlgorithm,
|
||||||
|
QgsProcessingFeatureBasedAlgorithm,
|
||||||
QgsLocatorFilter,
|
QgsLocatorFilter,
|
||||||
QgsLocatorResult)
|
QgsLocatorResult,
|
||||||
|
QgsProcessing,
|
||||||
|
QgsWkbTypes,
|
||||||
|
QgsMapLayer,
|
||||||
|
QgsFields)
|
||||||
from processing.gui.MessageDialog import MessageDialog
|
from processing.gui.MessageDialog import MessageDialog
|
||||||
from processing.gui.AlgorithmDialog import AlgorithmDialog
|
from processing.gui.AlgorithmDialog import AlgorithmDialog
|
||||||
|
from processing.gui.AlgorithmExecutor import execute_in_place
|
||||||
from qgis.utils import iface
|
from qgis.utils import iface
|
||||||
|
|
||||||
|
|
||||||
@ -101,3 +107,91 @@ class AlgorithmLocatorFilter(QgsLocatorFilter):
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
canvas.setMapTool(prevMapTool)
|
canvas.setMapTool(prevMapTool)
|
||||||
|
|
||||||
|
|
||||||
|
class InPlaceAlgorithmLocatorFilter(QgsLocatorFilter):
|
||||||
|
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
super().__init__(parent)
|
||||||
|
|
||||||
|
def clone(self):
|
||||||
|
return InPlaceAlgorithmLocatorFilter()
|
||||||
|
|
||||||
|
def name(self):
|
||||||
|
return 'edit_features'
|
||||||
|
|
||||||
|
def displayName(self):
|
||||||
|
return self.tr('Edit Selected Features')
|
||||||
|
|
||||||
|
def priority(self):
|
||||||
|
return QgsLocatorFilter.Low
|
||||||
|
|
||||||
|
def prefix(self):
|
||||||
|
return 'ef'
|
||||||
|
|
||||||
|
def flags(self):
|
||||||
|
return QgsLocatorFilter.FlagFast
|
||||||
|
|
||||||
|
def fetchResults(self, string, context, feedback):
|
||||||
|
# collect results in main thread, since this method is inexpensive and
|
||||||
|
# accessing the processing registry/current layer is not thread safe
|
||||||
|
|
||||||
|
if iface.activeLayer() is None or iface.activeLayer().type() != QgsMapLayer.VectorLayer or not iface.activeLayer().selectedFeatureCount():
|
||||||
|
return
|
||||||
|
|
||||||
|
for a in QgsApplication.processingRegistry().algorithms():
|
||||||
|
if not a.flags() & QgsProcessingAlgorithm.FlagSupportsInPlaceEdits:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if a.inputLayerTypes() and \
|
||||||
|
QgsProcessing.TypeVector not in a.inputLayerTypes() \
|
||||||
|
and QgsProcessing.TypeVectorAnyGeometry not in a.inputLayerTypes() \
|
||||||
|
and (QgsWkbTypes.geometryType(iface.activeLayer().wkbType()) == QgsWkbTypes.PolygonGeometry and QgsProcessing.TypeVectorPolygon not in a.inputLayerTypes() or
|
||||||
|
QgsWkbTypes.geometryType(
|
||||||
|
iface.activeLayer().wkbType()) == QgsWkbTypes.LineGeometry and QgsProcessing.TypeVectorLine not in a.inputLayerTypes() or
|
||||||
|
QgsWkbTypes.geometryType(
|
||||||
|
iface.activeLayer().wkbType()) == QgsWkbTypes.PointGeometry and QgsProcessing.TypeVectorPoint not in a.inputLayerTypes()):
|
||||||
|
continue
|
||||||
|
|
||||||
|
if QgsLocatorFilter.stringMatches(a.displayName(), string) or [t for t in a.tags() if QgsLocatorFilter.stringMatches(t, string)] or \
|
||||||
|
(context.usingPrefix and not string):
|
||||||
|
result = QgsLocatorResult()
|
||||||
|
result.filter = self
|
||||||
|
result.displayString = a.displayName()
|
||||||
|
result.icon = a.icon()
|
||||||
|
result.userData = a.id()
|
||||||
|
if string and QgsLocatorFilter.stringMatches(a.displayName(), string):
|
||||||
|
result.score = float(len(string)) / len(a.displayName())
|
||||||
|
else:
|
||||||
|
result.score = 0
|
||||||
|
self.resultFetched.emit(result)
|
||||||
|
|
||||||
|
def triggerResult(self, result):
|
||||||
|
alg = QgsApplication.processingRegistry().createAlgorithmById(result.userData)
|
||||||
|
if alg:
|
||||||
|
ok, message = alg.canExecute()
|
||||||
|
if not ok:
|
||||||
|
dlg = MessageDialog()
|
||||||
|
dlg.setTitle(self.tr('Missing dependency'))
|
||||||
|
dlg.setMessage(message)
|
||||||
|
dlg.exec_()
|
||||||
|
return
|
||||||
|
|
||||||
|
if len(alg.parameterDefinitions()) > 2:
|
||||||
|
# hack!!
|
||||||
|
dlg = alg.createCustomParametersWidget(None)
|
||||||
|
if not dlg:
|
||||||
|
dlg = AlgorithmDialog(alg, True)
|
||||||
|
canvas = iface.mapCanvas()
|
||||||
|
prevMapTool = canvas.mapTool()
|
||||||
|
dlg.show()
|
||||||
|
dlg.exec_()
|
||||||
|
if canvas.mapTool() != prevMapTool:
|
||||||
|
try:
|
||||||
|
canvas.mapTool().reset()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
canvas.setMapTool(prevMapTool)
|
||||||
|
else:
|
||||||
|
parameters = {}
|
||||||
|
execute_in_place(alg, parameters)
|
||||||
|
@ -66,9 +66,10 @@ class ParametersPanel(BASE, WIDGET):
|
|||||||
|
|
||||||
NOT_SELECTED = QCoreApplication.translate('ParametersPanel', '[Not selected]')
|
NOT_SELECTED = QCoreApplication.translate('ParametersPanel', '[Not selected]')
|
||||||
|
|
||||||
def __init__(self, parent, alg):
|
def __init__(self, parent, alg, in_place=False):
|
||||||
super(ParametersPanel, self).__init__(None)
|
super(ParametersPanel, self).__init__(None)
|
||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
|
self.in_place = in_place
|
||||||
|
|
||||||
self.grpAdvanced.hide()
|
self.grpAdvanced.hide()
|
||||||
|
|
||||||
@ -126,6 +127,9 @@ class ParametersPanel(BASE, WIDGET):
|
|||||||
if param.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
if param.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if self.in_place and param.name() in ('INPUT', 'OUTPUT'):
|
||||||
|
continue
|
||||||
|
|
||||||
if param.isDestination():
|
if param.isDestination():
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
@ -196,6 +200,9 @@ class ParametersPanel(BASE, WIDGET):
|
|||||||
if output.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
if output.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if self.in_place and param.name() in ('INPUT', 'OUTPUT'):
|
||||||
|
continue
|
||||||
|
|
||||||
label = QLabel(output.description())
|
label = QLabel(output.description())
|
||||||
widget = DestinationSelectionPanel(output, self.alg)
|
widget = DestinationSelectionPanel(output, self.alg)
|
||||||
self.layoutMain.insertWidget(self.layoutMain.count() - 1, label)
|
self.layoutMain.insertWidget(self.layoutMain.count() - 1, label)
|
||||||
|
@ -33,7 +33,9 @@ from qgis.PyQt import uic
|
|||||||
from qgis.PyQt.QtCore import Qt, QCoreApplication
|
from qgis.PyQt.QtCore import Qt, QCoreApplication
|
||||||
from qgis.PyQt.QtWidgets import QToolButton, QMenu, QAction
|
from qgis.PyQt.QtWidgets import QToolButton, QMenu, QAction
|
||||||
from qgis.utils import iface
|
from qgis.utils import iface
|
||||||
from qgis.core import (QgsApplication,
|
from qgis.core import (QgsWkbTypes,
|
||||||
|
QgsMapLayer,
|
||||||
|
QgsApplication,
|
||||||
QgsProcessingAlgorithm)
|
QgsProcessingAlgorithm)
|
||||||
from qgis.gui import (QgsGui,
|
from qgis.gui import (QgsGui,
|
||||||
QgsDockWidget,
|
QgsDockWidget,
|
||||||
@ -50,6 +52,7 @@ from processing.gui.AlgorithmExecutor import execute
|
|||||||
from processing.gui.ProviderActions import (ProviderActions,
|
from processing.gui.ProviderActions import (ProviderActions,
|
||||||
ProviderContextMenuActions)
|
ProviderContextMenuActions)
|
||||||
from processing.tools import dataobjects
|
from processing.tools import dataobjects
|
||||||
|
from processing.gui.AlgorithmExecutor import execute_in_place
|
||||||
|
|
||||||
pluginPath = os.path.split(os.path.dirname(__file__))[0]
|
pluginPath = os.path.split(os.path.dirname(__file__))[0]
|
||||||
|
|
||||||
@ -71,6 +74,7 @@ class ProcessingToolbox(QgsDockWidget, WIDGET):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(ProcessingToolbox, self).__init__(None)
|
super(ProcessingToolbox, self).__init__(None)
|
||||||
self.tipWasClosed = False
|
self.tipWasClosed = False
|
||||||
|
self.in_place_mode = False
|
||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
self.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
|
self.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
|
||||||
self.processingToolbar.setIconSize(iface.iconSize(True))
|
self.processingToolbar.setIconSize(iface.iconSize(True))
|
||||||
@ -108,6 +112,20 @@ class ProcessingToolbox(QgsDockWidget, WIDGET):
|
|||||||
QgsApplication.processingRegistry().providerRemoved.connect(self.addProvider)
|
QgsApplication.processingRegistry().providerRemoved.connect(self.addProvider)
|
||||||
QgsApplication.processingRegistry().providerRemoved.connect(self.removeProvider)
|
QgsApplication.processingRegistry().providerRemoved.connect(self.removeProvider)
|
||||||
|
|
||||||
|
iface.currentLayerChanged.connect(self.layer_changed)
|
||||||
|
|
||||||
|
def set_in_place_edit_mode(self, enabled):
|
||||||
|
if enabled:
|
||||||
|
self.algorithmTree.setFilters(QgsProcessingToolboxProxyModel.Filters(QgsProcessingToolboxProxyModel.FilterToolbox | QgsProcessingToolboxProxyModel.FilterInPlace))
|
||||||
|
else:
|
||||||
|
self.algorithmTree.setFilters(QgsProcessingToolboxProxyModel.FilterToolbox)
|
||||||
|
self.in_place_mode = enabled
|
||||||
|
|
||||||
|
def layer_changed(self, layer):
|
||||||
|
if layer is None or layer.type() != QgsMapLayer.VectorLayer:
|
||||||
|
return
|
||||||
|
self.algorithmTree.setInPlaceLayerType(QgsWkbTypes.geometryType(layer.wkbType()))
|
||||||
|
|
||||||
def disabledProviders(self):
|
def disabledProviders(self):
|
||||||
showTip = ProcessingConfig.getSetting(ProcessingConfig.SHOW_PROVIDERS_TOOLTIP)
|
showTip = ProcessingConfig.getSetting(ProcessingConfig.SHOW_PROVIDERS_TOOLTIP)
|
||||||
if not showTip or self.tipWasClosed:
|
if not showTip or self.tipWasClosed:
|
||||||
@ -211,11 +229,17 @@ class ProcessingToolbox(QgsDockWidget, WIDGET):
|
|||||||
dlg.exec_()
|
dlg.exec_()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if self.in_place_mode and len(alg.parameterDefinitions()) <= 2:
|
||||||
|
# hack
|
||||||
|
parameters = {}
|
||||||
|
execute_in_place(alg, parameters)
|
||||||
|
return
|
||||||
|
|
||||||
if alg.countVisibleParameters() > 0:
|
if alg.countVisibleParameters() > 0:
|
||||||
dlg = alg.createCustomParametersWidget(self)
|
dlg = alg.createCustomParametersWidget(self)
|
||||||
|
|
||||||
if not dlg:
|
if not dlg:
|
||||||
dlg = AlgorithmDialog(alg)
|
dlg = AlgorithmDialog(alg, self.in_place_mode)
|
||||||
canvas = iface.mapCanvas()
|
canvas = iface.mapCanvas()
|
||||||
prevMapTool = canvas.mapTool()
|
prevMapTool = canvas.mapTool()
|
||||||
dlg.show()
|
dlg.show()
|
||||||
|
@ -29,6 +29,7 @@ const QList<QString> QgsLocator::CORE_FILTERS = QList<QString>() << QStringLiter
|
|||||||
<< QStringLiteral( "calculator" )
|
<< QStringLiteral( "calculator" )
|
||||||
<< QStringLiteral( "bookmarks" )
|
<< QStringLiteral( "bookmarks" )
|
||||||
<< QStringLiteral( "optionpages" );
|
<< QStringLiteral( "optionpages" );
|
||||||
|
<< QStringLiteral( "edit_features" );
|
||||||
|
|
||||||
QgsLocator::QgsLocator( QObject *parent )
|
QgsLocator::QgsLocator( QObject *parent )
|
||||||
: QObject( parent )
|
: QObject( parent )
|
||||||
|
@ -787,6 +787,13 @@ bool QgsProcessingAlgorithm::createAutoOutputForParameter( QgsProcessingParamete
|
|||||||
// QgsProcessingFeatureBasedAlgorithm
|
// QgsProcessingFeatureBasedAlgorithm
|
||||||
//
|
//
|
||||||
|
|
||||||
|
QgsProcessingAlgorithm::Flags QgsProcessingFeatureBasedAlgorithm::flags() const
|
||||||
|
{
|
||||||
|
Flags f = QgsProcessingAlgorithm::flags();
|
||||||
|
f |= QgsProcessingAlgorithm::FlagSupportsInPlaceEdits;
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
void QgsProcessingFeatureBasedAlgorithm::initAlgorithm( const QVariantMap &config )
|
void QgsProcessingFeatureBasedAlgorithm::initAlgorithm( const QVariantMap &config )
|
||||||
{
|
{
|
||||||
addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ), QObject::tr( "Input layer" ), inputLayerTypes() ) );
|
addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ), QObject::tr( "Input layer" ), inputLayerTypes() ) );
|
||||||
|
@ -74,6 +74,7 @@ class CORE_EXPORT QgsProcessingAlgorithm
|
|||||||
FlagRequiresMatchingCrs = 1 << 5, //!< Algorithm requires that all input layers have matching coordinate reference systems
|
FlagRequiresMatchingCrs = 1 << 5, //!< Algorithm requires that all input layers have matching coordinate reference systems
|
||||||
FlagNoThreading = 1 << 6, //!< Algorithm is not thread safe and cannot be run in a background thread, e.g. for algorithms which manipulate the current project, layer selections, or with external dependencies which are not thread-safe.
|
FlagNoThreading = 1 << 6, //!< Algorithm is not thread safe and cannot be run in a background thread, e.g. for algorithms which manipulate the current project, layer selections, or with external dependencies which are not thread-safe.
|
||||||
FlagDisplayNameIsLiteral = 1 << 7, //!< Algorithm's display name is a static literal string, and should not be translated or automatically formatted. For use with algorithms named after commands, e.g. GRASS 'v.in.ogr'.
|
FlagDisplayNameIsLiteral = 1 << 7, //!< Algorithm's display name is a static literal string, and should not be translated or automatically formatted. For use with algorithms named after commands, e.g. GRASS 'v.in.ogr'.
|
||||||
|
FlagSupportsInPlaceEdits = 1 << 8, //!< Algorithm supports in-place editing
|
||||||
FlagDeprecated = FlagHideFromToolbox | FlagHideFromModeler, //!< Algorithm is deprecated
|
FlagDeprecated = FlagHideFromToolbox | FlagHideFromModeler, //!< Algorithm is deprecated
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS( Flags, Flag )
|
Q_DECLARE_FLAGS( Flags, Flag )
|
||||||
@ -861,6 +862,8 @@ class CORE_EXPORT QgsProcessingFeatureBasedAlgorithm : public QgsProcessingAlgor
|
|||||||
*/
|
*/
|
||||||
QgsProcessingFeatureBasedAlgorithm() = default;
|
QgsProcessingFeatureBasedAlgorithm() = default;
|
||||||
|
|
||||||
|
QgsProcessingAlgorithm::Flags flags() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void initAlgorithm( const QVariantMap &configuration = QVariantMap() ) override;
|
void initAlgorithm( const QVariantMap &configuration = QVariantMap() ) override;
|
||||||
@ -970,6 +973,7 @@ class CORE_EXPORT QgsProcessingFeatureBasedAlgorithm : public QgsProcessingAlgor
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
std::unique_ptr< QgsProcessingFeatureSource > mSource;
|
std::unique_ptr< QgsProcessingFeatureSource > mSource;
|
||||||
|
friend class QgsProcessingToolboxProxyModel;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -655,6 +655,12 @@ void QgsProcessingToolboxProxyModel::setFilters( QgsProcessingToolboxProxyModel:
|
|||||||
invalidateFilter();
|
invalidateFilter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QgsProcessingToolboxProxyModel::setInPlaceLayerType( QgsWkbTypes::GeometryType type )
|
||||||
|
{
|
||||||
|
mInPlaceGeometryType = type;
|
||||||
|
invalidateFilter();
|
||||||
|
}
|
||||||
|
|
||||||
void QgsProcessingToolboxProxyModel::setFilterString( const QString &filter )
|
void QgsProcessingToolboxProxyModel::setFilterString( const QString &filter )
|
||||||
{
|
{
|
||||||
mFilterString = filter;
|
mFilterString = filter;
|
||||||
@ -708,6 +714,32 @@ bool QgsProcessingToolboxProxyModel::filterAcceptsRow( int sourceRow, const QMod
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( mFilters & FilterInPlace )
|
||||||
|
{
|
||||||
|
const bool supportsInPlace = sourceModel()->data( sourceIndex, QgsProcessingToolboxModel::RoleAlgorithmFlags ).toInt() & QgsProcessingAlgorithm::FlagSupportsInPlaceEdits;
|
||||||
|
if ( !supportsInPlace )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const QgsProcessingFeatureBasedAlgorithm *alg = dynamic_cast< const QgsProcessingFeatureBasedAlgorithm * >( mModel->algorithmForIndex( sourceIndex ) );
|
||||||
|
|
||||||
|
if ( !alg->inputLayerTypes().empty() &&
|
||||||
|
!alg->inputLayerTypes().contains( QgsProcessing::TypeVector ) &&
|
||||||
|
!alg->inputLayerTypes().contains( QgsProcessing::TypeVectorAnyGeometry ) &&
|
||||||
|
( ( mInPlaceGeometryType == QgsWkbTypes::PolygonGeometry && !alg->inputLayerTypes().contains( QgsProcessing::TypeVectorPolygon ) ) ||
|
||||||
|
( mInPlaceGeometryType == QgsWkbTypes::LineGeometry && !alg->inputLayerTypes().contains( QgsProcessing::TypeVectorLine ) ) ||
|
||||||
|
( mInPlaceGeometryType == QgsWkbTypes::PointGeometry && !alg->inputLayerTypes().contains( QgsProcessing::TypeVectorPoint ) ) ) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QgsWkbTypes::Type type = QgsWkbTypes::Unknown;
|
||||||
|
if ( mInPlaceGeometryType == QgsWkbTypes::PointGeometry )
|
||||||
|
type = QgsWkbTypes::Point;
|
||||||
|
else if ( mInPlaceGeometryType == QgsWkbTypes::LineGeometry )
|
||||||
|
type = QgsWkbTypes::LineString;
|
||||||
|
else if ( mInPlaceGeometryType == QgsWkbTypes::PolygonGeometry )
|
||||||
|
type = QgsWkbTypes::Polygon;
|
||||||
|
if ( QgsWkbTypes::geometryType( alg->outputWkbType( type ) ) != mInPlaceGeometryType )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if ( mFilters & FilterModeler )
|
if ( mFilters & FilterModeler )
|
||||||
{
|
{
|
||||||
bool isHiddenFromModeler = sourceModel()->data( sourceIndex, QgsProcessingToolboxModel::RoleAlgorithmFlags ).toInt() & QgsProcessingAlgorithm::FlagHideFromModeler;
|
bool isHiddenFromModeler = sourceModel()->data( sourceIndex, QgsProcessingToolboxModel::RoleAlgorithmFlags ).toInt() & QgsProcessingAlgorithm::FlagHideFromModeler;
|
||||||
|
@ -423,6 +423,7 @@ class GUI_EXPORT QgsProcessingToolboxProxyModel: public QSortFilterProxyModel
|
|||||||
{
|
{
|
||||||
FilterToolbox = 1 << 1, //!< Filters out any algorithms and content which should not be shown in the toolbox
|
FilterToolbox = 1 << 1, //!< Filters out any algorithms and content which should not be shown in the toolbox
|
||||||
FilterModeler = 1 << 2, //!< Filters out any algorithms and content which should not be shown in the modeler
|
FilterModeler = 1 << 2, //!< Filters out any algorithms and content which should not be shown in the modeler
|
||||||
|
FilterInPlace = 1 << 3, //!< Only show algorithms which support in-place edits
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS( Filters, Filter )
|
Q_DECLARE_FLAGS( Filters, Filter )
|
||||||
Q_FLAG( Filters )
|
Q_FLAG( Filters )
|
||||||
@ -459,6 +460,8 @@ class GUI_EXPORT QgsProcessingToolboxProxyModel: public QSortFilterProxyModel
|
|||||||
*/
|
*/
|
||||||
Filters filters() const { return mFilters; }
|
Filters filters() const { return mFilters; }
|
||||||
|
|
||||||
|
void setInPlaceLayerType( QgsWkbTypes::GeometryType type );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a \a filter string, such that only algorithms matching the
|
* Sets a \a filter string, such that only algorithms matching the
|
||||||
* specified string will be shown.
|
* specified string will be shown.
|
||||||
@ -485,6 +488,7 @@ class GUI_EXPORT QgsProcessingToolboxProxyModel: public QSortFilterProxyModel
|
|||||||
QgsProcessingToolboxModel *mModel = nullptr;
|
QgsProcessingToolboxModel *mModel = nullptr;
|
||||||
Filters mFilters = nullptr;
|
Filters mFilters = nullptr;
|
||||||
QString mFilterString;
|
QString mFilterString;
|
||||||
|
QgsWkbTypes::GeometryType mInPlaceGeometryType = QgsWkbTypes::UnknownGeometry;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -93,6 +93,11 @@ void QgsProcessingToolboxTreeView::setFilters( QgsProcessingToolboxProxyModel::F
|
|||||||
mModel->setFilters( filters );
|
mModel->setFilters( filters );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QgsProcessingToolboxTreeView::setInPlaceLayerType( QgsWkbTypes::GeometryType type )
|
||||||
|
{
|
||||||
|
mModel->setInPlaceLayerType( type );
|
||||||
|
}
|
||||||
|
|
||||||
QModelIndex QgsProcessingToolboxTreeView::findFirstVisibleAlgorithm( const QModelIndex &parent )
|
QModelIndex QgsProcessingToolboxTreeView::findFirstVisibleAlgorithm( const QModelIndex &parent )
|
||||||
{
|
{
|
||||||
for ( int r = 0; r < mModel->rowCount( parent ); ++r )
|
for ( int r = 0; r < mModel->rowCount( parent ); ++r )
|
||||||
|
@ -85,6 +85,8 @@ class GUI_EXPORT QgsProcessingToolboxTreeView : public QTreeView
|
|||||||
*/
|
*/
|
||||||
void setFilters( QgsProcessingToolboxProxyModel::Filters filters );
|
void setFilters( QgsProcessingToolboxProxyModel::Filters filters );
|
||||||
|
|
||||||
|
void setInPlaceLayerType( QgsWkbTypes::GeometryType type );
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user