Skip to content
Permalink
Browse files

[FEATURE][processing] Add buttons to save/clear/copy log

In the algorithm execution dialog, this adds buttons to allow
users to save the current log (to text or HTML files), copy the
log contents to the clipboard, and clear the log.
  • Loading branch information
nyalldawson committed Apr 20, 2018
1 parent 0dfb3c2 commit 4a594d3f32c47059af35ff42b7ba2d81d8212257
@@ -28,6 +28,12 @@ class QgsProcessingAlgorithmDialogBase : QDialog
%End
public:

enum LogFormat
{
FormatPlainText,
FormatHtml,
};

QgsProcessingAlgorithmDialogBase( QWidget *parent = 0, Qt::WindowFlags flags = 0 );
%Docstring
Constructor for QgsProcessingAlgorithmDialogBase.
@@ -93,6 +99,16 @@ slots in this dialog.
virtual QVariantMap getParameterValues() const;
%Docstring
Returns the parameter values for the algorithm to run in the dialog.
%End

void saveLogToFile( const QString &path, LogFormat format = FormatPlainText );
%Docstring
Saves the log contents to a text file (specified by the file ``path``), in
the given ``format``.

.. versionadded:: 3.2

.. seealso:: :py:func:`saveLog`
%End

public slots:
@@ -141,6 +157,29 @@ Pushes a console info string to the dialog's log.
%Docstring
Creates a modal progress dialog showing progress and log messages
from this dialog.
%End

void clearLog();
%Docstring
Clears the current log contents.

.. versionadded:: 3.2
%End

void saveLog();
%Docstring
Opens a dialog allowing users to save the current log contents.

.. versionadded:: 3.2

.. seealso:: :py:func:`saveLogToFile`
%End

void copyLogToClipboard();
%Docstring
Copies the current log contents to the clipboard.

.. versionadded:: 3.2
%End

protected:
@@ -25,6 +25,10 @@
#include <QToolButton>
#include <QDesktopServices>
#include <QScrollBar>
#include <QApplication>
#include <QClipboard>
#include <QFileDialog>


///@cond NOT_STABLE

@@ -108,6 +112,10 @@ QgsProcessingAlgorithmDialogBase::QgsProcessingAlgorithmDialogBase( QWidget *par
connect( mButtonCollapse, &QToolButton::clicked, this, &QgsProcessingAlgorithmDialogBase::toggleCollapsed );
connect( splitter, &QSplitter::splitterMoved, this, &QgsProcessingAlgorithmDialogBase::splitterChanged );

connect( mButtonSaveLog, &QToolButton::clicked, this, &QgsProcessingAlgorithmDialogBase::saveLog );
connect( mButtonCopyLog, &QToolButton::clicked, this, &QgsProcessingAlgorithmDialogBase::copyLogToClipboard );
connect( mButtonClearLog, &QToolButton::clicked, this, &QgsProcessingAlgorithmDialogBase::clearLog );

mMessageBar = new QgsMessageBar();
mMessageBar->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed );
verticalLayout->insertWidget( 0, mMessageBar );
@@ -165,6 +173,27 @@ QVariantMap QgsProcessingAlgorithmDialogBase::getParameterValues() const
return QVariantMap();
}

void QgsProcessingAlgorithmDialogBase::saveLogToFile( const QString &path, const LogFormat format )
{
QFile logFile( path );
if ( !logFile.open( QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate ) )
{
return;
}
QTextStream fout( &logFile );

switch ( format )
{
case FormatPlainText:
fout << txtLog->toPlainText();
break;

case FormatHtml:
fout << txtLog->toHtml();
break;
}
}

QgsProcessingFeedback *QgsProcessingAlgorithmDialogBase::createFeedback()
{
auto feedback = qgis::make_unique< QgsProcessingAlgorithmDialogFeedback >();
@@ -369,6 +398,49 @@ QDialog *QgsProcessingAlgorithmDialogBase::createProgressDialog()
return dialog;
}

void QgsProcessingAlgorithmDialogBase::clearLog()
{
txtLog->clear();
}

void QgsProcessingAlgorithmDialogBase::saveLog()
{
QgsSettings settings;
QString lastUsedDir = settings.value( QStringLiteral( "/Processing/lastUsedLogDirectory" ), QDir::homePath() ).toString();

QString filter;
const QString txtExt = tr( "Text files" ) + QStringLiteral( " (*.txt *.TXT)" );
const QString htmlExt = tr( "HTML files" ) + QStringLiteral( " (*.html *.HTML)" );

QString path = QFileDialog::getSaveFileName( this, tr( "Save Log to File" ), lastUsedDir, txtExt + ";;" + htmlExt, &filter );
if ( path.isEmpty() )
{
return;
}

settings.setValue( QStringLiteral( "/Processing/lastUsedLogDirectory" ), QFileInfo( path ).path() );

LogFormat format = FormatPlainText;
if ( filter == htmlExt )
{
format = FormatHtml;
}
saveLogToFile( path, format );
}

