Skip to content

Commit

Permalink
Make QgsProcessingFeedback remember logged messages for later recall
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Mar 31, 2020
1 parent 72eae44 commit 0684d41
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 6 deletions.
26 changes: 26 additions & 0 deletions python/core/auto_generated/processing/qgsprocessingfeedback.sip.in
Expand Up @@ -27,6 +27,14 @@ it to users via the GUI.
%End
public:

QgsProcessingFeedback( bool logFeedback = true );
%Docstring
Constructor for QgsProcessingFeedback.

If ``logFeedback`` is ``True``, then all feedback received will be directed
to :py:class:`QgsMessageLog`.
%End

virtual void setProgressText( const QString &text );
%Docstring
Sets a progress report text string. This can be used in conjunction with
Expand Down Expand Up @@ -98,6 +106,24 @@ report the output from executing an external command or subprocess.
Pushes a summary of the QGIS (and underlying library) version information to the log.

.. versionadded:: 3.4.7
%End

QString htmlLog() const;
%Docstring
Returns the HTML formatted contents of the log, which contains all messages pushed to the feedback object.

.. seealso:: :py:func:`textLog`

.. versionadded:: 3.14
%End

QString textLog() const;
%Docstring
Returns the plain text contents of the log, which contains all messages pushed to the feedback object.

.. seealso:: :py:func:`htmlLog`

.. versionadded:: 3.14
%End

};
Expand Down
36 changes: 31 additions & 5 deletions src/core/processing/qgsprocessingfeedback.cpp
Expand Up @@ -26,33 +26,59 @@
#include <proj_api.h>
#endif

QgsProcessingFeedback::QgsProcessingFeedback( bool logFeedback )
: mLogFeedback( logFeedback )
{

}

void QgsProcessingFeedback::setProgressText( const QString & )
{
}

