Skip to content

Commit

Permalink
Port algorithm help to QgsProcessingAlgorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jun 5, 2017
1 parent 1e78855 commit 2d1579d
Show file tree
Hide file tree
Showing 11 changed files with 118 additions and 40 deletions.
26 changes: 26 additions & 0 deletions python/core/processing/qgsprocessingalgorithm.sip
Expand Up @@ -76,6 +76,32 @@ class QgsProcessingAlgorithm
:rtype: list of str
%End

virtual QString shortHelpString() const;
%Docstring
Returns a localised short helper string for the algorithm. This string should provide a basic description
about what the algorithm does and the parameters and outputs associated with it.
.. seealso:: helpString()
.. seealso:: helpUrl()
:rtype: str
%End

virtual QString helpString() const;
%Docstring
Returns a localised help string for the algorithm. Algorithm subclasses should implement either
helpString() or helpUrl().
.. seealso:: helpUrl()
.. seealso:: shortHelpString()
:rtype: str
%End

virtual QString helpUrl() const;
%Docstring
Returns a url pointing to the algorithm's help page.
.. seealso:: helpString()
.. seealso:: shortHelpString()
:rtype: str
%End

virtual QIcon icon() const;
%Docstring
Returns an icon for the algorithm.
Expand Down
6 changes: 3 additions & 3 deletions python/plugins/processing/algs/gdal/GdalAlgorithm.py
Expand Up @@ -77,7 +77,7 @@ def processAlgorithm(self, context, feedback):
commands[i] = c
GdalUtils.runGdal(commands, feedback)

def shortHelp(self):
def shortHelpString(self):
helpPath = GdalUtils.gdalHelpPath()
if helpPath == '':
return
Expand All @@ -87,9 +87,9 @@ def shortHelp(self):
else:
url = helpPath + '{}.html'.format(self.commandName())

