Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[processing] Move recent algorithm log to c++ class
  • Loading branch information
nyalldawson committed Jul 4, 2018
1 parent d66d1ee commit d232cde
Show file tree
Hide file tree
Showing 10 changed files with 315 additions and 0 deletions.
@@ -0,0 +1,72 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/processing/qgsprocessingrecentalgorithmlog.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/




class QgsProcessingRecentAlgorithmLog : QObject
{
%Docstring
A log for tracking recently used processing algorithms.

QgsProcessingRecentAlgorithmLog is not usually directly created, instead
use the instance accessible through :py:func:`QgsGui.processingRecentAlgorithmLog()`

The log contents are saved and restored via QgsSettings.

.. note::

Not stable API

.. versionadded:: 3.4
%End

%TypeHeaderCode
#include "qgsprocessingrecentalgorithmlog.h"
%End
public:

QgsProcessingRecentAlgorithmLog( QObject *parent = 0 );
%Docstring
Constructor for QgsProcessingRecentAlgorithmLog, with the specified
``parent`` object.
%End

QStringList recentAlgorithmIds() const;
%Docstring
Returns a list of the IDs of recently used processing algorithms, where the
first item in the list is the most recently used algorithm.
%End

void push( const QString &id );
%Docstring
Pushes the algorithm with matching ``id`` to the top of the recently used
algorithm list.

If this changes the list of recent algorithm IDs then the changed() signal
will be emitted.
%End

signals:

void changed();
%Docstring
Emitted when the list of recently used algorithms is changed, e.g. when
a new algorithm ID is pushed to the list (see push()).
%End

};


/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/processing/qgsprocessingrecentalgorithmlog.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
7 changes: 7 additions & 0 deletions python/gui/auto_generated/qgsgui.sip.in
Expand Up @@ -67,6 +67,13 @@ Returns the global layout item GUI registry, used for registering the GUI behavi
Returns the global processing gui registry, used for registering the GUI behavior of processing algorithms.

.. versionadded:: 3.2
%End

static QgsProcessingRecentAlgorithmLog *processingRecentAlgorithmLog();
%Docstring
Returns the global processing recent algorithm log, used for tracking recently used processing algorithms.

.. versionadded:: 3.4
%End

