Move algorithm id (previously commandLineName) to QgsProcessingAlgorithm

This commit is contained in:
Nyall Dawson 2017-04-03 20:35:03 +10:00
parent 950ed680bd
commit 2a1a71574a
22 changed files with 66 additions and 70 deletions

View File

@ -51,6 +51,14 @@ class QgsProcessingAlgorithm
\see tags() \see tags()
%End %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; virtual QString displayName() const = 0;
%Docstring %Docstring
Returns the translated algorithm name, which should be used for any user-visible display Returns the translated algorithm name, which should be used for any user-visible display

View File

@ -57,7 +57,7 @@ class GridAverage(GdalAlgorithm):
TYPE = ['Byte', 'Int16', 'UInt16', 'UInt32', 'Int32', 'Float32', 'Float64'] TYPE = ['Byte', 'Int16', 'UInt16', 'UInt32', 'Int32', 'Float32', 'Float64']
def name(self): def name(self):
return 'gridmovingaverage' return 'gridaverage'
def displayName(self): def displayName(self):
return self.tr('Grid (Moving average)') return self.tr('Grid (Moving average)')
@ -65,9 +65,6 @@ class GridAverage(GdalAlgorithm):
def icon(self): def icon(self):
return QIcon(os.path.join(pluginPath, 'images', 'gdaltools', 'grid.png')) return QIcon(os.path.join(pluginPath, 'images', 'gdaltools', 'grid.png'))
def commandLineName(self):
return "gdal:gridaverage"
def group(self): def group(self):
return self.tr('Raster analysis') return self.tr('Raster analysis')

View File

@ -70,9 +70,6 @@ class GridDataMetrics(GdalAlgorithm):
def icon(self): def icon(self):
return QIcon(os.path.join(pluginPath, 'images', 'gdaltools', 'grid.png')) return QIcon(os.path.join(pluginPath, 'images', 'gdaltools', 'grid.png'))
def commandLineName(self):
return "gdal:griddatametrics"
def group(self): def group(self):
return self.tr('Raster analysis') return self.tr('Raster analysis')

View File

@ -90,7 +90,7 @@ class Grass7Algorithm(GeoAlgorithm):
self.uniqueSuffix = str(uuid.uuid4()).replace('-', '') self.uniqueSuffix = str(uuid.uuid4()).replace('-', '')
# Use the ext mechanism # Use the ext mechanism
name = self.commandLineName().replace('.', '_')[len('grass7:'):] name = self.name().replace('.', '_')
try: try:
self.module = importlib.import_module('processing.algs.grass7.ext.' + name) self.module = importlib.import_module('processing.algs.grass7.ext.' + name)
except ImportError: except ImportError:
@ -574,9 +574,6 @@ class Grass7Algorithm(GeoAlgorithm):
def getTempFilename(self): def getTempFilename(self):
return system.getTempFilename() return system.getTempFilename()
def commandLineName(self):
return 'grass7:' + self.name()
def checkBeforeOpeningParametersDialog(self): def checkBeforeOpeningParametersDialog(self):
return Grass7Utils.checkGrass7IsInstalled() return Grass7Utils.checkGrass7IsInstalled()

View File