return self._formatHelp('''This algorithm is based on the GDAL {} module.
return '''This algorithm is based on the GDAL {} module.
For more info, see the <a href={}> module help</a>
'''.format(self.commandName(), url))
'''.format(self.commandName(), url)

def commandName(self):
for output in self.outputs:
Expand Down
8 changes: 4 additions & 4 deletions python/plugins/processing/algs/grass7/Grass7Algorithm.py
Expand Up @@ -112,15 +112,15 @@ def icon(self):
def svgIconPath(self):
return QgsApplication.iconPath("providerGrass.svg")

def help(self):
def helpUrl(self):
helpPath = Grass7Utils.grassHelpPath()
if helpPath == '':
return False, None
return None

if os.path.exists(helpPath):
return False, QUrl.fromLocalFile(os.path.join(helpPath, '{}.html'.format(self.grass7Name))).toString()
return QUrl.fromLocalFile(os.path.join(helpPath, '{}.html'.format(self.grass7Name))).toString()
else:
return False, helpPath + '{}.html'.format(self.grass7Name)
return helpPath + '{}.html'.format(self.grass7Name)

def getParameterDescriptions(self):
descs = {}
Expand Down
13 changes: 2 additions & 11 deletions python/plugins/processing/core/GeoAlgorithm.py
Expand Up @@ -76,17 +76,8 @@ def __init__(self):

# methods to overwrite when creating a custom geoalgorithm

def _formatHelp(self, text):
return "<h2>%s</h2>%s" % (self.displayName(), "".join(["<p>%s</p>" % s for s in text.split("\n")]))

def help(self):
return False, None

def shortHelp(self):
text = shortHelp.get(self.id(), None)
if text is not None:
text = self._formatHelp(text)
return text
def shortHelpString(self):
return shortHelp.get(self.id(), None)

def processAlgorithm(self, context, feedback):
"""Here goes the algorithm itself.
Expand Down
30 changes: 18 additions & 12 deletions python/plugins/processing/gui/AlgorithmDialogBase.py
Expand Up @@ -104,7 +104,7 @@ def __init__(self, alg):
# if desktop.physicalDpiX() > 96:
# self.txtHelp.setZoomFactor(desktop.physicalDpiX() / 96)

algHelp = self.alg.shortHelp()
algHelp = self.formatHelp(self.alg)
if algHelp is None:
self.textShortHelp.setVisible(False)
else:
Expand All @@ -123,18 +123,18 @@ def linkClicked(url):

self.textShortHelp.anchorClicked.connect(linkClicked)

isText, algHelp = self.alg.help()
if algHelp is not None:
algHelp = algHelp if isText else QUrl(algHelp)
if self.alg.helpString() is not None:
try:
if isText:
self.txtHelp.setHtml(algHelp)
else:
html = self.tr('<p>Downloading algorithm help... Please wait.</p>')
self.txtHelp.setHtml(html)
rq = QNetworkRequest(algHelp)
self.reply = QgsNetworkAccessManager.instance().get(rq)
self.reply.finished.connect(self.requestFinished)
self.txtHelp.setHtml(self.alg.helpString())
except Exception:
self.tabWidget.removeTab(2)
elif self.alg.helpUrl() is not None:
try:
html = self.tr('<p>Downloading algorithm help... Please wait.</p>')
self.txtHelp.setHtml(html)
rq = QNetworkRequest(QUrl(self.alg.helpUrl()))
self.reply = QgsNetworkAccessManager.instance().get(rq)
self.reply.finished.connect(self.requestFinished)
except Exception:
self.tabWidget.removeTab(2)
else:
Expand All @@ -143,6 +143,12 @@ def linkClicked(url):
self.showDebug = ProcessingConfig.getSetting(
ProcessingConfig.SHOW_DEBUG_IN_DIALOG)

def formatHelp(self, alg):
text = alg.shortHelpString()
if not text:
return None
return "<h2>%s</h2>%s" % (alg.displayName(), "".join(["<p>%s</p>" % s for s in text.split("\n")]))

def requestFinished(self):
"""Change the webview HTML content"""
reply = self.sender()
Expand Down
10 changes: 5 additions & 5 deletions python/plugins/processing/modeler/ModelerAlgorithm.py
Expand Up @@ -539,15 +539,15 @@ def updateModelerView(self):
if self.modelerdialog:
self.modelerdialog.repaintModel()

def help(self):
def helpString(self):
try:
return True, getHtmlFromDescriptionsDict(self, self.helpContent)
return getHtmlFromDescriptionsDict(self, self.helpContent)
except:
return False, None
return None

def shortHelp(self):
def shortHelpString(self):
if 'ALG_DESC' in self.helpContent:
return self._formatHelp(str(self.helpContent['ALG_DESC']))
return str(self.helpContent['ALG_DESC'])
return None

def getParameterDescriptions(self):
Expand Down
10 changes: 5 additions & 5 deletions python/plugins/processing/script/ScriptAlgorithm.py
Expand Up @@ -198,16 +198,16 @@ def processAlgorithm(self, context, feedback):
for out in self.outputs:
out.setValue(ns[out.name])

def help(self):
def helpString(self):
if self.descriptionFile is None:
return False, None
helpfile = self.descriptionFile + '.help'
if os.path.exists(helpfile):
return True, getHtmlFromHelpFile(self, helpfile)
return getHtmlFromHelpFile(self, helpfile)
else:
return False, None
return None

def shortHelp(self):
def shortHelpString(self):
if self.descriptionFile is None:
return None
helpFile = str(self.descriptionFile) + '.help'
Expand All @@ -216,7 +216,7 @@ def shortHelp(self):
try:
descriptions = json.load(f)
if 'ALG_DESC' in descriptions:
return self._formatHelp(str(descriptions['ALG_DESC']))
return str(descriptions['ALG_DESC'])
except:
return None
return None
Expand Down
15 changes: 15 additions & 0 deletions src/core/processing/qgsnativealgorithms.cpp
Expand Up @@ -70,6 +70,12 @@ QgsCentroidAlgorithm::QgsCentroidAlgorithm()
addOutput( new QgsProcessingOutputVectorLayer( QStringLiteral( "OUTPUT_LAYER" ), QObject::tr( "Centroids" ), QgsProcessingParameterDefinition::TypeVectorPoint ) );
}

QString QgsCentroidAlgorithm::shortHelpString() const
{
return QObject::tr( "This algorithm creates a new point layer, with points representing the centroid of the geometries in an input layer.\n\n"
"The attributes associated to each point in the output layer are the same ones associated to the original features." );
}

QVariantMap QgsCentroidAlgorithm::run( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const
{
QgsVectorLayer *layer = qobject_cast< QgsVectorLayer *>( parameterAsLayer( parameters, QStringLiteral( "INPUT" ), context ) );
Expand Down Expand Up @@ -129,6 +135,15 @@ QgsBufferAlgorithm::QgsBufferAlgorithm()
addOutput( new QgsProcessingOutputVectorLayer( QStringLiteral( "OUTPUT_LAYER" ), QObject::tr( "Buffered" ), QgsProcessingParameterDefinition::TypeVectorPoint ) );
}

QString QgsBufferAlgorithm::shortHelpString() const
{
return QObject::tr( "This algorithm computes a buffer area for all the features in an input layer, using a fixed or dynamic distance.\n\n"
"The segments parameter controls the number of line segments to use to approximate a quarter circle when creating rounded offsets.\n\n"
"The end cap style parameter controls how line endings are handled in the buffer.\n\n"
"The join style parameter specifies whether round, mitre or beveled joins should be used when offsetting corners in a line.\n\n"
"The mitre limit parameter is only applicable for mitre join styles, and controls the maximum distance from the offset curve to use when creating a mitred join." );
}

QVariantMap QgsBufferAlgorithm::run( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const
{
QgsVectorLayer *layer = qobject_cast< QgsVectorLayer *>( parameterAsLayer( parameters, QStringLiteral( "INPUT" ), context ) );
Expand Down
2 changes: 2 additions & 0 deletions src/core/processing/qgsnativealgorithms.h
Expand Up @@ -57,6 +57,7 @@ class QgsCentroidAlgorithm : public QgsProcessingAlgorithm
QString displayName() const override { return QObject::tr( "Centroids" ); }
virtual QStringList tags() const override { return QObject::tr( "centroid,center,average,point,middle" ).split( ',' ); }
QString group() const override { return QObject::tr( "Vector geometry tools" ); }
QString shortHelpString() const override;

virtual QVariantMap run( const QVariantMap &parameters,
QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const override;
Expand All @@ -77,6 +78,7 @@ class QgsBufferAlgorithm : public QgsProcessingAlgorithm
QString displayName() const override { return QObject::tr( "Buffer" ); }
virtual QStringList tags() const override { return QObject::tr( "buffer,grow" ).split( ',' ); }
QString group() const override { return QObject::tr( "Vector geometry tools" ); }
QString shortHelpString() const override;

virtual QVariantMap run( const QVariantMap &parameters,
QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const override;
Expand Down
15 changes: 15 additions & 0 deletions src/core/processing/qgsprocessingalgorithm.cpp
Expand Up @@ -36,6 +36,21 @@ QString QgsProcessingAlgorithm::id() const
return name();
}

QString QgsProcessingAlgorithm::shortHelpString() const
{
return QString();
}

QString QgsProcessingAlgorithm::helpString() const
{
return QString();
}

QString QgsProcessingAlgorithm::helpUrl() const
{
return QString();
}

QIcon QgsProcessingAlgorithm::icon() const
{
return QgsApplication::getThemeIcon( "/processingAlgorithm.svg" );
Expand Down
23 changes: 23 additions & 0 deletions src/core/processing/qgsprocessingalgorithm.h
Expand Up @@ -95,6 +95,29 @@ class CORE_EXPORT QgsProcessingAlgorithm
*/
virtual QStringList tags() const { return QStringList(); }

/**
* Returns a localised short helper string for the algorithm. This string should provide a basic description
* about what the algorithm does and the parameters and outputs associated with it.
* \see helpString()
* \see helpUrl()
*/
virtual QString shortHelpString() const;

/**
* Returns a localised help string for the algorithm. Algorithm subclasses should implement either
* helpString() or helpUrl().
* \see helpUrl()
* \see shortHelpString()
*/
virtual QString helpString() const;

/**
* Returns a url pointing to the algorithm's help page.
* \see helpString()
* \see shortHelpString()
*/
virtual QString helpUrl() const;

/**
* Returns an icon for the algorithm.
* \see svgIconPath()
Expand Down

0 comments on commit 2d1579d

Please sign in to comment.