Skip to content

Commit 3724f9e

Browse files
authored
use a model for select map layer style categories (#7907)
this avoids cluttering QgsMapLayer and reduces a bit code redundancy
1 parent efa7277 commit 3724f9e

13 files changed

+357
-196
lines changed

python/core/auto_generated/qgsmaplayer.sip.in

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -94,31 +94,6 @@ This is the base class for all map layer types (vector, raster).
9494
typedef QFlags<QgsMapLayer::StyleCategory> StyleCategories;
9595

9696

97-
struct ReadableStyleCategory
98-
{
99-
public:
100-
ReadableStyleCategory( const QString &name, const QString &toolTip = QString() );
101-
%Docstring
102-
Create a ReadableStyleCategory
103-
%End
104-
ReadableStyleCategory( const QString &name, const QIcon &icon, const QString &toolTip = QString() );
105-
%Docstring
106-
Create a ReadableStyleCategory
107-
%End
108-
QString name() const;
109-
%Docstring
110-
Return the translated name of the category
111-
%End
112-
QString toolTip() const;
113-
%Docstring
114-
Return the translated tooltip of the category
115-
%End
116-
QIcon icon() const;
117-
%Docstring
118-
Return the icon of the category
119-
%End
120-
};
121-
12297
QgsMapLayer( QgsMapLayer::LayerType type = VectorLayer, const QString &name = QString(), const QString &source = QString() );
12398
%Docstring
12499
Constructor for QgsMapLayer
@@ -181,15 +156,6 @@ Returns the extension of a Property.
181156
.. versionadded:: 3.0
182157
%End
183158

184-
static ReadableStyleCategory readableStyleCategory( StyleCategory category );
185-
%Docstring
186-
Readable and Translated category
187-
188-
.. versionadded:: 3.4
189-
%End
190-
191-
192-
193159
QString id() const;
194160
%Docstring
195161
Returns the layer's unique ID, which is used to access this layer from :py:class:`QgsProject`.

src/app/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ SET(QGIS_APP_SRCS
6161
qgslayertreeviewmemoryindicator.cpp
6262
qgslayertreeviewnonremovableindicator.cpp
6363
qgsmapcanvasdockwidget.cpp
64+
qgsmaplayerstylecategoriesmodel.cpp
6465
qgsmaplayerstyleguiutils.cpp
6566
qgsmapsavedialog.cpp
6667
qgspuzzlewidget.cpp
@@ -285,6 +286,7 @@ SET (QGIS_APP_MOC_HDRS
285286
qgslayertreeviewfilterindicator.h
286287
qgslayertreeviewnonremovableindicator.h
287288
qgsmapcanvasdockwidget.h
289+
qgsmaplayerstylecategoriesmodel.h
288290
qgsmaplayerstyleguiutils.h
289291
qgsmapsavedialog.h
290292
qgspuzzlewidget.h

src/app/qgsapplayertreeviewmenuprovider.cpp

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
* (at your option) any later version. *
1313
* *
1414
***************************************************************************/
15+
1516
#include "qgsapplayertreeviewmenuprovider.h"
1617

1718

@@ -37,6 +38,8 @@
3738
#include "qgslayertreeregistrybridge.h"
3839
#include "qgssymbolselectordialog.h"
3940
#include "qgssinglesymbolrenderer.h"
41+
#include "qgsmaplayerstylecategoriesmodel.h"
42+
4043

4144
QgsAppLayerTreeViewMenuProvider::QgsAppLayerTreeViewMenuProvider( QgsLayerTreeView *view, QgsMapCanvas *canvas )
4245
: mView( view )
@@ -320,13 +323,17 @@ QMenu *QgsAppLayerTreeViewMenuProvider::createContextMenu()
320323
{
321324
QMenu *copyStyleMenu = menuStyleManager->addMenu( tr( "Copy Style" ) );
322325
copyStyleMenu->setToolTipsVisible( true );
323-
QList<QgsMapLayer::StyleCategory> categories = qgsEnumMap<QgsMapLayer::StyleCategory>().keys();
324-
categories.move( categories.indexOf( QgsMapLayer::AllStyleCategories ), 0 ); // move All categories to top
325-
for ( QgsMapLayer::StyleCategory category : categories )
326+
QgsMapLayerStyleCategoriesModel *model = new QgsMapLayerStyleCategoriesModel( copyStyleMenu );
327+
model->setShowAllCategories( true );
328+
for ( int row = 0; row < model->rowCount(); ++row )
326329
{
327-
QgsMapLayer::ReadableStyleCategory readableCategory = QgsMapLayer::readableStyleCategory( category );
328-
QAction *copyAction = new QAction( readableCategory.icon(), readableCategory.name(), copyStyleMenu );
329-
copyAction->setToolTip( readableCategory.toolTip() );
330+
QModelIndex index = model->index( row, 0 );
331+
QString name = model->data( index, Qt::DisplayRole ).toString();
332+
QString tooltip = model->data( index, Qt::ToolTipRole ).toString();
333+
QIcon icon = model->data( index, Qt::DecorationRole ).value<QIcon>();
334+
QgsMapLayer::StyleCategory category = model->index2category( index );
335+
QAction *copyAction = new QAction( icon, name, copyStyleMenu );
336+
copyAction->setToolTip( tooltip );
330337
connect( copyAction, &QAction::triggered, this, [ = ]() {app->copyStyle( layer, category );} );
331338
copyStyleMenu->addAction( copyAction );
332339
if ( category == QgsMapLayer::AllStyleCategories )
@@ -342,19 +349,24 @@ QMenu *QgsAppLayerTreeViewMenuProvider::createContextMenu()
342349
{
343350
if ( layer->type() == QgsMapLayer::VectorLayer )
344351
{
345-
QMenu *copyStyleMenu = menuStyleManager->addMenu( tr( "Paste Style" ) );
346-
copyStyleMenu->setToolTipsVisible( true );
347-
QList<QgsMapLayer::StyleCategory> categories = qgsEnumMap<QgsMapLayer::StyleCategory>().keys();
348-
categories.move( categories.indexOf( QgsMapLayer::AllStyleCategories ), 0 ); // move All categories to top
349-
for ( QgsMapLayer::StyleCategory category : categories )
352+
QMenu *pasteStyleMenu = menuStyleManager->addMenu( tr( "Paste Style" ) );
353+
pasteStyleMenu->setToolTipsVisible( true );
354+
355+
QgsMapLayerStyleCategoriesModel *model = new QgsMapLayerStyleCategoriesModel( pasteStyleMenu );
356+
model->setShowAllCategories( true );
357+
for ( int row = 0; row < model->rowCount(); ++row )
350358
{
351-
QgsMapLayer::ReadableStyleCategory readableCategory = QgsMapLayer::readableStyleCategory( category );
352-
QAction *copyAction = new QAction( readableCategory.icon(), readableCategory.name() );
353-
copyAction->setToolTip( readableCategory.toolTip() );
354-
connect( copyAction, &QAction::triggered, this, [ = ]() {app->pasteStyle( layer, category );} );
355-
copyStyleMenu->addAction( copyAction );
359+
QModelIndex index = model->index( row, 0 );
360+
QString name = model->data( index, Qt::DisplayRole ).toString();
361+
QString tooltip = model->data( index, Qt::ToolTipRole ).toString();
362+
QIcon icon = model->data( index, Qt::DecorationRole ).value<QIcon>();
363+
QgsMapLayer::StyleCategory category = model->index2category( index );
364+
QAction *copyAction = new QAction( icon, name, pasteStyleMenu );
365+
copyAction->setToolTip( tooltip );
366+
connect( copyAction, &QAction::triggered, this, [ = ]() {app->copyStyle( layer, category );} );
367+
pasteStyleMenu->addAction( copyAction );
356368
if ( category == QgsMapLayer::AllStyleCategories )
357-
copyStyleMenu->addSeparator();
369+
pasteStyleMenu->addSeparator();
358370
}
359371
}
360372
else
Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
/***************************************************************************
2+
qgsmaplayerstylecategoriesmodel.cpp
3+
--------------------------------------
4+
Date : September 2018
5+
Copyright : (C) 2018 by Denis Rouzaud
6+
Email : denis@opengis.ch
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#include "qgsmaplayerstylecategoriesmodel.h"
17+
18+
QgsMapLayerStyleCategoriesModel::QgsMapLayerStyleCategoriesModel( QObject *parent )
19+
: QAbstractListModel( parent )
20+
{
21+
mCategoryList = qgsEnumMap<QgsMapLayer::StyleCategory>().keys();
22+
// move All categories to top
23+
mCategoryList.move( mCategoryList.indexOf( QgsMapLayer::AllStyleCategories ), 0 );
24+
}
25+
26+
void QgsMapLayerStyleCategoriesModel::setCategories( QgsMapLayer::StyleCategories categories )
27+
{
28+
if ( mCategories == categories )
29+
return;
30+
31+
beginResetModel();
32+
mCategories = categories;
33+
endResetModel();
34+
}
35+
36+
QgsMapLayer::StyleCategories QgsMapLayerStyleCategoriesModel::categories() const
37+
{
38+
return mCategories;
39+
}
40+
41+
void QgsMapLayerStyleCategoriesModel::setShowAllCategories( bool showAll )
42+
{
43+
beginResetModel();
44+
mShowAllCategories = showAll;
45+
endResetModel();
46+
}
47+
48+
QgsMapLayer::StyleCategory QgsMapLayerStyleCategoriesModel::index2category( const QModelIndex &index ) const
49+
{
50+
return mCategoryList.at( index.row() - ( mShowAllCategories ? 0 : 1 ) );
51+
}
52+
53+
int QgsMapLayerStyleCategoriesModel::rowCount( const QModelIndex & ) const
54+
{
55+
int count = mCategoryList.count();
56+
if ( !mShowAllCategories )
57+
count--;
58+
return count;
59+
}
60+
61+
int QgsMapLayerStyleCategoriesModel::columnCount( const QModelIndex & ) const
62+
{
63+
return 1;
64+
}
65+
66+
QVariant QgsMapLayerStyleCategoriesModel::data( const QModelIndex &index, int role ) const
67+
{
68+
if ( !index.isValid() || index.row() >= rowCount() )
69+
return QVariant();
70+
71+
QgsMapLayer::StyleCategory category = index2category( index );
72+
73+
switch ( category )
74+
{
75+
case QgsMapLayer::LayerConfiguration:
76+
switch ( role )
77+
{
78+
case Qt::DisplayRole:
79+
return tr( "Layer Configuration" );
80+
case Qt::ToolTipRole:
81+
return tr( "Identifiable, removable, searchable, display expression, read-only" );
82+
case Qt::DecorationRole:
83+
return QgsApplication::getThemeIcon( QStringLiteral( "/propertyicons/system.svg" ) );
84+
}
85+
case QgsMapLayer::Symbology :
86+
switch ( role )
87+
{
88+
case Qt::DisplayRole:
89+
return tr( "Symbology" );
90+
case Qt::ToolTipRole:
91+
return QVariant();
92+
case Qt::DecorationRole:
93+
return QgsApplication::getThemeIcon( QStringLiteral( "/propertyicons/symbology.svg" ) );
94+
}
95+
case QgsMapLayer::Symbology3D:
96+
switch ( role )
97+
{
98+
case Qt::DisplayRole:
99+
return tr( "3D Symbology" );
100+
case Qt::ToolTipRole:
101+
return QVariant();
102+
case Qt::DecorationRole:
103+
return QgsApplication::getThemeIcon( QStringLiteral( "/3d.svg" ) );
104+
}
105+
case QgsMapLayer::Labeling :
106+
switch ( role )
107+
{
108+
case Qt::DisplayRole:
109+
return tr( "Labels" );
110+
case Qt::ToolTipRole:
111+
return QVariant();
112+
case Qt::DecorationRole:
113+
return QgsApplication::getThemeIcon( QStringLiteral( "/propertyicons/labels.svg" ) );
114+
}
115+
case QgsMapLayer::Fields :
116+
switch ( role )
117+
{
118+
case Qt::DisplayRole:
119+
return tr( "Fields" );
120+
case Qt::ToolTipRole:
121+
return tr( "Aliases, widgets, WMS/WFS, expressions, constraints, virtual fields" );
122+
case Qt::DecorationRole:
123+
return QgsApplication::getThemeIcon( QStringLiteral( "/mSourceFields" ) );
124+
}
125+
case QgsMapLayer::Forms :
126+
switch ( role )
127+
{
128+
case Qt::DisplayRole:
129+
return tr( "Forms" );
130+
case Qt::ToolTipRole:
131+
return QVariant();
132+
case Qt::DecorationRole:
133+
return QgsApplication::getThemeIcon( QStringLiteral( "/mActionFormView" ) );
134+
}
135+
case QgsMapLayer::Actions :
136+
switch ( role )
137+
{
138+
case Qt::DisplayRole:
139+
return tr( "Actions" );
140+
case Qt::ToolTipRole:
141+
return QVariant();
142+
case Qt::DecorationRole:
143+
return QgsApplication::getThemeIcon( QStringLiteral( "/propertyicons/action.svg" ) );
144+
}
145+
case QgsMapLayer::MapTips :
146+
switch ( role )
147+
{
148+
case Qt::DisplayRole:
149+
return tr( "Map Tips" );
150+
case Qt::ToolTipRole:
151+
return QVariant();
152+
case Qt::DecorationRole:
153+
return QgsApplication::getThemeIcon( QStringLiteral( "/propertyicons/display.svg" ) );
154+
}
155+
case QgsMapLayer::Diagrams :
156+
switch ( role )
157+
{
158+
case Qt::DisplayRole:
159+
return tr( "Diagrams" );
160+
case Qt::ToolTipRole:
161+
return QVariant();
162+
case Qt::DecorationRole:
163+
return QgsApplication::getThemeIcon( QStringLiteral( "/propertyicons/diagram.svg" ) );
164+
}
165+
case QgsMapLayer::AttributeTable :
166+
switch ( role )
167+
{
168+
case Qt::DisplayRole:
169+
return tr( "Attribute Table Settings" );
170+
case Qt::ToolTipRole:
171+
return tr( "Choice and order of columns, conditional styling" );
172+
case Qt::DecorationRole:
173+
return QgsApplication::getThemeIcon( QStringLiteral( "/mActionOpenTable" ) );
174+
}
175+
case QgsMapLayer::Rendering :
176+
switch ( role )
177+
{
178+
case Qt::DisplayRole:
179+
return tr( "Rendering" );
180+
case Qt::ToolTipRole:
181+
return tr( "Scale visibility, simplify method, opacity" );
182+
case Qt::DecorationRole:
183+
return QgsApplication::getThemeIcon( QStringLiteral( "/propertyicons/rendering.svg" ) );
184+
}
185+
case QgsMapLayer::CustomProperties :
186+
switch ( role )
187+
{
188+
case Qt::DisplayRole:
189+
return tr( "Custom Properties" );
190+
case Qt::ToolTipRole:
191+
return QVariant();
192+
case Qt::DecorationRole:
193+
return QgsApplication::getThemeIcon( QStringLiteral( "/mActionOptions.svg" ) );
194+
}
195+
case QgsMapLayer::AllStyleCategories :
196+
switch ( role )
197+
{
198+
case Qt::DisplayRole:
199+
return tr( "All Style Categories" );
200+
case Qt::ToolTipRole:
201+
return QVariant();
202+
case Qt::DecorationRole:
203+
return QVariant();
204+
}
205+
}
206+
return QVariant();
207+
}
208+
209+
bool QgsMapLayerStyleCategoriesModel::setData( const QModelIndex &index, const QVariant &value, int role )
210+
{
211+
if ( !index.isValid() || index.row() >= rowCount() )
212+
return false;
213+
214+
if ( role == Qt::CheckStateRole )
215+
{
216+
QgsMapLayer::StyleCategory category = index2category( index );
217+
if ( value.value<Qt::CheckState>() == Qt::Checked )
218+
{
219+
mCategories |= category;
220+
emit dataChanged( index, index );
221+
return true;
222+
}
223+
else if ( value.value<Qt::CheckState>() == Qt::Unchecked )
224+
{
225+
mCategories &= category;
226+
emit dataChanged( index, index );
227+
return true;
228+
}
229+
}
230+
return false;
231+
}
232+
233+
234+
Qt::ItemFlags QgsMapLayerStyleCategoriesModel::flags( const QModelIndex & ) const
235+
{
236+
return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;
237+
}

0 commit comments

Comments
 (0)