Skip to content
Permalink
Browse files

Merge pull request #42326 from 3nids/filter-svg

Add filtering capabilities to SVG selector widget
  • Loading branch information
3nids committed Mar 22, 2021
2 parents 74733e0 + 413848c commit 959d68a1e7cc32364030274493287a1f25ea0252
@@ -13,6 +13,32 @@



class QgsSvgSelectorFilterModel : QSortFilterProxyModel
{
%Docstring
A model for displaying SVG files with a preview icon which can be filtered by file name.
Population of the model is performed in a background thread to ensure that
initial creation of the model is responsive and does not block the GUI.

.. versionadded:: 3.20
%End

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

QgsSvgSelectorFilterModel( QObject *parent /TransferThis/, const QString &path = QString(), int iconSize = 30 );
%Docstring
Constructor for creating a model for SVG files in a specific path.

:param parent: parent object
:param path: initial path, which is recursively searched
:param iconSize: desired size of SVG icons to create
%End

};

class QgsSvgSelectorListModel : QAbstractListModel
{
%Docstring
@@ -29,6 +29,7 @@
#include "qgsvectorlayer.h"

#include <QAbstractListModel>
#include <QSortFilterProxyModel>
#include <QCheckBox>
#include <QDir>
#include <QFileDialog>
@@ -216,19 +217,25 @@ void QgsSvgGroupLoader::loadGroup( const QString &parentPath )

///@endcond




QgsSvgSelectorFilterModel::QgsSvgSelectorFilterModel( QObject *parent, const QString &path, int iconSize )
: QSortFilterProxyModel( parent )
{
mModel = new QgsSvgSelectorListModel( parent, path, iconSize );
setFilterCaseSensitivity( Qt::CaseInsensitive );
setSourceModel( mModel );
setFilterRole( Qt::UserRole );
}

//,
// QgsSvgSelectorListModel
//

QgsSvgSelectorListModel::QgsSvgSelectorListModel( QObject *parent, int iconSize )
: QAbstractListModel( parent )
, mSvgLoader( new QgsSvgSelectorLoader( this ) )
, mIconSize( iconSize )
{
mSvgLoader->setPath( QString() );
connect( mSvgLoader, &QgsSvgSelectorLoader::foundSvgs, this, &QgsSvgSelectorListModel::addSvgs );
mSvgLoader->start();
}
: QgsSvgSelectorListModel( parent, QString(), iconSize )
{}

QgsSvgSelectorListModel::QgsSvgSelectorListModel( QObject *parent, const QString &path, int iconSize )
: QAbstractListModel( parent )
@@ -395,6 +402,18 @@ QgsSvgSelectorWidget::QgsSvgSelectorWidget( QWidget *parent )
mGroupsTreeView->setHeaderHidden( true );
populateList();

connect( mSvgFilterLineEdit, &QgsFilterLineEdit::textChanged, this, [ = ]( const QString & filterText )
{
if ( !mImagesListView->selectionModel()->selectedIndexes().isEmpty() )
{
disconnect( mImagesListView->selectionModel(), &QItemSelectionModel::currentChanged, this, &QgsSvgSelectorWidget::svgSelectionChanged );
mImagesListView->selectionModel()->clearSelection();
connect( mImagesListView->selectionModel(), &QItemSelectionModel::currentChanged, this, &QgsSvgSelectorWidget::svgSelectionChanged );
}
qobject_cast<QgsSvgSelectorFilterModel *>( mImagesListView->model() )->setFilterFixedString( filterText );
} );


mParametersModel = new QgsSvgParametersModel( this );
mParametersTreeView->setModel( mParametersModel );
mParametersGroupBox->setVisible( mAllowParameters );
@@ -484,8 +503,9 @@ void QgsSvgSelectorWidget::populateIcons( const QModelIndex &idx )
QString path = idx.data( Qt::UserRole + 1 ).toString();

QAbstractItemModel *oldModel = mImagesListView->model();
QgsSvgSelectorListModel *m = new QgsSvgSelectorListModel( mImagesListView, path, mIconSize );
QgsSvgSelectorFilterModel *m = new QgsSvgSelectorFilterModel( mImagesListView, path, mIconSize );
mImagesListView->setModel( m );
connect( mSvgFilterLineEdit, &QgsFilterLineEdit::textChanged, m, &QSortFilterProxyModel::setFilterFixedString );
delete oldModel; //explicitly delete old model to force any background threads to stop

connect( mImagesListView->selectionModel(), &QItemSelectionModel::currentChanged,
@@ -513,7 +533,7 @@ void QgsSvgSelectorWidget::populateList()

// Initially load the icons in the List view without any grouping
QAbstractItemModel *oldModel = mImagesListView->model();
QgsSvgSelectorListModel *m = new QgsSvgSelectorListModel( mImagesListView );
QgsSvgSelectorFilterModel *m = new QgsSvgSelectorFilterModel( mImagesListView );
mImagesListView->setModel( m );
delete oldModel; //explicitly delete old model to force any background threads to stop
}
@@ -737,3 +757,5 @@ void QgsSvgParameterValueDelegate::updateEditorGeometry( QWidget *editor, const
}

///@endcond


@@ -23,6 +23,7 @@
#include "qgsguiutils.h"
#include "qgsproperty.h"

#include <QSortFilterProxyModel>
#include <QAbstractListModel>
#include <QDialog>
#include <QDialogButtonBox>
@@ -42,6 +43,7 @@ class QPushButton;
class QTreeView;

class QgsExpressionContextGenerator;
class QgsSvgSelectorListModel;


#ifndef SIP_RUN
@@ -267,6 +269,32 @@ class GUI_EXPORT QgsSvgGroupLoader : public QThread
///@endcond
#endif

/**
* \ingroup gui
* \class QgsSvgSelectorFilterModel
* \brief A model for displaying SVG files with a preview icon which can be filtered by file name.
* Population of the model is performed in a background thread to ensure that
* initial creation of the model is responsive and does not block the GUI.
* \since QGIS 3.20
*/
class GUI_EXPORT QgsSvgSelectorFilterModel : public QSortFilterProxyModel
{
Q_OBJECT

public:

/**
* Constructor for creating a model for SVG files in a specific path.
* \param parent parent object
* \param path initial path, which is recursively searched
* \param iconSize desired size of SVG icons to create
*/
QgsSvgSelectorFilterModel( QObject *parent SIP_TRANSFERTHIS, const QString &path = QString(), int iconSize = 30 );

private:
QgsSvgSelectorListModel *mModel = nullptr;
};

/**
* \ingroup gui
* \class QgsSvgSelectorListModel
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>331</width>
<height>490</height>
<height>500</height>
</rect>
</property>
<property name="windowTitle">
@@ -38,13 +38,19 @@
<string>SVG browser</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<property name="verticalSpacing">
<number>3</number>
</property>
<item row="1" column="0">
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QWidget" name="layoutWidget">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="QLabel" name="mGroupsLabel">
<property name="text">
@@ -72,6 +78,9 @@
</widget>
<widget class="QWidget" name="layoutWidget_1">
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="QLabel" name="mImagesLabel">
<property name="text">
@@ -125,6 +134,13 @@
</property>
</widget>
</item>
<item>
<widget class="QgsFilterLineEdit" name="mSvgFilterLineEdit">
<property name="showSearchIcon" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
@@ -220,6 +236,11 @@
<header>qgsfilecontentsourcelineedit.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsFilterLineEdit</class>
<extends>QLineEdit</extends>
<header>qgsfilterlineedit.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>mSvgSourceLineEdit</tabstop>

0 comments on commit 959d68a

Please sign in to comment.