@ -108,10 +108,6 @@ class SagaAlgorithm(GeoAlgorithm):
else: else:
self.cmdname = self._name self.cmdname = self._name
self._display_name = QCoreApplication.translate("SAGAAlgorithm", str(self._name)) self._display_name = QCoreApplication.translate("SAGAAlgorithm", str(self._name))
# _commandLineName is the name used in processing to call the algorithm
# Most of the time will be equal to the cmdname, but in same cases, several processing algorithms
# call the same SAGA one
self._commandLineName = self.createCommandLineName(self._name)
self._name = decoratedAlgorithmName(self._name) self._name = decoratedAlgorithmName(self._name)
self._display_name = QCoreApplication.translate("SAGAAlgorithm", str(self._name)) self._display_name = QCoreApplication.translate("SAGAAlgorithm", str(self._name))
@ -289,7 +285,7 @@ class SagaAlgorithm(GeoAlgorithm):
f.write(self.crs.toWkt()) f.write(self.crs.toWkt())
def preProcessInputs(self): def preProcessInputs(self):
name = self.commandLineName().replace('.', '_')[len('saga:'):] name = self.name().replace('.', '_')
try: try:
module = importlib.import_module('processing.algs.saga.ext.' + name) module = importlib.import_module('processing.algs.saga.ext.' + name)
except ImportError: except ImportError:
@ -299,9 +295,8 @@ class SagaAlgorithm(GeoAlgorithm):
func(self) func(self)
def editCommands(self, commands): def editCommands(self, commands):
name = self.commandLineName()[len('saga:'):]
try: try:
module = importlib.import_module('processing.algs.saga.ext.' + name) module = importlib.import_module('processing.algs.saga.ext.' + self.name())
except ImportError: except ImportError:
return commands return commands
if hasattr(module, 'editCommands'): if hasattr(module, 'editCommands'):
@ -373,11 +368,3 @@ class SagaAlgorithm(GeoAlgorithm):
extent2 = (layer.extent(), layer.height(), layer.width()) extent2 = (layer.extent(), layer.height(), layer.width())
if extent != extent2: if extent != extent2:
return self.tr("Input layers do not have the same grid extent.") return self.tr("Input layers do not have the same grid extent.")
def createCommandLineName(self, name):
validChars = \
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789:'
return 'saga:' + ''.join(c for c in name if c in validChars).lower()
def commandLineName(self):
return self._commandLineName

View File

@ -93,7 +93,7 @@ class GeoAlgorithm(QgsProcessingAlgorithm):
return False, None return False, None
def shortHelp(self): def shortHelp(self):
text = shortHelp.get(self.commandLineName(), None) text = shortHelp.get(self.id(), None)
if text is not None: if text is not None:
text = self._formatHelp(text) text = self._formatHelp(text)
return text return text
@ -461,9 +461,6 @@ class GeoAlgorithm(QgsProcessingAlgorithm):
s += '\n' s += '\n'
return s return s
def commandLineName(self):
return self.provider().id().lower() + ':' + self.name()
def removeOutputFromName(self, name): def removeOutputFromName(self, name):
for out in self.outputs: for out in self.outputs:
if out.name == name: if out.name == name:
@ -499,7 +496,7 @@ class GeoAlgorithm(QgsProcessingAlgorithm):
console. console.
""" """
s = 'processing.run("' + self.commandLineName() + '",' s = 'processing.run("' + self.id() + '",'
for param in self.parameters: for param in self.parameters:
s += param.getValueAsCommandLineParameter() + ',' s += param.getValueAsCommandLineParameter() + ','
for out in self.outputs: for out in self.outputs:

View File

@ -47,13 +47,13 @@ class AlgorithmList(QObject):
for p in QgsApplication.processingRegistry().providers(): for p in QgsApplication.processingRegistry().providers():
if p.id() == provider_id: if p.id() == provider_id:
p.refreshAlgorithms() p.refreshAlgorithms()
self.algs[p.id()] = {a.commandLineName(): a for a in p.algorithms()} self.algs[p.id()] = {a.id(): a for a in p.algorithms()}
self.providerUpdated.emit(p.id()) self.providerUpdated.emit(p.id())
break break
def addProvider(self, provider): def addProvider(self, provider):
if QgsApplication.processingRegistry().addProvider(provider): if QgsApplication.processingRegistry().addProvider(provider):
self.algs[provider.id()] = {a.commandLineName(): a for a in provider.algorithms()} self.algs[provider.id()] = {a.id(): a for a in provider.algorithms()}
def getAlgorithm(self, name): def getAlgorithm(self, name):
for provider in list(self.algs.values()): for provider in list(self.algs.values()):

View File