void QgsProcessingFeedback::reportError( const QString &error, bool )
{
QgsMessageLog::logMessage( error, tr( "Processing" ), Qgis::Critical );
if ( mLogFeedback )
QgsMessageLog::logMessage( error, tr( "Processing" ), Qgis::Critical );

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

void QgsProcessingFeedback::pushInfo( const QString &info )
{
QgsMessageLog::logMessage( info, tr( "Processing" ), Qgis::Info );
if ( mLogFeedback )
QgsMessageLog::logMessage( info, tr( "Processing" ), Qgis::Info );

mHtmlLog.append( info.toHtmlEscaped().replace( '\n', QStringLiteral( "<br>" ) ) + QStringLiteral( "<br/>" ) );
mTextLog.append( info + '\n' );
}

void QgsProcessingFeedback::pushCommandInfo( const QString &info )
{
QgsMessageLog::logMessage( info, tr( "Processing" ), Qgis::Info );
if ( mLogFeedback )
QgsMessageLog::logMessage( info, tr( "Processing" ), Qgis::Info );

mHtmlLog.append( QStringLiteral( "<code>%1</code><br/>" ).arg( info.toHtmlEscaped().replace( '\n', QStringLiteral( "<br>" ) ) ) );
mTextLog.append( info + '\n' );
}

void QgsProcessingFeedback::pushDebugInfo( const QString &info )
{
QgsMessageLog::logMessage( info, tr( "Processing" ), Qgis::Info );
if ( mLogFeedback )
QgsMessageLog::logMessage( info, tr( "Processing" ), Qgis::Info );

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

void QgsProcessingFeedback::pushConsoleInfo( const QString &info )
{
QgsMessageLog::logMessage( info, tr( "Processing" ), Qgis::Info );
if ( mLogFeedback )
QgsMessageLog::logMessage( info, tr( "Processing" ), Qgis::Info );

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

void QgsProcessingFeedback::pushVersionInfo( const QgsProcessingProvider *provider )
Expand Down
29 changes: 29 additions & 0 deletions src/core/processing/qgsprocessingfeedback.h
Expand Up @@ -40,6 +40,14 @@ class CORE_EXPORT QgsProcessingFeedback : public QgsFeedback

public:

/**
* Constructor for QgsProcessingFeedback.
*
* If \a logFeedback is TRUE, then all feedback received will be directed
* to QgsMessageLog.
*/
QgsProcessingFeedback( bool logFeedback = true );

/**
* Sets a progress report text string. This can be used in conjunction with
* setProgress() to provide detailed progress reports, such as "Transformed
Expand Down Expand Up @@ -99,6 +107,27 @@ class CORE_EXPORT QgsProcessingFeedback : public QgsFeedback
*/
void pushVersionInfo( const QgsProcessingProvider *provider = nullptr );

/**
* Returns the HTML formatted contents of the log, which contains all messages pushed to the feedback object.
*
* \see textLog()
* \since QGIS 3.14
*/
QString htmlLog() const { return mHtmlLog; }

/**
* Returns the plain text contents of the log, which contains all messages pushed to the feedback object.
*
* \see htmlLog()
* \since QGIS 3.14
*/
QString textLog() const { return mTextLog; }

private:
bool mLogFeedback = true;
QString mHtmlLog;
QString mTextLog;

};


Expand Down
10 changes: 10 additions & 0 deletions src/gui/processing/qgsprocessingalgorithmdialogbase.cpp
Expand Up @@ -35,33 +35,43 @@

///@cond NOT_STABLE

QgsProcessingAlgorithmDialogFeedback::QgsProcessingAlgorithmDialogFeedback()
: QgsProcessingFeedback( false )
{}

void QgsProcessingAlgorithmDialogFeedback::setProgressText( const QString &text )
{
QgsProcessingFeedback::setProgressText( text );
emit progressTextChanged( text );
}

void QgsProcessingAlgorithmDialogFeedback::reportError( const QString &error, bool fatalError )
{
QgsProcessingFeedback::reportError( error, fatalError );
emit errorReported( error, fatalError );
}

void QgsProcessingAlgorithmDialogFeedback::pushInfo( const QString &info )
{
QgsProcessingFeedback::pushInfo( info );
emit infoPushed( info );
}

void QgsProcessingAlgorithmDialogFeedback::pushCommandInfo( const QString &info )
{
QgsProcessingFeedback::pushCommandInfo( info );
emit commandInfoPushed( info );
}

void QgsProcessingAlgorithmDialogFeedback::pushDebugInfo( const QString &info )
{
QgsProcessingFeedback::pushDebugInfo( info );
emit debugInfoPushed( info );
}

void QgsProcessingAlgorithmDialogFeedback::pushConsoleInfo( const QString &info )
{
QgsProcessingFeedback::pushConsoleInfo( info );
emit consoleInfoPushed( info );
}

Expand Down
2 changes: 1 addition & 1 deletion src/gui/processing/qgsprocessingalgorithmdialogbase.h
Expand Up @@ -49,7 +49,7 @@ class QgsProcessingAlgorithmDialogFeedback : public QgsProcessingFeedback
/**
* Constructor for QgsProcessingAlgorithmDialogFeedback.
*/
QgsProcessingAlgorithmDialogFeedback() = default;
QgsProcessingAlgorithmDialogFeedback();

signals:

Expand Down
14 changes: 14 additions & 0 deletions tests/src/analysis/testqgsprocessing.cpp
Expand Up @@ -521,6 +521,7 @@ class TestQgsProcessing: public QObject
void encodeDecodeUriProvider();
void normalizeLayerSource();
void context();
void feedback();
void mapLayers();
void mapLayerFromStore();
void mapLayerFromString();
Expand Down Expand Up @@ -1056,6 +1057,19 @@ void TestQgsProcessing::context()
QVERIFY( !context2.temporaryLayerStore()->mapLayer( id ) );
}

void TestQgsProcessing::feedback()
{
QgsProcessingFeedback f;
f.pushInfo( QStringLiteral( "info" ) );
f.reportError( QStringLiteral( "error" ) );
f.pushDebugInfo( QStringLiteral( "debug" ) );
f.pushCommandInfo( QStringLiteral( "command" ) );
f.pushConsoleInfo( QStringLiteral( "console" ) );

QCOMPARE( f.htmlLog(), QStringLiteral( "info<br/><span style=\"color:red\">error</span><br/><span style=\"color:#777\">debug</span><br/><code>command</code><br/><code style=\"color:#777\">console</code><br/>" ) );
QCOMPARE( f.textLog(), QStringLiteral( "info\nerror\ndebug\ncommand\nconsole\n" ) );
}

void TestQgsProcessing::mapLayers()
{
QString testDataDir = QStringLiteral( TEST_DATA_DIR ) + '/'; //defined in CmakeLists.txt
Expand Down

0 comments on commit 0684d41

Please sign in to comment.