Skip to content

Commit

Permalink
Merge pull request #4328 from nyalldawson/proc_c7
Browse files Browse the repository at this point in the history
Porting processing to c++, part 2 (followup to #4311)
  • Loading branch information
nyalldawson committed Apr 7, 2017
2 parents 9c30a0e + 837ee29 commit 2adccb9
Show file tree
Hide file tree
Showing 73 changed files with 1,057 additions and 737 deletions.
5 changes: 3 additions & 2 deletions doc/api_break.dox
Expand Up @@ -2163,13 +2163,14 @@ Processing {#qgis_api_break_3_0_Processing}
----------

- Algorithm providers now subclass the c++ QgsProcessingProvider class, and must be adapted to the API for QgsProcessingProvider. Specifically,
getName() should be replaced with id(), getDescription() with name(), and getIcon with icon().
getName() should be replaced with id(), getDescription() with name(), and getIcon with icon(). AlgorithmProvider was removed.
- Algorithm's processAlgorithm method now passes a QgsProcessingFeedback object instead of the loosely defined progress parameter. Algorithms will
need to update their use of the progress argument to utilize the QgsProcessingFeedback API.
- Similarly, Python processing scripts no longer have access to a progress variable for reporting their progress. Instead they have a feedback
object of type QgsProcessingFeedback, and will need to adapt their use of progress reporting to the QgsProcessingFeedback API.
- SilentProgress was removed. Use the base QgsProcessingFeedback class instead.

- algList was removed. Use QgsApplication.processingRegistry() instead.
- Processing.algs was removed. QgsApplication.processingRegistry().algorithms() instead.

Triangulation {#qgis_api_break_3_0_Triangulation}
-------------
Expand Down
18 changes: 18 additions & 0 deletions python/core/processing/qgsprocessingalgorithm.sip
Expand Up @@ -9,6 +9,7 @@




class QgsProcessingAlgorithm
{
%Docstring
Expand Down Expand Up @@ -37,6 +38,8 @@ class QgsProcessingAlgorithm

virtual ~QgsProcessingAlgorithm();

// QgsProcessingAlgorithm &operator=( const QgsProcessingAlgorithm &other ) = delete;

virtual QString name() const = 0;
%Docstring
Returns the algorithm name, used for identifying the algorithm. This string
Expand All @@ -48,6 +51,14 @@ class QgsProcessingAlgorithm
\see tags()
%End

QString id() const;
%Docstring
Returns the unique ID for the algorithm, which is a combination of the algorithm
provider's ID and the algorithms unique name (e.g. "qgis:mergelayers" ).
\see name()
\see provider()
%End

virtual QString displayName() const = 0;
%Docstring
Returns the translated algorithm name, which should be used for any user-visible display
Expand Down Expand Up @@ -85,6 +96,13 @@ class QgsProcessingAlgorithm
Returns the flags indicating how and when the algorithm operates and should be exposed to users.
%End

QgsProcessingProvider *provider() const;
%Docstring
Returns the provider to which this algorithm belongs.
%End

private:
QgsProcessingAlgorithm( const QgsProcessingAlgorithm &other );
};
QFlags<QgsProcessingAlgorithm::Flag> operator|(QgsProcessingAlgorithm::Flag f1, QFlags<QgsProcessingAlgorithm::Flag> f2);

Expand Down
67 changes: 65 additions & 2 deletions python/core/processing/qgsprocessingprovider.sip
Expand Up @@ -9,7 +9,7 @@



class QgsProcessingProvider
class QgsProcessingProvider : QObject
{
%Docstring
Abstract base class for processing providers. An algorithm provider is a set of
Expand All @@ -24,7 +24,7 @@ class QgsProcessingProvider

public:

QgsProcessingProvider();
QgsProcessingProvider( QObject *parent /TransferThis/ = 0 );
%Docstring
Constructor for QgsProcessingProvider.
%End
Expand Down Expand Up @@ -64,6 +64,12 @@ class QgsProcessingProvider
%Docstring
Returns true if the provider can be activated, or false if it cannot be activated (e.g. due to
missing external dependencies).
\see isActive()
%End

virtual bool isActive() const;
%Docstring
Returns true if the provider is active and able to run algorithms.
%End

virtual QStringList supportedOutputRasterLayerExtensions() const;
Expand Down Expand Up @@ -95,6 +101,63 @@ class QgsProcessingProvider
\see supportedOutputVectorLayerExtensions()
%End

virtual bool load();
%Docstring
Loads the provider. This will be called when the plugin is being loaded, and any general
setup actions should occur in an overridden version of this method.
Subclasses should not individually load any algorithms in their load() implementations, as that must
occur within the loadAlgorithms() method. Instead, subclasses should call refreshAlgorithms()
from any overloaded load() method to trigger an initial load of the provider's algorithms.
\returns true if provider could be successfully loaded
\see unload()
%End

virtual void unload();
%Docstring
Unloads the provider. Any tear-down steps required by the provider should be implemented here.
\see load()
%End

void refreshAlgorithms();
%Docstring
Refreshes the algorithms available from the provider, causing it to re-populate with all associated algorithms.
%End

QList< const QgsProcessingAlgorithm * > algorithms() const;
%Docstring
Returns a list of algorithms supplied by this provider.
\see algorithm()
%End

const QgsProcessingAlgorithm *algorithm( const QString &name ) const;
%Docstring
Returns the matching algorithm by name, or a None if no matching
algorithm is contained by this provider.
\see algorithms()
%End

signals:

void algorithmsLoaded();
%Docstring
Emitted when the provider has loaded (or refreshed) its list of available
algorithms.
\see refreshAlgorithms()
%End

protected:

virtual void loadAlgorithms() = 0;
%Docstring
Loads all algorithms belonging to this provider. Subclasses should implement this, calling
addAlgorithm() to register all their associated algorithms.
%End

bool addAlgorithm( QgsProcessingAlgorithm *algorithm /Transfer/ );
%Docstring
Adds an algorithm to the provider. Ownership of the algorithm is transferred to the provider.
%End

private:
QgsProcessingProvider( const QgsProcessingProvider &other );
};
Expand Down
18 changes: 17 additions & 1 deletion python/core/processing/qgsprocessingregistry.sip
Expand Up @@ -42,9 +42,12 @@ class QgsProcessingRegistry : QObject

bool addProvider( QgsProcessingProvider *provider /Transfer/ );
%Docstring
Add a processing provider to the registry. Ownership of the provider is transferred to the registry.
Add a processing provider to the registry. Ownership of the provider is transferred to the registry,
and the provider's parent will be set to the registry.
Returns false if the provider could not be added (eg if a provider with a duplicate ID already exists
in the registry).
Adding a provider to the registry automatically triggers the providers QgsProcessingProvider.load()
method to populate the provider with algorithms.
\see removeProvider()
%End

Expand All @@ -67,6 +70,19 @@ class QgsProcessingRegistry : QObject
Returns a matching provider by provider ID.
%End

QList< const QgsProcessingAlgorithm *> algorithms() const;
%Docstring
Returns a list of all available algorithms from registered providers.
\see algorithmById()
%End

const QgsProcessingAlgorithm *algorithmById( const QString &id ) const;
%Docstring
Finds an algorithm by its ID. If no matching algorithm is found, a None
is returned.
\see algorithms()
%End

signals:

void providerAdded( const QString &id );
Expand Down
5 changes: 3 additions & 2 deletions python/plugins/processing/ProcessingPlugin.py
Expand Up @@ -46,7 +46,6 @@
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]
Expand Down Expand Up @@ -164,6 +163,7 @@ def unload(self):
self.iface.unregisterOptionsWidgetFactory(self.options_factory)

removeMenus()
Processing.deinitialize()

def openCommander(self):
if self.commander is None:
Expand All @@ -185,7 +185,8 @@ def openModeler(self):
dlg.show()

def updateModel(self):
algList.reloadProvider('model')
model_provider = QgsApplication.processingRegistry().providerById('model')
model_provider.refreshAlgorithms()

def openResults(self):
if self.resultsDock.isVisible():
Expand Down
Expand Up @@ -25,66 +25,67 @@

__revision__ = '$Format:%H$'

from processing.core.AlgorithmProvider import AlgorithmProvider
from qgis.core import QgsProcessingProvider
from processing.core.ProcessingConfig import Setting, ProcessingConfig
from exampleprovider.ExampleAlgorithm import ExampleAlgorithm


class ExampleAlgorithmProvider(AlgorithmProvider):
class ExampleAlgorithmProvider(QgsProcessingProvider):

MY_DUMMY_SETTING = 'MY_DUMMY_SETTING'

def __init__(self):
super().__init__()

# Deactivate provider by default
self.activate = False

# Load algorithms
self.alglist = [ExampleAlgorithm()]
for alg in self.alglist:
alg.provider = self

def initializeSettings(self):
def load(self):
"""In this method we add settings needed to configure our
provider.
Do not forget to call the parent method, since it takes care
or automatically adding a setting for activating or
deactivating the algorithms in the provider.
"""
AlgorithmProvider.initializeSettings(self)
ProcessingConfig.settingIcons[self.name()] = self.icon()
# Deactivate provider by default
ProcessingConfig.addSetting(Setting(self.name(), 'ACTIVATE_EXAMPLE',
'Activate', False))
ProcessingConfig.addSetting(Setting('Example algorithms',
ExampleAlgorithmProvider.MY_DUMMY_SETTING,
'Example setting', 'Default value'))
ProcessingConfig.readSettings()
self.refreshAlgorithms()
return True

def unload(self):
"""Setting should be removed here, so they do not appear anymore
when the plugin is unloaded.
"""
AlgorithmProvider.unload(self)
ProcessingConfig.removeSetting('ACTIVATE_EXAMPLE')
ProcessingConfig.removeSetting(
ExampleAlgorithmProvider.MY_DUMMY_SETTING)

def isActive(self):
"""Return True if the provider is activated and ready to run algorithms"""
return ProcessingConfig.getSetting('ACTIVATE_EXAMPLE')

def setActive(self, active):
ProcessingConfig.setSettingValue('ACTIVATE_EXAMPLE', active)

def id(self):
"""This is the name that will appear on the toolbox group.
It is also used to create the command line name of all the
algorithms from this provider.
"""
return 'Example provider'
return 'example'

def name(self):
"""This is the provired full name.
"""This is the localised full name.
"""
return 'Example algorithms'

def icon(self):
"""We return the default icon.
"""
return AlgorithmProvider.icon(self)
return QgsProcessingProvider.icon(self)

def _loadAlgorithms(self):
def loadAlgorithms(self):
"""Here we fill the list of algorithms in self.algs.
This method is called whenever the list of algorithms should
Expand All @@ -98,4 +99,5 @@ def _loadAlgorithms(self):
even if the list does not change, since the self.algs list is
cleared before calling this method.
"""
self.algs = self.alglist
for alg in [ExampleAlgorithm()]:
self.addAlgorithm(alg)
Expand Up @@ -30,6 +30,7 @@
import sys
import inspect

from qgis.core import QgsApplication
from processing.core.Processing import Processing
from exampleprovider.ExampleAlgorithmProvider import ExampleAlgorithmProvider

Expand All @@ -45,7 +46,7 @@ def __init__(self):
self.provider = ExampleAlgorithmProvider()

def initGui(self):
Processing.addProvider(self.provider)
QgsApplication.processingRegistry().addProvider(self.provider)

def unload(self):
Processing.removeProvider(self.provider)
QgsApplication.processingRegistry().removeProvider(self.provider)

0 comments on commit 2adccb9

Please sign in to comment.