Skip to content

Commit

Permalink
[processing] Add a warning-level information message feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
nirvn committed Dec 7, 2020
1 parent 344bc5f commit 04b9c6a
Show file tree
Hide file tree
Showing 12 changed files with 105 additions and 9 deletions.
27 changes: 27 additions & 0 deletions python/core/auto_generated/processing/qgsprocessingfeedback.sip.in
Expand Up @@ -49,6 +49,23 @@ Sets a progress report text string. This can be used in conjunction with
Reports that the algorithm encountered an ``error`` while executing.

If ``fatalError`` is ``True`` then the error prevented the algorithm from executing.
%End

virtual void pushWarning( const QString &warning );
%Docstring
Pushes a warning informational message from the algorithm. This
should only be used sparsely as to maintain the importance of visual
queues associated to this type of message.

.. seealso:: :py:func:`pushInfo`

.. seealso:: :py:func:`pushCommandInfo`

.. seealso:: :py:func:`pushDebugInfo`

.. seealso:: :py:func:`pushConsoleInfo`

.. versionadded:: 3.16.2
%End

virtual void pushInfo( const QString &info );
Expand All @@ -57,6 +74,8 @@ Pushes a general informational message from the algorithm. This can
be used to report feedback which is neither a status report or an
error, such as "Found 47 matching features".

.. seealso:: :py:func:`pushWarning`

.. seealso:: :py:func:`pushCommandInfo`

.. seealso:: :py:func:`pushDebugInfo`
Expand All @@ -70,6 +89,8 @@ Pushes an informational message containing a command from the algorithm.
This is usually used to report commands which are executed in an external
application or as subprocesses.

.. seealso:: :py:func:`pushWarning`

.. seealso:: :py:func:`pushInfo`

.. seealso:: :py:func:`pushDebugInfo`
Expand All @@ -82,6 +103,8 @@ application or as subprocesses.
Pushes an informational message containing debugging helpers from
the algorithm.

.. seealso:: :py:func:`pushWarning`

.. seealso:: :py:func:`pushInfo`

.. seealso:: :py:func:`pushCommandInfo`
Expand All @@ -94,6 +117,8 @@ the algorithm.
Pushes a console feedback message from the algorithm. This is used to
report the output from executing an external command or subprocess.

.. seealso:: :py:func:`pushWarning`

.. seealso:: :py:func:`pushInfo`

.. seealso:: :py:func:`pushDebugInfo`
Expand Down Expand Up @@ -164,6 +189,8 @@ to scale the current progress to account for progress through the overall proces

virtual void reportError( const QString &error, bool fatalError = false );

virtual void pushWarning( const QString &warning );

virtual void pushInfo( const QString &info );

virtual void pushCommandInfo( const QString &info );
Expand Down
Expand Up @@ -116,6 +116,11 @@ the given ``format``.
Reports an ``error`` string to the dialog's log.

If ``fatalError`` is ``True``, the error prevented the algorithm from executing.
%End

void pushWarning( const QString &warning );
%Docstring
Pushes a warning information string to the dialog's log.
%End

void pushInfo( const QString &info );
Expand Down Expand Up @@ -243,7 +248,7 @@ Sets the algorithm results.
.. seealso:: :py:func:`setExecuted`
%End

void setInfo( const QString &message, bool isError = false, bool escapeHtml = true );
void setInfo( const QString &message, bool isError = false, bool escapeHtml = true, bool isWarning = false );
%Docstring
Displays an info ``message`` in the dialog's log.
%End
Expand Down
2 changes: 1 addition & 1 deletion src/analysis/processing/qgsalgorithmclip.cpp
Expand Up @@ -97,7 +97,7 @@ QVariantMap QgsClipAlgorithm::processAlgorithm( const QVariantMap &parameters, Q
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "OVERLAY" ) ) );

if ( featureSource->hasSpatialIndex() == QgsFeatureSource::SpatialIndexNotPresent )
feedback->reportError( QObject::tr( "No spatial index exists for input layer, performance will be severely degraded" ) );
feedback->pushWarning( QObject::tr( "No spatial index exists for input layer, performance will be severely degraded" ) );