void QgsProcessingAlgorithmDialogBase::copyLogToClipboard()
{
QMimeData *m = new QMimeData();
m->setText( txtLog->toPlainText() );
m->setHtml( txtLog->toHtml() );
QClipboard *cb = QApplication::clipboard();

#ifdef Q_OS_LINUX
cb->setMimeData( m, QClipboard::Selection );
#endif
cb->setMimeData( m, QClipboard::Clipboard );
}

void QgsProcessingAlgorithmDialogBase::closeEvent( QCloseEvent *e )
{
QDialog::closeEvent( e );
@@ -85,6 +85,16 @@ class GUI_EXPORT QgsProcessingAlgorithmDialogBase : public QDialog, private Ui::

public:

/**
* Log format options.
* \since QGIS 3.2
*/
enum LogFormat
{
FormatPlainText, //!< Plain text file (.txt)
FormatHtml, //!< HTML file (.html)
};

/**
* Constructor for QgsProcessingAlgorithmDialogBase.
*/
@@ -144,6 +154,14 @@ class GUI_EXPORT QgsProcessingAlgorithmDialogBase : public QDialog, private Ui::
*/
virtual QVariantMap getParameterValues() const;

/**
* Saves the log contents to a text file (specified by the file \a path), in
* the given \a format.
* \since QGIS 3.2
* \see saveLog()
*/
void saveLogToFile( const QString &path, LogFormat format = FormatPlainText );

public slots:

void accept() override;
@@ -191,6 +209,25 @@ class GUI_EXPORT QgsProcessingAlgorithmDialogBase : public QDialog, private Ui::
*/
QDialog *createProgressDialog();

/**
* Clears the current log contents.
* \since QGIS 3.2
*/
void clearLog();

/**
* Opens a dialog allowing users to save the current log contents.
* \since QGIS 3.2
* \see saveLogToFile()
*/
void saveLog();

/**
* Copies the current log contents to the clipboard.
* \since QGIS 3.2
*/
void copyLogToClipboard();

protected:

void closeEvent( QCloseEvent *e ) override;
@@ -87,6 +87,77 @@
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="mButtonSaveLog">
<property name="toolTip">
<string>Save Log to File</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../../images/images.qrc">
<normaloff>:/images/themes/default/mActionFileSave.svg</normaloff>:/images/themes/default/mActionFileSave.svg</iconset>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="mButtonCopyLog">
<property name="toolTip">
<string>Copy Log to Clipboard</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../../images/images.qrc">
<normaloff>:/images/themes/default/mActionEditCopy.svg</normaloff>:/images/themes/default/mActionEditCopy.svg</iconset>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="mButtonClearLog">
<property name="toolTip">
<string>Clear Log</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../../images/images.qrc">
<normaloff>:/images/themes/default/console/iconClearConsole.svg</normaloff>:/images/themes/default/console/iconClearConsole.svg</iconset>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
@@ -146,6 +217,37 @@
</item>
</layout>
</widget>
<resources/>
<resources>
<include location="../../../images/images.qrc"/>
<include location="../../../images/images.qrc"/>
<include location="../../../images/images.qrc"/>
<include location="../../../images/images.qrc"/>
<include location="../../../images/images.qrc"/>
<include location="../../../images/images.qrc"/>
<include location="../../../images/images.qrc"/>
<include location="../../../images/images.qrc"/>
<include location="../../../images/images.qrc"/>
<include location="../../../images/images.qrc"/>
<include location="../../../images/images.qrc"/>
<include location="../../../images/images.qrc"/>
<include location="../../../images/images.qrc"/>
<include location="../../../images/images.qrc"/>
<include location="../../../images/images.qrc"/>
<include location="../../../images/images.qrc"/>
<include location="../../../images/images.qrc"/>
<include location="../../../images/images.qrc"/>
<include location="../../../images/images.qrc"/>
<include location="../../../images/images.qrc"/>
<include location="../../../images/images.qrc"/>
<include location="../../../images/images.qrc"/>
<include location="../../../images/images.qrc"/>
<include location="../../../images/images.qrc"/>
<include location="../../../images/images.qrc"/>
<include location="../../../images/images.qrc"/>
<include location="../../../images/images.qrc"/>
<include location="../../../images/images.qrc"/>
<include location="../../../images/images.qrc"/>
<include location="../../../images/images.qrc"/>
</resources>
<connections/>
</ui>

0 comments on commit 4a594d3

Please sign in to comment.
You can’t perform that action at this time.