@ -236,9 +236,9 @@ class ConfigDialog(BASE, WIDGET):
algItem.setIcon(icon) algItem.setIcon(icon)
algItem.setEditable(False) algItem.setEditable(False)
try: try:
settingMenu = ProcessingConfig.settings["MENU_" + alg.commandLineName()] settingMenu = ProcessingConfig.settings["MENU_" + alg.id()]
settingButton = ProcessingConfig.settings["BUTTON_" + alg.commandLineName()] settingButton = ProcessingConfig.settings["BUTTON_" + alg.id()]
settingIcon = ProcessingConfig.settings["ICON_" + alg.commandLineName()] settingIcon = ProcessingConfig.settings["ICON_" + alg.id()]
except: except:
continue continue
self.items[settingMenu] = SettingItem(settingMenu) self.items[settingMenu] = SettingItem(settingMenu)
@ -269,8 +269,8 @@ class ConfigDialog(BASE, WIDGET):
providers = Processing.providers providers = Processing.providers
for provider in providers: for provider in providers:
for alg in provider.algorithms(): for alg in provider.algorithms():
d = defaultMenuEntries.get(alg.commandLineName(), "") d = defaultMenuEntries.get(alg.id(), "")
setting = ProcessingConfig.settings["MENU_" + alg.commandLineName()] setting = ProcessingConfig.settings["MENU_" + alg.id()]
item = self.items[setting] item = self.items[setting]
item.setData(d, Qt.EditRole) item.setData(d, Qt.EditRole)
self.saveMenus = True self.saveMenus = True

View File

@ -75,7 +75,7 @@ class EditRenderingStylesDialog(BASE, WIDGET):
self.tblStyles.setItem(i, 0, item) self.tblStyles.setItem(i, 0, item)
item = RenderingStyleFilePanel() item = RenderingStyleFilePanel()
style = \ style = \
RenderingStyles.getStyle(self.alg.commandLineName(), RenderingStyles.getStyle(self.alg.id(),
output.name) output.name)
if style: if style:
item.setText(str(style)) item.setText(str(style))
@ -88,7 +88,7 @@ class EditRenderingStylesDialog(BASE, WIDGET):
styles = {} styles = {}
for key in list(self.valueItems.keys()): for key in list(self.valueItems.keys()):
styles[key] = str(self.valueItems[key].getValue()) styles[key] = str(self.valueItems[key].getValue())
RenderingStyles.addAlgStylesAndSave(self.alg.commandLineName(), styles) RenderingStyles.addAlgStylesAndSave(self.alg.id(), styles)
QDialog.accept(self) QDialog.accept(self)

View File

@ -70,7 +70,7 @@ def handleAlgorithmResults(alg, feedback=None, showResults=True):
else: else:
name = out.description name = out.description
dataobjects.load(out.value, name, alg.crs, dataobjects.load(out.value, name, alg.crs,
RenderingStyles.getStyle(alg.commandLineName(), RenderingStyles.getStyle(alg.id(),
out.name)) out.name))
except Exception: except Exception:
ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,

View File

