Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Remove activation control from AlgorithmProvider
Split between QgsProcessingProvider and subclasses
  • Loading branch information
nyalldawson committed Apr 7, 2017
1 parent ff32054 commit 117260d
Show file tree
Hide file tree
Showing 15 changed files with 95 additions and 80 deletions.
8 changes: 7 additions & 1 deletion python/core/processing/qgsprocessingprovider.sip
Expand Up @@ -24,7 +24,7 @@ class QgsProcessingProvider : QObject

public:

QgsProcessingProvider( QObject* parent /TransferThis/ = 0 );
QgsProcessingProvider( QObject *parent /TransferThis/ = 0 );
%Docstring
Constructor for QgsProcessingProvider.
%End
Expand Down Expand Up @@ -64,6 +64,12 @@ class QgsProcessingProvider : QObject
%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 @@ -37,18 +37,14 @@ class ExampleAlgorithmProvider(AlgorithmProvider):
def __init__(self):
super().__init__()

# Deactivate provider by default
self.activate = False

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.load(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'))
Expand All @@ -58,20 +54,27 @@ 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'

Expand Down
12 changes: 10 additions & 2 deletions python/plugins/processing/algs/gdal/GdalAlgorithmProvider.py
Expand Up @@ -102,7 +102,9 @@ def __init__(self):
self.algs = []

def load(self):
AlgorithmProvider.load(self)
ProcessingConfig.settingIcons[self.name()] = self.icon()
ProcessingConfig.addSetting(Setting(self.name(), 'ACTIVATE_GDAL',
self.tr('Activate'), True))
ProcessingConfig.addSetting(Setting(
self.name(),
GdalUtils.GDAL_HELP_PATH,
Expand All @@ -111,9 +113,15 @@ def load(self):
return True

def unload(self):
AlgorithmProvider.unload(self)
ProcessingConfig.removeSetting('ACTIVATE_GDAL')
ProcessingConfig.removeSetting(GdalUtils.GDAL_HELP_PATH)

def isActive(self):
return ProcessingConfig.getSetting('ACTIVATE_GDAL')

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

def name(self):
version = GdalUtils.readableVersion()
return 'GDAL ({})'.format(version)
Expand Down
12 changes: 10 additions & 2 deletions python/plugins/processing/algs/grass7/Grass7AlgorithmProvider.py
Expand Up @@ -48,7 +48,9 @@ def __init__(self):
self.algs = []

def load(self):
AlgorithmProvider.load(self)
ProcessingConfig.settingIcons[self.name()] = self.icon()
ProcessingConfig.addSetting(Setting(self.name(), 'ACTIVATE_GRASS7',
self.tr('Activate'), True))
if isWindows() or isMac():
ProcessingConfig.addSetting(Setting(
self.name(),
Expand All @@ -70,13 +72,19 @@ def load(self):
return True

def unload(self):
AlgorithmProvider.unload(self)
ProcessingConfig.removeSetting('ACTIVATE_GRASS7')
if isWindows() or isMac():
ProcessingConfig.removeSetting(Grass7Utils.GRASS_FOLDER)
ProcessingConfig.removeSetting(Grass7Utils.GRASS_LOG_COMMANDS)
ProcessingConfig.removeSetting(Grass7Utils.GRASS_LOG_CONSOLE)
ProcessingConfig.removeSetting(Grass7Utils.GRASS_HELP_PATH)

def isActive(self):
return ProcessingConfig.getSetting('ACTIVATE_GRASS7')

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

def createAlgsList(self):
algs = []
folder = Grass7Utils.grassDescriptionPath()
Expand Down
13 changes: 10 additions & 3 deletions python/plugins/processing/algs/r/RAlgorithmProvider.py
Expand Up @@ -52,7 +52,6 @@ class RAlgorithmProvider(AlgorithmProvider):
def __init__(self):
super().__init__()
self.algs = []
self.activate = False
self.actions.append(CreateNewScriptAction(
'Create new R script', CreateNewScriptAction.SCRIPT_R))
self.actions.append(GetRScriptsAction())
Expand All @@ -61,7 +60,9 @@ def __init__(self):
DeleteScriptAction(DeleteScriptAction.SCRIPT_R)]

def load(self):
AlgorithmProvider.load(self)
ProcessingConfig.settingIcons[self.name()] = self.icon()
ProcessingConfig.addSetting(Setting(self.name(), 'ACTIVATE_R',
self.tr('Activate'), False))
ProcessingConfig.addSetting(Setting(
self.name(), RUtils.RSCRIPTS_FOLDER,
self.tr('R Scripts folder'), RUtils.defaultRScriptsFolder(),
Expand All @@ -81,13 +82,19 @@ def load(self):
return True

def unload(self):
AlgorithmProvider.unload(self)
ProcessingConfig.removeSetting('ACTIVATE_R')
ProcessingConfig.removeSetting(RUtils.RSCRIPTS_FOLDER)
if isWindows():
ProcessingConfig.removeSetting(RUtils.R_FOLDER)
ProcessingConfig.removeSetting(RUtils.R_LIBS_USER)
ProcessingConfig.removeSetting(RUtils.R_USE64)

def isActive(self):
return ProcessingConfig.getSetting('ACTIVATE_R')

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

def icon(self):
return QgsApplication.getThemeIcon("/providerR.svg")

Expand Down
13 changes: 10 additions & 3 deletions python/plugins/processing/algs/saga/SagaAlgorithmProvider.py
Expand Up @@ -46,11 +46,12 @@ class SagaAlgorithmProvider(AlgorithmProvider):

def __init__(self):
super().__init__()
self.activate = True
self.algs = []

def load(self):
AlgorithmProvider.load(self)
ProcessingConfig.settingIcons[self.name()] = self.icon()
ProcessingConfig.addSetting(Setting("SAGA", 'ACTIVATE_SAGA',
self.tr('Activate'), True))
if (isWindows() or isMac()):
ProcessingConfig.addSetting(Setting("SAGA",
SagaUtils.SAGA_FOLDER, self.tr('SAGA folder'),
Expand All @@ -68,13 +69,19 @@ def load(self):
return True

def unload(self):
AlgorithmProvider.unload(self)
ProcessingConfig.removeSetting('ACTIVATE_SAGA')
if (isWindows() or isMac()):
ProcessingConfig.removeSetting(SagaUtils.SAGA_FOLDER)

ProcessingConfig.removeSetting(SagaUtils.SAGA_LOG_CONSOLE)
ProcessingConfig.removeSetting(SagaUtils.SAGA_LOG_COMMANDS)

def isActive(self):
return ProcessingConfig.getSetting('ACTIVATE_SAGA')

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

def loadAlgorithms(self):
version = SagaUtils.getInstalledVersion(True)
if version is None:
Expand Down
30 changes: 0 additions & 30 deletions python/plugins/processing/core/AlgorithmProvider.py
Expand Up @@ -26,7 +26,6 @@
__revision__ = '$Format:%H$'

from qgis.core import (QgsProcessingProvider)
from processing.core.ProcessingConfig import Setting, ProcessingConfig


class AlgorithmProvider(QgsProcessingProvider):
Expand All @@ -40,34 +39,5 @@ class AlgorithmProvider(QgsProcessingProvider):

def __init__(self):
super().__init__()
# Indicates if the provider should be active by default.
# For provider relying on an external software, this should be
# False, so the user should activate them manually and install
# the required software in advance.
self.activate = True
self.actions = []
self.contextMenuActions = []

def load(self):
"""This is the place where you should add config parameters
using the ProcessingConfig class.
This method is called when a provider is added to the
Processing framework. By default it just adds a setting to
activate or deactivate algorithms from the provider.
"""
ProcessingConfig.settingIcons[self.name()] = self.icon()
name = 'ACTIVATE_' + self.id().upper().replace(' ', '_')
ProcessingConfig.addSetting(Setting(self.name(), name,
self.tr('Activate'), self.activate))
return True

def unload(self):
"""Do here anything that you want to be done when the provider
is removed from the list of available ones.
This method is called when you remove the provider from
Processing. Removal of config setting should be done here.
"""
name = 'ACTIVATE_' + self.id().upper().replace(' ', '_')
ProcessingConfig.removeSetting(name)
9 changes: 6 additions & 3 deletions python/plugins/processing/core/Processing.py
Expand Up @@ -111,11 +111,14 @@ def removeProvider(provider):
@staticmethod
def activateProvider(providerOrName, activate=True):
provider_id = providerOrName.id() if isinstance(providerOrName, AlgorithmProvider) else providerOrName
name = 'ACTIVATE_' + provider_id.upper().replace(' ', '_')
ProcessingConfig.setSettingValue(name, activate)
provider = QgsApplication.processingRegistry().providerById(provider_id)
if provider:
try:
provider.setActive(True)
provider.refreshAlgorithms()
except:
# provider could not be activated
QgsMessageLog.logMessage(Processing.tr('Error: Provider {0} could not be activated\n').format(provider_id),
Processing.tr("Processing"))

@staticmethod
def initialize():
Expand Down
37 changes: 19 additions & 18 deletions python/plugins/processing/gui/ProcessingToolbox.py
Expand Up @@ -98,9 +98,9 @@ def disabledProviders(self):
return False

for provider in QgsApplication.processingRegistry().providers():
name = 'ACTIVATE_' + provider.id().upper().replace(' ', '_')
if not ProcessingConfig.getSetting(name):
if not provider.isActive():
return True

return False

def textChanged(self):
Expand All @@ -112,8 +112,7 @@ def textChanged(self):
self.algorithmTree.expandAll()
self.disabledWithMatchingAlgs = []
for provider in QgsApplication.processingRegistry().providers():
name = 'ACTIVATE_' + provider.id().upper().replace(' ', '_')
if not ProcessingConfig.getSetting(name):
if not provider.isActive():
for alg in provider.algorithms():
if text in alg.name():
self.disabledWithMatchingAlgs.append(provider.id())
Expand Down Expand Up @@ -153,15 +152,21 @@ def _filterItem(self, item, text):
return False

def activateProvider(self, id):
name = 'ACTIVATE_' + id.upper().replace(' ', '_')
ProcessingConfig.setSettingValue(name, True)
self.fillTree()
self.textChanged()
self.showDisabled()
provider = QgsApplication.processingRegistry().providerById(id)
if not provider.canBeActivated():
QMessageBox.warning(self, "Activate provider",
"The provider has been activated, but it might need additional configuration.")
QMessageBox.warning(self, self.tr("Activate provider"),
self.tr("The provider has been activated, but it might need additional configuration."))
return

try:
# not part of the base class - only some providers have a setActive member
provider.setActive(True)
self.fillTree()
self.textChanged()
self.showDisabled()
except:
QMessageBox.warning(self, self.tr("Activate provider"),
self.tr("The provider could not be activated."))

def updateProvider(self):
provider = self.sender()
Expand Down Expand Up @@ -316,9 +321,8 @@ def addRecentAlgorithms(self, updating):

def addProvider(self, provider_id):
provider = QgsApplication.processingRegistry().providerById(provider_id)
name = 'ACTIVATE_' + provider.id().upper().replace(' ', '_')
providerItem = TreeProviderItem(provider, self.algorithmTree, self)
if not ProcessingConfig.getSetting(name):
if not provider.isActive():
providerItem.setHidden(True)
self.disabledProviderItems[provider.id()] = providerItem

Expand All @@ -335,8 +339,7 @@ def fillTreeUsingProviders(self):
self.disabledProviderItems = {}
disabled = []
for provider in QgsApplication.processingRegistry().providers():
name = 'ACTIVATE_' + provider.id().upper().replace(' ', '_')
if ProcessingConfig.getSetting(name):
if provider.isActive():
providerItem = TreeProviderItem(provider, self.algorithmTree, self)
else:
disabled.append(provider)
Expand Down Expand Up @@ -391,9 +394,7 @@ def populate(self):
groups = {}
count = 0
algs = self.provider.algorithms()

name = 'ACTIVATE_' + self.provider.id().upper().replace(' ', '_')
active = ProcessingConfig.getSetting(name)
active = self.provider.isActive()

# Add algorithms
for alg in algs:
Expand Down
Expand Up @@ -53,7 +53,7 @@ def __init__(self):
self.algs = []

def load(self):
AlgorithmProvider.load(self)
ProcessingConfig.settingIcons[self.name()] = self.icon()
ProcessingConfig.addSetting(Setting(self.name(),
ModelerUtils.MODELS_FOLDER, self.tr('Models folder', 'ModelerAlgorithmProvider'),
ModelerUtils.defaultModelsFolder(), valuetype=Setting.MULTIPLE_FOLDERS))
Expand Down
3 changes: 1 addition & 2 deletions python/plugins/processing/modeler/ModelerDialog.py
Expand Up @@ -599,8 +599,7 @@ def fillAlgorithmTreeUsingProviders(self):
text = str(self.searchBox.text())
search_strings = text.split(' ')
for provider in QgsApplication.processingRegistry().providers():
name = 'ACTIVATE_' + provider.id().upper().replace(' ', '_')
if not ProcessingConfig.getSetting(name):
if not provider.isActive():
continue
groups = {}

Expand Down
1 change: 0 additions & 1 deletion python/plugins/processing/modeler/ModelerUtils.py
Expand Up @@ -35,7 +35,6 @@
class ModelerUtils(object):

MODELS_FOLDER = 'MODELS_FOLDER'
ACTIVATE_MODELS = 'ACTIVATE_MODELS'

@staticmethod
def defaultModelsFolder():
Expand Down
3 changes: 1 addition & 2 deletions python/plugins/processing/script/ScriptAlgorithmProvider.py
Expand Up @@ -58,15 +58,14 @@ def __init__(self):
DeleteScriptAction(DeleteScriptAction.SCRIPT_PYTHON)]

def load(self):
AlgorithmProvider.load(self)
ProcessingConfig.settingIcons[self.name()] = self.icon()
ProcessingConfig.addSetting(Setting(self.name(),
ScriptUtils.SCRIPTS_FOLDER,
self.tr('Scripts folder', 'ScriptAlgorithmProvider'),
ScriptUtils.defaultScriptsFolder(), valuetype=Setting.MULTIPLE_FOLDERS))
return True

def unload(self):
AlgorithmProvider.unload(self)
ProcessingConfig.addSetting(ScriptUtils.SCRIPTS_FOLDER)

def icon(self):
Expand Down

0 comments on commit 117260d

Please sign in to comment.