QString dest;
QgsWkbTypes::GeometryType sinkType = QgsWkbTypes::geometryType( featureSource->wkbType() );
Expand Down
2 changes: 1 addition & 1 deletion src/analysis/processing/qgsalgorithmextractbyextent.cpp
Expand Up @@ -71,7 +71,7 @@ QVariantMap QgsExtractByExtentAlgorithm::processAlgorithm( const QVariantMap &pa
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );

if ( featureSource->hasSpatialIndex() == QgsFeatureSource::SpatialIndexNotPresent )
feedback->reportError( QObject::tr( "No spatial index exists for input layer, performance will be severely degraded" ) );
feedback->pushWarning( QObject::tr( "No spatial index exists for input layer, performance will be severely degraded" ) );

QgsRectangle extent = parameterAsExtent( parameters, QStringLiteral( "EXTENT" ), context, featureSource->sourceCrs() );
bool clip = parameterAsBoolean( parameters, QStringLiteral( "CLIP" ), context );
Expand Down
2 changes: 1 addition & 1 deletion src/analysis/processing/qgsalgorithmextractbylocation.cpp
Expand Up @@ -215,7 +215,7 @@ void QgsLocationBasedAlgorithm::processByIteratingOverIntersectSource( const Qgs
QgsProcessingFeedback *feedback )
{
if ( targetSource->hasSpatialIndex() == QgsFeatureSource::SpatialIndexNotPresent )
feedback->reportError( QObject::tr( "No spatial index exists for input layer, performance will be severely degraded" ) );
feedback->pushWarning( QObject::tr( "No spatial index exists for input layer, performance will be severely degraded" ) );

// build a list of 'reversed' predicates, because in this function
// we actually test the reverse of what the user wants (allowing us
Expand Down
2 changes: 1 addition & 1 deletion src/analysis/processing/qgsalgorithmjoinbylocation.cpp
Expand Up @@ -313,7 +313,7 @@ bool QgsJoinByLocationAlgorithm::featureFilter( const QgsFeature &feature, QgsGe
void QgsJoinByLocationAlgorithm::processAlgorithmByIteratingOverJoinedSource( QgsProcessingContext &context, QgsProcessingFeedback *feedback )
{
if ( mBaseSource->hasSpatialIndex() == QgsFeatureSource::SpatialIndexNotPresent )
feedback->reportError( QObject::tr( "No spatial index exists for input layer, performance will be severely degraded" ) );
feedback->pushWarning( QObject::tr( "No spatial index exists for input layer, performance will be severely degraded" ) );

QgsFeatureIterator joinIter = mJoinSource->getFeatures( QgsFeatureRequest().setDestinationCrs( mBaseSource->sourceCrs(), context.transformContext() ).setSubsetOfAttributes( mJoinedFieldIndices ) );
QgsFeature f;
Expand Down
14 changes: 14 additions & 0 deletions src/core/processing/qgsprocessingfeedback.cpp
Expand Up @@ -49,6 +49,15 @@ void QgsProcessingFeedback::reportError( const QString &error, bool )
mTextLog.append( error + '\n' );
}

void QgsProcessingFeedback::pushWarning( const QString &warning )
{
if ( mLogFeedback )
QgsMessageLog::logMessage( warning, tr( "Processing" ), Qgis::Warning );

mHtmlLog.append( QStringLiteral( "<span style=\"color:#b85a20;\">%1</span><br/>" ).arg( warning.toHtmlEscaped() ).replace( '\n', QLatin1String( "<br>" ) ) + QStringLiteral( "<br/>" ) );
mTextLog.append( warning + '\n' );
}

void QgsProcessingFeedback::pushInfo( const QString &info )
{
if ( mLogFeedback )
Expand Down Expand Up @@ -152,6 +161,11 @@ void QgsProcessingMultiStepFeedback::reportError( const QString &error, bool fat
mFeedback->reportError( error, fatalError );
}

void QgsProcessingMultiStepFeedback::pushWarning( const QString &warning )
{
mFeedback->pushWarning( warning );
}

void QgsProcessingMultiStepFeedback::pushInfo( const QString &info )
{
mFeedback->pushInfo( info );
Expand Down
17 changes: 17 additions & 0 deletions src/core/processing/qgsprocessingfeedback.h
Expand Up @@ -63,10 +63,23 @@ class CORE_EXPORT QgsProcessingFeedback : public QgsFeedback
*/
virtual void reportError( const QString &error, bool fatalError = false );

/**
* Pushes a warning informational message from the algorithm. This
* should only be used sparsely as to maintain the importance of visual
* queues associated to this type of message.
* \see pushInfo()
* \see pushCommandInfo()
* \see pushDebugInfo()
* \see pushConsoleInfo()
* \since QGIS 3.16.2
*/
virtual void pushWarning( const QString &warning );

/**
* Pushes a general informational message from the algorithm. This can
* be used to report feedback which is neither a status report or an
* error, such as "Found 47 matching features".
* \see pushWarning()
* \see pushCommandInfo()
* \see pushDebugInfo()
* \see pushConsoleInfo()
Expand All @@ -77,6 +90,7 @@ class CORE_EXPORT QgsProcessingFeedback : public QgsFeedback
* Pushes an informational message containing a command from the algorithm.
* This is usually used to report commands which are executed in an external
* application or as subprocesses.
* \see pushWarning()
* \see pushInfo()
* \see pushDebugInfo()
* \see pushConsoleInfo()
Expand All @@ -86,6 +100,7 @@ class CORE_EXPORT QgsProcessingFeedback : public QgsFeedback
/**
* Pushes an informational message containing debugging helpers from
* the algorithm.
* \see pushWarning()
* \see pushInfo()
* \see pushCommandInfo()
* \see pushConsoleInfo()
Expand All @@ -95,6 +110,7 @@ class CORE_EXPORT QgsProcessingFeedback : public QgsFeedback
/**
* Pushes a console feedback message from the algorithm. This is used to
* report the output from executing an external command or subprocess.
* \see pushWarning()
* \see pushInfo()
* \see pushDebugInfo()
* \see pushCommandInfo()
Expand Down Expand Up @@ -164,6 +180,7 @@ class CORE_EXPORT QgsProcessingMultiStepFeedback : public QgsProcessingFeedback

void setProgressText( const QString &text ) override;
void reportError( const QString &error, bool fatalError = false ) override;
void pushWarning( const QString &warning ) override;
void pushInfo( const QString &info ) override;
void pushCommandInfo( const QString &info ) override;
void pushDebugInfo( const QString &info ) override;
Expand Down
19 changes: 16 additions & 3 deletions src/gui/processing/qgsprocessingalgorithmdialogbase.cpp
Expand Up @@ -51,6 +51,12 @@ void QgsProcessingAlgorithmDialogFeedback::reportError( const QString &error, bo
emit errorReported( error, fatalError );
}

void QgsProcessingAlgorithmDialogFeedback::pushWarning( const QString &warning )
{
QgsProcessingFeedback::pushWarning( warning );
emit warningPushed( warning );
}

void QgsProcessingAlgorithmDialogFeedback::pushInfo( const QString &info )
{
QgsProcessingFeedback::pushInfo( info );
Expand Down Expand Up @@ -233,6 +239,7 @@ QgsProcessingFeedback *QgsProcessingAlgorithmDialogBase::createFeedback()
connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::consoleInfoPushed, this, &QgsProcessingAlgorithmDialogBase::pushConsoleInfo );
connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::debugInfoPushed, this, &QgsProcessingAlgorithmDialogBase::pushDebugInfo );
connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::errorReported, this, &QgsProcessingAlgorithmDialogBase::reportError );
connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::warningPushed, this, &QgsProcessingAlgorithmDialogBase::pushWarning );
connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::infoPushed, this, &QgsProcessingAlgorithmDialogBase::pushInfo );
connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::progressTextChanged, this, &QgsProcessingAlgorithmDialogBase::setProgressText );
connect( buttonCancel, &QPushButton::clicked, feedback.get(), &QgsProcessingFeedback::cancel );
Expand Down Expand Up @@ -401,6 +408,12 @@ void QgsProcessingAlgorithmDialogBase::reportError( const QString &error, bool f
processEvents();
}

void QgsProcessingAlgorithmDialogBase::pushWarning( const QString &warning )
{
setInfo( warning, false, true, true );
processEvents();
}

void QgsProcessingAlgorithmDialogBase::pushInfo( const QString &info )
{
setInfo( info );
Expand Down Expand Up @@ -651,12 +664,12 @@ QString QgsProcessingAlgorithmDialogBase::formatStringForLog( const QString &str
return s;
}

void QgsProcessingAlgorithmDialogBase::setInfo( const QString &message, bool isError, bool escapeHtml )
void QgsProcessingAlgorithmDialogBase::setInfo( const QString &message, bool isError, bool escapeHtml, bool isWarning )
{
// note -- we have to wrap the message in a span block, or QTextEdit::append sometimes gets confused
// and varies between treating it as a HTML string or a plain text string! (see https://github.com/qgis/QGIS/issues/37934)
if ( isError )
txtLog->append( QStringLiteral( "<span style=\"color:red\">%1</span>" ).arg( escapeHtml ? formatStringForLog( message.toHtmlEscaped() ) : formatStringForLog( message ) ) );
if ( isError || isWarning )
txtLog->append( QStringLiteral( "<span style=\"color:%1\">%2</span>" ).arg( isError ? QStringLiteral( "red" ) : QStringLiteral( "#b85a20" ), escapeHtml ? formatStringForLog( message.toHtmlEscaped() ) : formatStringForLog( message ) ) );
else if ( escapeHtml )
txtLog->append( QStringLiteral( "<span>%1</span" ).arg( formatStringForLog( message.toHtmlEscaped() ) ) );
else
Expand Down
9 changes: 8 additions & 1 deletion src/gui/processing/qgsprocessingalgorithmdialogbase.h
Expand Up @@ -56,6 +56,7 @@ class QgsProcessingAlgorithmDialogFeedback : public QgsProcessingFeedback

void progressTextChanged( const QString &text );
void errorReported( const QString &text, bool fatalError );
void warningPushed( const QString &text );
void infoPushed( const QString &text );
void commandInfoPushed( const QString &text );
void debugInfoPushed( const QString &text );
Expand All @@ -65,6 +66,7 @@ class QgsProcessingAlgorithmDialogFeedback : public QgsProcessingFeedback

void setProgressText( const QString &text ) override;
void reportError( const QString &error, bool fatalError ) override;
void pushWarning( const QString &info ) override;
void pushInfo( const QString &info ) override;
void pushCommandInfo( const QString &info ) override;
void pushDebugInfo( const QString &info ) override;
Expand Down Expand Up @@ -170,6 +172,11 @@ class GUI_EXPORT QgsProcessingAlgorithmDialogBase : public QDialog, public QgsPr
*/
void reportError( const QString &error, bool fatalError );

/**
* Pushes a warning information string to the dialog's log.
*/
void pushWarning( const QString &warning );

/**
* Pushes an information string to the dialog's log.
*/
Expand Down Expand Up @@ -288,7 +295,7 @@ class GUI_EXPORT QgsProcessingAlgorithmDialogBase : public QDialog, public QgsPr
/**
* Displays an info \a message in the dialog's log.
*/
void setInfo( const QString &message, bool isError = false, bool escapeHtml = true );
void setInfo( const QString &message, bool isError = false, bool escapeHtml = true, bool isWarning = false );

/**
* Resets the dialog's gui, ready for another algorithm execution.
Expand Down
12 changes: 12 additions & 0 deletions src/process/qgsprocess.cpp
Expand Up @@ -74,6 +74,18 @@ void ConsoleFeedback::reportError( const QString &error, bool )
}
}

void ConsoleFeedback::pushWarning( const QString &warning )
{
if ( !mUseJson )
std::cout << "WARNING:\t" << warning.toLocal8Bit().constData() << '\n';
else
{
if ( !mJsonLog.contains( QStringLiteral( "warning" ) ) )
mJsonLog.insert( QStringLiteral( "warning" ), QStringList() );
mJsonLog[ QStringLiteral( "warning" )] = mJsonLog.value( QStringLiteral( "warning" ) ).toStringList() << warning;
}
}

void ConsoleFeedback::pushInfo( const QString &info )
{
if ( !mUseJson )
Expand Down
1 change: 1 addition & 0 deletions src/process/qgsprocess.h
Expand Up @@ -42,6 +42,7 @@ class ConsoleFeedback : public QgsProcessingFeedback

void setProgressText( const QString &text ) override;
void reportError( const QString &error, bool fatalError ) override;
void pushWarning( const QString &warning ) override;
void pushInfo( const QString &info ) override;
void pushCommandInfo( const QString &info ) override;
void pushDebugInfo( const QString &info ) override;
Expand Down

0 comments on commit 04b9c6a

Please sign in to comment.