@ -141,7 +141,7 @@ class ProcessingToolbox(BASE, WIDGET):
# hide if every part of text is not contained somewhere in either the item text or item user role # hide if every part of text is not contained somewhere in either the item text or item user role
item_text = [item.text(0).lower(), item.data(0, Qt.UserRole).lower()] item_text = [item.text(0).lower(), item.data(0, Qt.UserRole).lower()]
if isinstance(item, TreeAlgorithmItem): if isinstance(item, TreeAlgorithmItem):
item_text.append(item.alg.commandLineName()) item_text.append(item.alg.id())
item_text.extend(item.data(0, Qt.UserRole + 1)) item_text.extend(item.data(0, Qt.UserRole + 1))
hide = bool(text) and not all( hide = bool(text) and not all(
@ -227,14 +227,14 @@ class ProcessingToolbox(BASE, WIDGET):
def editRenderingStyles(self): def editRenderingStyles(self):
item = self.algorithmTree.currentItem() item = self.algorithmTree.currentItem()
if isinstance(item, TreeAlgorithmItem): if isinstance(item, TreeAlgorithmItem):
alg = Processing.getAlgorithm(item.alg.commandLineName()) alg = Processing.getAlgorithm(item.alg.id())
dlg = EditRenderingStylesDialog(alg) dlg = EditRenderingStylesDialog(alg)
dlg.exec_() dlg.exec_()
def executeAlgorithmAsBatchProcess(self): def executeAlgorithmAsBatchProcess(self):
item = self.algorithmTree.currentItem() item = self.algorithmTree.currentItem()
if isinstance(item, TreeAlgorithmItem): if isinstance(item, TreeAlgorithmItem):
alg = Processing.getAlgorithm(item.alg.commandLineName()) alg = Processing.getAlgorithm(item.alg.id())
alg = alg.getCopy() alg = alg.getCopy()
dlg = BatchAlgorithmDialog(alg) dlg = BatchAlgorithmDialog(alg)
dlg.show() dlg.show()
@ -243,7 +243,7 @@ class ProcessingToolbox(BASE, WIDGET):
def executeAlgorithm(self): def executeAlgorithm(self):
item = self.algorithmTree.currentItem() item = self.algorithmTree.currentItem()
if isinstance(item, TreeAlgorithmItem): if isinstance(item, TreeAlgorithmItem):
alg = Processing.getAlgorithm(item.alg.commandLineName()) alg = Processing.getAlgorithm(item.alg.id())
message = alg.checkBeforeOpeningParametersDialog() message = alg.checkBeforeOpeningParametersDialog()
if message: if message:
dlg = MessageDialog() dlg = MessageDialog()

View File

@ -114,14 +114,14 @@ defaultMenuEntries.update({'gdal:buildvirtualraster': miscMenu,
def initializeMenus(): def initializeMenus():
for provider in QgsApplication.processingRegistry().providers(): for provider in QgsApplication.processingRegistry().providers():
for alg in provider.algorithms(): for alg in provider.algorithms():
d = defaultMenuEntries.get(alg.commandLineName(), "") d = defaultMenuEntries.get(alg.id(), "")
setting = Setting(menusSettingsGroup, "MENU_" + alg.commandLineName(), setting = Setting(menusSettingsGroup, "MENU_" + alg.id(),
"Menu path", d) "Menu path", d)
ProcessingConfig.addSetting(setting) ProcessingConfig.addSetting(setting)
setting = Setting(menusSettingsGroup, "BUTTON_" + alg.commandLineName(), setting = Setting(menusSettingsGroup, "BUTTON_" + alg.id(),
"Add button", False) "Add button", False)
ProcessingConfig.addSetting(setting) ProcessingConfig.addSetting(setting)
setting = Setting(menusSettingsGroup, "ICON_" + alg.commandLineName(), setting = Setting(menusSettingsGroup, "ICON_" + alg.id(),
"Icon", "", valuetype=Setting.FILE) "Icon", "", valuetype=Setting.FILE)
ProcessingConfig.addSetting(setting) ProcessingConfig.addSetting(setting)
@ -137,9 +137,9 @@ def updateMenus():
def createMenus(): def createMenus():
for provider in list(algList.algs.values()): for provider in list(algList.algs.values()):
for alg in list(provider.values()): for alg in list(provider.values()):
menuPath = ProcessingConfig.getSetting("MENU_" + alg.commandLineName()) menuPath = ProcessingConfig.getSetting("MENU_" + alg.id())
addButton = ProcessingConfig.getSetting("BUTTON_" + alg.commandLineName()) addButton = ProcessingConfig.getSetting("BUTTON_" + alg.id())
icon = ProcessingConfig.getSetting("ICON_" + alg.commandLineName()) icon = ProcessingConfig.getSetting("ICON_" + alg.id())
if icon and os.path.exists(icon): if icon and os.path.exists(icon):
icon = QIcon(icon) icon = QIcon(icon)
else: else:
@ -152,7 +152,7 @@ def createMenus():
def removeMenus(): def removeMenus():
for provider in list(algList.algs.values()): for provider in list(algList.algs.values()):
for alg in list(provider.values()): for alg in list(provider.values()):
menuPath = ProcessingConfig.getSetting("MENU_" + alg.commandLineName()) menuPath = ProcessingConfig.getSetting("MENU_" + alg.id())
if menuPath: if menuPath:
paths = menuPath.split("/") paths = menuPath.split("/")
removeAlgorithmEntry(alg, paths[0], paths[-1]) removeAlgorithmEntry(alg, paths[0], paths[-1])
@ -161,7 +161,7 @@ def removeMenus():
def addAlgorithmEntry(alg, menuName, submenuName, actionText=None, icon=None, addButton=False): def addAlgorithmEntry(alg, menuName, submenuName, actionText=None, icon=None, addButton=False):
action = QAction(icon or alg.icon(), actionText or alg.displayName(), iface.mainWindow()) action = QAction(icon or alg.icon(), actionText or alg.displayName(), iface.mainWindow())
action.triggered.connect(lambda: _executeAlgorithm(alg)) action.triggered.connect(lambda: _executeAlgorithm(alg))
action.setObjectName("mProcessingUserMenu_%s" % alg.commandLineName()) action.setObjectName("mProcessingUserMenu_%s" % alg.id())
if menuName: if menuName:
menu = getMenu(menuName, iface.mainWindow().menuBar()) menu = getMenu(menuName, iface.mainWindow().menuBar())

View File

@ -541,12 +541,6 @@ class ModelerAlgorithm(GeoAlgorithm):
else: else:
return None return None
def commandLineName(self):
if self.descriptionFile is None:
return ''
else:
return 'modeler:' + os.path.basename(self.descriptionFile)[:-6].lower()
def checkBeforeOpeningParametersDialog(self): def checkBeforeOpeningParametersDialog(self):
for alg in list(self.algs.values()): for alg in list(self.algs.values()):
algInstance = algList.getAlgorithm(alg.consoleName) algInstance = algList.getAlgorithm(alg.consoleName)

View File

@ -186,7 +186,7 @@ class ModelerDialog(BASE, WIDGET):
item = items[0] item = items[0]
if isinstance(item, TreeAlgorithmItem): if isinstance(item, TreeAlgorithmItem):
mimeData = QMimeData() mimeData = QMimeData()
mimeData.setText(item.alg.commandLineName()) mimeData.setText(item.alg.id())
return mimeData return mimeData
self.algorithmTree.mimeData = _mimeDataAlgorithm self.algorithmTree.mimeData = _mimeDataAlgorithm
@ -549,7 +549,7 @@ class ModelerDialog(BASE, WIDGET):
def addAlgorithm(self): def addAlgorithm(self):
item = self.algorithmTree.currentItem() item = self.algorithmTree.currentItem()
if isinstance(item, TreeAlgorithmItem): if isinstance(item, TreeAlgorithmItem):
alg = algList.getAlgorithm(item.alg.commandLineName()) alg = algList.getAlgorithm(item.alg.id())
self._addAlgorithm(alg.getCopy()) self._addAlgorithm(alg.getCopy())
def _addAlgorithm(self, alg, pos=None): def _addAlgorithm(self, alg, pos=None):
@ -611,7 +611,7 @@ class ModelerDialog(BASE, WIDGET):
for alg in algs: for alg in algs:
if alg.flags() & QgsProcessingAlgorithm.FlagHideFromModeler: if alg.flags() & QgsProcessingAlgorithm.FlagHideFromModeler:
continue continue
if alg.commandLineName() == self.alg.commandLineName(): if alg.id() == self.alg.id():
continue continue
item_text = [alg.displayName().lower()] item_text = [alg.displayName().lower()]

View File

@ -321,7 +321,7 @@ class ModelerParametersDialog(QDialog):
self.dependenciesPanel.setSelectedItems(selected) self.dependenciesPanel.setSelectedItems(selected)
def createAlgorithm(self): def createAlgorithm(self):
alg = Algorithm(self._alg.commandLineName()) alg = Algorithm(self._alg.id())
alg.setName(self.model) alg.setName(self.model)
alg.description = self.descriptionBox.text() alg.description = self.descriptionBox.text()
params = self._alg.parameters params = self._alg.parameters

View File

@ -63,7 +63,7 @@ class PreconfiguredAlgorithm(GeoAlgorithm):
return newone return newone
def defineCharacteristics(self): def defineCharacteristics(self):
self.name = self.description["name"] self._name = self.description["name"]
self._group = self.description["group"] self._group = self.description["group"]
def execute(self, feedback): def execute(self, feedback):

View File

@ -35,4 +35,4 @@ def algAsDict(alg):
outputs = {} outputs = {}
for out in alg.outputs: for out in alg.outputs:
outputs[out.name] = out.value outputs[out.name] = out.value
return {"parameters": params, "outputs": outputs, "algname": alg.commandLineName()} return {"parameters": params, "outputs": outputs, "algname": alg.id()}

View File

@ -51,7 +51,7 @@ def algorithmsList(text=None):
sortedlist = sorted(list(provider.values()), key=lambda alg: alg.name()) sortedlist = sorted(list(provider.values()), key=lambda alg: alg.name())
for alg in sortedlist: for alg in sortedlist:
if text is None or text.lower() in alg.name().lower(): if text is None or text.lower() in alg.name().lower():
lst.append(alg.commandLineName()) lst.append(alg.id())
return lst return lst
@ -66,7 +66,7 @@ def printAlgorithms(text=None):
sortedlist = sorted(list(provider.values()), key=lambda alg: alg.name()) sortedlist = sorted(list(provider.values()), key=lambda alg: alg.name())
for alg in sortedlist: for alg in sortedlist:
if text is None or text.lower() in alg.name().lower(): if text is None or text.lower() in alg.name().lower():
s += '{}--->{}\n'.format(alg.name().ljust(50, '-'), alg.commandLineName()) s += '{}--->{}\n'.format(alg.name().ljust(50, '-'), alg.id())
print(s) print(s)

View File

@ -38,7 +38,7 @@ def baseHelpForAlgorithm(alg, folder):
groupName = alg.group().lower() groupName = alg.group().lower()
groupName = groupName.replace('[', '').replace(']', '').replace(' - ', '_') groupName = groupName.replace('[', '').replace(']', '').replace(' - ', '_')
groupName = groupName.replace(' ', '_') groupName = groupName.replace(' ', '_')
cmdLineName = alg.commandLineName() cmdLineName = alg.id()
algName = cmdLineName[cmdLineName.find(':') + 1:].lower() algName = cmdLineName[cmdLineName.find(':') + 1:].lower()
validChars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_' validChars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_'
safeGroupName = ''.join(c for c in groupName if c in validChars) safeGroupName = ''.join(c for c in groupName if c in validChars)
@ -89,7 +89,7 @@ def baseHelpForAlgorithm(alg, folder):
f.write('Console usage\n') f.write('Console usage\n')
f.write('-------------\n') f.write('-------------\n')
f.write('\n::\n\n') f.write('\n::\n\n')
cmd = " processing.run('{}', ".format(alg.commandLineName()) cmd = " processing.run('{}', ".format(alg.id())
for p in alg.parameters: for p in alg.parameters:
cmd += '{}, '.format(p.name.lower().strip()) cmd += '{}, '.format(p.name.lower().strip())

View File

@ -17,6 +17,15 @@
#include "qgsprocessingalgorithm.h" #include "qgsprocessingalgorithm.h"
#include "qgsapplication.h" #include "qgsapplication.h"
#include "qgsprocessingprovider.h"
QString QgsProcessingAlgorithm::id() const
{
if ( mProvider )
return QString( "%1:%2" ).arg( mProvider->id(), name() );
else
return name();
}
QIcon QgsProcessingAlgorithm::icon() const QIcon QgsProcessingAlgorithm::icon() const
{ {

View File

@ -68,6 +68,14 @@ class CORE_EXPORT QgsProcessingAlgorithm
*/ */
virtual QString name() const = 0; virtual QString name() const = 0;
/**
* 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()
*/
QString id() const;
/** /**
* Returns the translated algorithm name, which should be used for any user-visible display * Returns the translated algorithm name, which should be used for any user-visible display
* of the algorithm name. * of the algorithm name.

View File

@ -347,8 +347,10 @@ void TestQgsProcessing::algorithm()
{ {
DummyAlgorithm alg( "test" ); DummyAlgorithm alg( "test" );
DummyProvider *p = new DummyProvider( "p1" ); DummyProvider *p = new DummyProvider( "p1" );
QCOMPARE( alg.id(), QString( "test" ) );
alg.setProvider( p ); alg.setProvider( p );
QCOMPARE( alg.provider(), p ); QCOMPARE( alg.provider(), p );
QCOMPARE( alg.id(), QString( "p1:test" ) );
QVERIFY( p->algorithms().isEmpty() ); QVERIFY( p->algorithms().isEmpty() );