Skip to content

Commit

Permalink
[FEATURE][processing] Add buttons to save/clear/copy log
Browse files Browse the repository at this point in the history
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 4a594d3
Show file tree
Hide file tree
Showing 4 changed files with 251 additions and 1 deletion.
39 changes: 39 additions & 0 deletions python/gui/processing/qgsprocessingalgorithmdialogbase.sip.in
Expand Up @@ -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.
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down
72 changes: 72 additions & 0 deletions src/gui/processing/qgsprocessingalgorithmdialogbase.cpp
Expand Up @@ -25,6 +25,10 @@
#include <QToolButton>
#include <QDesktopServices>
#include <QScrollBar>
#include <QApplication>
#include <QClipboard>
#include <QFileDialog>


///@cond NOT_STABLE

Expand Down Expand Up @@ -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 );
Expand Down Expand Up @@ -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 >();
Expand Down Expand Up @@ -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 );
Expand Down
37 changes: 37 additions & 0 deletions src/gui/processing/qgsprocessingalgorithmdialogbase.h
Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
104 changes: 103 additions & 1 deletion src/ui/processing/qgsprocessingalgorithmdialogbase.ui
Expand Up @@ -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>
Expand Down Expand Up @@ -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.