static void enableAutoGeometryRestore( QWidget *widget, const QString &key = QString() );
Expand Down
1 change: 1 addition & 0 deletions python/gui/gui_auto.sip
Expand Up @@ -315,4 +315,5 @@
%Include auto_generated/locator/qgslocatorwidget.sip
%Include auto_generated/processing/qgsprocessingalgorithmconfigurationwidget.sip
%Include auto_generated/processing/qgsprocessingalgorithmdialogbase.sip
%Include auto_generated/processing/qgsprocessingrecentalgorithmlog.sip
%Include auto_generated/qgsadvanceddigitizingcanvasitem.sip
2 changes: 2 additions & 0 deletions src/gui/CMakeLists.txt
Expand Up @@ -197,6 +197,7 @@ SET(QGIS_GUI_SRCS
processing/qgsprocessingalgorithmdialogbase.cpp
processing/qgsprocessingconfigurationwidgets.cpp
processing/qgsprocessingguiregistry.cpp
processing/qgsprocessingrecentalgorithmlog.cpp

qgisinterface.cpp
qgsactionmenu.cpp
Expand Down Expand Up @@ -717,6 +718,7 @@ SET(QGIS_GUI_MOC_HDRS
processing/qgsprocessingalgorithmconfigurationwidget.h
processing/qgsprocessingalgorithmdialogbase.h
processing/qgsprocessingconfigurationwidgets.h
processing/qgsprocessingrecentalgorithmlog.h
)
SET_PROPERTY(GLOBAL PROPERTY QGIS_GUI_MOC_HDRS ${QGIS_GUI_MOC_HDRS})

Expand Down
50 changes: 50 additions & 0 deletions src/gui/processing/qgsprocessingrecentalgorithmlog.cpp
@@ -0,0 +1,50 @@
/***************************************************************************
qgsprocessingrecentalgorithmlog.cpp
------------------------------------
Date : July 2018
Copyright : (C) 2018 Nyall Dawson
Email : nyall dot dawson at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsprocessingrecentalgorithmlog.h"
#include "qgssettings.h"

///@cond PRIVATE

const int MAX_LOG_LENGTH = 5;

QgsProcessingRecentAlgorithmLog::QgsProcessingRecentAlgorithmLog( QObject *parent )
: QObject( parent )
{
QgsSettings settings;
mRecentAlgorithmIds = settings.value( QStringLiteral( "processing/recentAlgorithms" ), QVariant(), QgsSettings::Gui ).toStringList();
}

QStringList QgsProcessingRecentAlgorithmLog::recentAlgorithmIds() const
{
return mRecentAlgorithmIds;
}

void QgsProcessingRecentAlgorithmLog::push( const QString &id )
{
const QStringList previous = mRecentAlgorithmIds;
mRecentAlgorithmIds.removeAll( id );
mRecentAlgorithmIds.insert( 0, id );
if ( mRecentAlgorithmIds.length() > MAX_LOG_LENGTH )
mRecentAlgorithmIds = mRecentAlgorithmIds.mid( 0, MAX_LOG_LENGTH );

QgsSettings settings;
settings.setValue( QStringLiteral( "processing/recentAlgorithms" ), mRecentAlgorithmIds, QgsSettings::Gui );

if ( previous != mRecentAlgorithmIds )
emit changed();
}

///@endcond
79 changes: 79 additions & 0 deletions src/gui/processing/qgsprocessingrecentalgorithmlog.h
@@ -0,0 +1,79 @@
/***************************************************************************
qgsprocessingrecentalgorithmlog.h
----------------------------------
Date : July 2018
Copyright : (C) 2018 Nyall Dawson
Email : nyall dot dawson at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSPROCESSINGRECENTALGORITHMLOG_H
#define QGSPROCESSINGRECENTALGORITHMLOG_H

#include "qgis.h"
#include "qgis_gui.h"

///@cond NOT_STABLE

/**
* \ingroup gui
* \brief A log for tracking recently used processing algorithms.
*
* QgsProcessingRecentAlgorithmLog is not usually directly created, instead
* use the instance accessible through QgsGui::processingRecentAlgorithmLog().
*
* The log contents are saved and restored via QgsSettings.
*
* \note Not stable API
* \since QGIS 3.4
*/
class GUI_EXPORT QgsProcessingRecentAlgorithmLog : public QObject
{
Q_OBJECT

public:

/**
* Constructor for QgsProcessingRecentAlgorithmLog, with the specified
* \a parent object.
*/
QgsProcessingRecentAlgorithmLog( QObject *parent = nullptr );

/**
* Returns a list of the IDs of recently used processing algorithms, where the
* first item in the list is the most recently used algorithm.
*/
QStringList recentAlgorithmIds() const;

/**
* Pushes the algorithm with matching \a id to the top of the recently used
* algorithm list.
*
* If this changes the list of recent algorithm IDs then the changed() signal
* will be emitted.
*/
void push( const QString &id );

signals:

/**
* Emitted when the list of recently used algorithms is changed, e.g. when
* a new algorithm ID is pushed to the list (see push()).
*/
void changed();

private:

QStringList mRecentAlgorithmIds;

};

///@endcond

#endif // QGSPROCESSINGRECENTALGORITHMLOG_H
8 changes: 8 additions & 0 deletions src/gui/qgsgui.cpp
Expand Up @@ -32,6 +32,7 @@
#include "qgsshortcutsmanager.h"
#include "qgswidgetstatehelper_p.h"
#include "qgslogger.h"
#include "qgsprocessingrecentalgorithmlog.h"

QgsGui *QgsGui::instance()
{
Expand Down Expand Up @@ -79,6 +80,11 @@ QgsProcessingGuiRegistry *QgsGui::processingGuiRegistry()
return instance()->mProcessingGuiRegistry;
}

QgsProcessingRecentAlgorithmLog *QgsGui::processingRecentAlgorithmLog()
{
return instance()->mProcessingRecentAlgorithmLog;
}

void QgsGui::enableAutoGeometryRestore( QWidget *widget, const QString &key )
{
if ( widget->objectName().isEmpty() )
Expand All @@ -91,6 +97,7 @@ void QgsGui::enableAutoGeometryRestore( QWidget *widget, const QString &key )
QgsGui::~QgsGui()
{
delete mProcessingGuiRegistry;
delete mProcessingRecentAlgorithmLog;
delete mLayoutItemGuiRegistry;
delete mLayerTreeEmbeddedWidgetRegistry;
delete mEditorWidgetRegistry;
Expand All @@ -116,5 +123,6 @@ QgsGui::QgsGui()
mSourceSelectProviderRegistry = new QgsSourceSelectProviderRegistry();
mLayoutItemGuiRegistry = new QgsLayoutItemGuiRegistry();
mWidgetStateHelper = new QgsWidgetStateHelper();
mProcessingRecentAlgorithmLog = new QgsProcessingRecentAlgorithmLog();
mProcessingGuiRegistry = new QgsProcessingGuiRegistry();
}
8 changes: 8 additions & 0 deletions src/gui/qgsgui.h
Expand Up @@ -31,6 +31,7 @@ class QgsNative;
class QgsLayoutItemGuiRegistry;
class QgsWidgetStateHelper;
class QgsProcessingGuiRegistry;
class QgsProcessingRecentAlgorithmLog;

/**
* \ingroup gui
Expand Down Expand Up @@ -96,6 +97,12 @@ class GUI_EXPORT QgsGui
*/
static QgsProcessingGuiRegistry *processingGuiRegistry();

/**
* Returns the global processing recent algorithm log, used for tracking recently used processing algorithms.
* \since QGIS 3.4
*/
static QgsProcessingRecentAlgorithmLog *processingRecentAlgorithmLog();

/**
* Register the widget to allow its position to be automatically saved and restored when open and closed.
* Use this to avoid needing to call saveGeometry() and restoreGeometry() on your widget.
Expand All @@ -117,6 +124,7 @@ class GUI_EXPORT QgsGui
QgsMapLayerActionRegistry *mMapLayerActionRegistry = nullptr;
QgsLayoutItemGuiRegistry *mLayoutItemGuiRegistry = nullptr;
QgsProcessingGuiRegistry *mProcessingGuiRegistry = nullptr;
QgsProcessingRecentAlgorithmLog *mProcessingRecentAlgorithmLog = nullptr;

#ifdef SIP_RUN
QgsGui( const QgsGui &other );
Expand Down
1 change: 1 addition & 0 deletions tests/src/python/CMakeLists.txt
Expand Up @@ -140,6 +140,7 @@ ADD_PYTHON_TEST(PyQgsPoint test_qgspoint.py)
ADD_PYTHON_TEST(PyQgsPointClusterRenderer test_qgspointclusterrenderer.py)
ADD_PYTHON_TEST(PyQgsPointDisplacementRenderer test_qgspointdisplacementrenderer.py)
ADD_PYTHON_TEST(PyQgsPostgresDomain test_qgspostgresdomain.py)
ADD_PYTHON_TEST(PyQgsProcessingRecentAlgorithmLog test_qgsprocessingrecentalgorithmslog.py)
ADD_PYTHON_TEST(PyQgsProjectionSelectionWidgets test_qgsprojectionselectionwidgets.py)
ADD_PYTHON_TEST(PyQgsProjectMetadata test_qgsprojectmetadata.py)
ADD_PYTHON_TEST(PyQgsRange test_qgsrange.py)
Expand Down
87 changes: 87 additions & 0 deletions tests/src/python/test_qgsprocessingrecentalgorithmslog.py
@@ -0,0 +1,87 @@
# -*- coding: utf-8 -*-
"""QGIS Unit tests for QgsProcessingRecentAlgorithmLog.
.. note:: This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
"""
__author__ = 'Nyall Dawson'
__date__ = '2018-07'
__copyright__ = 'Copyright 2018, The QGIS Project'
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'

from qgis.PyQt.QtCore import QCoreApplication
from qgis.core import QgsSettings
from qgis.gui import QgsProcessingRecentAlgorithmLog, QgsGui
from qgis.testing import start_app, unittest
from qgis.PyQt.QtTest import QSignalSpy

start_app()


class TestQgsProcessingRecentAlgorithmLog(unittest.TestCase):

@classmethod
def setUpClass(cls):
"""Run before all tests"""
QCoreApplication.setOrganizationName("QGIS_Test")
QCoreApplication.setOrganizationDomain("QGIS_TestPyQgsNewGeoPackageLayerDialog.com")
QCoreApplication.setApplicationName("QGIS_TestPyQgsNewGeoPackageLayerDialog")
QgsSettings().clear()

def test_log(self):
log = QgsProcessingRecentAlgorithmLog()
self.assertFalse(log.recentAlgorithmIds())
spy = QSignalSpy(log.changed)

log.push('test')
self.assertEqual(log.recentAlgorithmIds(), ['test'])
self.assertEqual(len(spy), 1)
log.push('test')
self.assertEqual(log.recentAlgorithmIds(), ['test'])
self.assertEqual(len(spy), 1)

log.push('test2')
self.assertEqual(log.recentAlgorithmIds(), ['test2', 'test'])
self.assertEqual(len(spy), 2)

log.push('test')
self.assertEqual(log.recentAlgorithmIds(), ['test', 'test2'])
self.assertEqual(len(spy), 3)

log.push('test3')
self.assertEqual(log.recentAlgorithmIds(), ['test3', 'test', 'test2'])
self.assertEqual(len(spy), 4)

log.push('test4')
self.assertEqual(log.recentAlgorithmIds(), ['test4', 'test3', 'test', 'test2'])
self.assertEqual(len(spy), 5)

log.push('test5')
self.assertEqual(log.recentAlgorithmIds(), ['test5', 'test4', 'test3', 'test', 'test2'])
self.assertEqual(len(spy), 6)

log.push('test6')
self.assertEqual(log.recentAlgorithmIds(), ['test6', 'test5', 'test4', 'test3', 'test'])
self.assertEqual(len(spy), 7)

log.push('test3')
self.assertEqual(log.recentAlgorithmIds(), ['test3', 'test6', 'test5', 'test4', 'test'])
self.assertEqual(len(spy), 8)

log.push('test3')
self.assertEqual(log.recentAlgorithmIds(), ['test3', 'test6', 'test5', 'test4', 'test'])
self.assertEqual(len(spy), 8)

# test that log has been saved to QgsSettings
log2 = QgsProcessingRecentAlgorithmLog()
self.assertEqual(log2.recentAlgorithmIds(), ['test3', 'test6', 'test5', 'test4', 'test'])

def test_gui_instance(self):
self.assertIsNotNone(QgsGui.instance().processingRecentAlgorithmLog())


if __name__ == '__main__':
unittest.main()

0 comments on commit d232cde

Please sign in to comment.