QGIS API Documentation 3.36.0-Maidenhead (09951dc0acf)
Loading...
Searching...
No Matches
qgsbookmarkmodel.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsbookmarkmodel.cpp
3 --------------------
4 Date : September 2019
5 Copyright : (C) 2019 Nyall Dawson
6 Email : nyall dot dawson at gmail dot com
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 "qgsapplication.h"
17#include "qgsbookmarkmodel.h"
18#include "qgsbookmarkmanager.h"
19
20#include <QIcon>
21
23 : QAbstractTableModel( parent )
24 , mManager( manager )
25 , mProjectManager( projectManager )
26{
27 for ( QgsBookmarkManager *obj : { manager, projectManager } )
28 {
29 connect( obj, &QgsBookmarkManager::bookmarkAdded, this, &QgsBookmarkManagerModel::bookmarkAdded );
30 connect( obj, &QgsBookmarkManager::bookmarkAboutToBeAdded, this, &QgsBookmarkManagerModel::bookmarkAboutToBeAdded );
31 connect( obj, &QgsBookmarkManager::bookmarkRemoved, this, &QgsBookmarkManagerModel::bookmarkRemoved );
32 connect( obj, &QgsBookmarkManager::bookmarkAboutToBeRemoved, this, &QgsBookmarkManagerModel::bookmarkAboutToBeRemoved );
33 connect( obj, &QgsBookmarkManager::bookmarkChanged, this, &QgsBookmarkManagerModel::bookmarkChanged );
34 }
35}
36
37int QgsBookmarkManagerModel::rowCount( const QModelIndex & ) const
38{
39 return mManager->bookmarks().count() + mProjectManager->bookmarks().count();
40}
41
42int QgsBookmarkManagerModel::columnCount( const QModelIndex & ) const
43{
44 return ColumnStore + 1;
45}
46
47QVariant QgsBookmarkManagerModel::data( const QModelIndex &index, int role ) const
48{
49 if ( !index.isValid() )
50 return QVariant();
51
52 const QgsBookmark b = bookmarkForIndex( index );
53 const int managerCount = mManager->bookmarks().count();
54
55 switch ( role )
56 {
57 case static_cast< int >( CustomRole::Extent ):
58 return b.extent();
59
60 case static_cast< int >( CustomRole::Rotation ):
61 return b.rotation();
62
63 case static_cast< int >( CustomRole::Name ):
64 return b.name();
65
66 case static_cast< int >( CustomRole::Id ):
67 return b.id();
68
69 case static_cast< int >( CustomRole::Group ):
70 return b.group();
71
72 case Qt::DecorationRole:
73 return index.column() == ColumnName ? QgsApplication::getThemeIcon( QStringLiteral( "/mItemBookmark.svg" ) ) : QIcon();
74
75 case Qt::DisplayRole:
76 case Qt::EditRole:
77 {
78 switch ( index.column() )
79 {
80 case ColumnName:
81 return b.name();
82 case ColumnGroup:
83 return b.group();
84 case ColumnXMin:
85 return b.extent().xMinimum();
86 case ColumnYMin:
87 return b.extent().yMinimum();
88 case ColumnXMax:
89 return b.extent().xMaximum();
90 case ColumnYMax:
91 return b.extent().yMaximum();
92 case ColumnRotation:
93 return b.rotation();
94 case ColumnCrs:
95 return b.extent().crs().authid();
96 case ColumnStore:
97 return QVariant();
98 }
99 break;
100 }
101
102 case Qt::CheckStateRole:
103 {
104 if ( index.column() == ColumnStore )
105 return index.row() < managerCount ? Qt::Unchecked : Qt::Checked;
106 break;
107 }
108 }
109 return QVariant();
110}
111
112Qt::ItemFlags QgsBookmarkManagerModel::flags( const QModelIndex &index ) const
113{
114 if ( !index.isValid() || index.row() < 0 || index.row() >= rowCount() )
115 return Qt::ItemFlags();
116
117 Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
118 if ( index.column() == ColumnStore )
119 {
120 flags |= Qt::ItemIsUserCheckable;
121 }
122 else
123 {
124 // projection column is not editable!
125 if ( index.column() != ColumnCrs )
126 flags |= Qt::ItemIsEditable;
127 }
128 return flags;
129}
130
131bool QgsBookmarkManagerModel::setData( const QModelIndex &index, const QVariant &value, int role )
132{
133 if ( !index.isValid() )
134 return false;
135
136 QgsBookmark b = bookmarkForIndex( index );
137 const int managerCount = mManager->bookmarks().count();
138
139 switch ( role )
140 {
141 case Qt::EditRole:
142 {
143 QgsReferencedRectangle extent = b.extent();
144 switch ( index.column() )
145 {
146 case ColumnName:
147 b.setName( value.toString() );
148 break;
149 case ColumnGroup:
150 b.setGroup( value.toString() );
151 break;
152 case ColumnXMin:
153 {
154 bool ok = false;
155 extent.setXMinimum( value.toDouble( &ok ) );
156 if ( !ok )
157 return false;
158 break;
159 }
160 case ColumnYMin:
161 {
162 bool ok = false;
163 extent.setYMinimum( value.toDouble( &ok ) );
164 if ( !ok )
165 return false;
166 break;
167 }
168 case ColumnXMax:
169 {
170 bool ok = false;
171 extent.setXMaximum( value.toDouble( &ok ) );
172 if ( !ok )
173 return false;
174 break;
175 }
176 case ColumnYMax:
177 {
178 bool ok = false;
179 extent.setYMaximum( value.toDouble( &ok ) );
180 if ( !ok )
181 return false;
182 break;
183 }
184 case ColumnRotation:
185 b.setRotation( value.toDouble() );
186 break;
187 case ColumnCrs:
188 {
190 if ( !crs.createFromString( value.toString() ) )
191 return false;
192 extent.setCrs( crs );
193 break;
194 }
195 default:
196 return false;
197 }
198 b.setExtent( extent );
199 return index.row() < managerCount ? mManager->updateBookmark( b ) : mProjectManager->updateBookmark( b );
200 }
201
202 case Qt::CheckStateRole:
203 {
204 if ( index.column() != ColumnStore )
205 return false;
206
207 if ( index.row() < managerCount )
208 {
209 if ( value.toInt() != Qt::Checked )
210 return false;
211 return mManager->moveBookmark( b.id(), mProjectManager );
212 }
213 else
214 {
215 if ( value.toInt() != Qt::Unchecked )
216 return false;
217 return mProjectManager->moveBookmark( b.id(), mManager );
218 }
219 }
220 }
221
222 return false;
223}
224
225bool QgsBookmarkManagerModel::insertRows( int, int count, const QModelIndex &parent )
226{
227 // append
228 const int oldCount = mManager->bookmarks().count();
229 beginInsertRows( parent, oldCount, oldCount + count );
230 bool result = true;
231 for ( int i = 0; i < count; ++i )
232 {
233 bool res = false;
234 mBlocked = true;
235 mManager->addBookmark( QgsBookmark(), &res );
236 mBlocked = false;
237 result &= res;
238 }
239 endInsertRows();
240 return result;
241}
242
243bool QgsBookmarkManagerModel::removeRows( int row, int count, const QModelIndex &parent )
244{
245 beginRemoveRows( parent, row, row + count );
246
247 const QList< QgsBookmark > appBookmarks = mManager->bookmarks();
248 const QList< QgsBookmark > projectBookmarks = mProjectManager->bookmarks();
249 for ( int r = row + count - 1; r >= row; --r )
250 {
251 if ( r >= appBookmarks.count() )
252 mProjectManager->removeBookmark( projectBookmarks.at( r - appBookmarks.size() ).id() );
253 else
254 mManager->removeBookmark( appBookmarks.at( r ).id() );
255 }
256 endRemoveRows();
257 return true;
258}
259
260QVariant QgsBookmarkManagerModel::headerData( int section, Qt::Orientation orientation, int role ) const
261{
262 if ( role == Qt::DisplayRole )
263 {
264 switch ( section )
265 {
266 case ColumnName:
267 return tr( "Name" );
268 case ColumnGroup:
269 return tr( "Group" );
270 case ColumnXMin:
271 return tr( "xMin" );
272 case ColumnYMin:
273 return tr( "yMin" );
274 case ColumnXMax:
275 return tr( "xMax" );
276 case ColumnYMax:
277 return tr( "yMax" );
278 case ColumnRotation:
279 return tr( "Rotation" );
280 case ColumnCrs:
281 return tr( "CRS" );
282 case ColumnStore:
283 return tr( "In Project" );
284 }
285 }
286 return QAbstractTableModel::headerData( section, orientation, role );
287}
288
289void QgsBookmarkManagerModel::bookmarkAboutToBeAdded( const QString & )
290{
291 if ( mBlocked )
292 return;
293
294 if ( qobject_cast< QgsBookmarkManager * >( sender() ) == mManager )
295 beginInsertRows( QModelIndex(), mManager->bookmarks().count(), mManager->bookmarks().count() );
296 else
297 beginInsertRows( QModelIndex(), mManager->bookmarks().count() + mProjectManager->bookmarks().count(),
298 mManager->bookmarks().count() + mProjectManager->bookmarks().count() );
299}
300
301void QgsBookmarkManagerModel::bookmarkAdded( const QString & )
302{
303 if ( mBlocked )
304 return;
305
306 endInsertRows();
307}
308
309void QgsBookmarkManagerModel::bookmarkAboutToBeRemoved( const QString &id )
310{
311 if ( mBlocked )
312 return;
313
314 QgsBookmarkManager *manager = qobject_cast< QgsBookmarkManager * >( sender() );
315
316 const QList< QgsBookmark > bookmarks = manager->bookmarks();
317 bool found = false;
318 int i = 0;
319 for ( i = 0; i < bookmarks.count(); ++i )
320 {
321 if ( bookmarks.at( i ).id() == id )
322 {
323 found = true;
324 break;
325 }
326 }
327 if ( !found )
328 return;
329
330 if ( manager == mManager )
331 beginRemoveRows( QModelIndex(), i, i );
332 else
333 beginRemoveRows( QModelIndex(), mManager->bookmarks().count() + i,
334 mManager->bookmarks().count() + i );
335}
336
337void QgsBookmarkManagerModel::bookmarkRemoved( const QString & )
338{
339 if ( mBlocked )
340 return;
341
342 endRemoveRows();
343}
344
345void QgsBookmarkManagerModel::bookmarkChanged( const QString &id )
346{
347 if ( mBlocked )
348 return;
349
350 QgsBookmarkManager *manager = qobject_cast< QgsBookmarkManager * >( sender() );
351 const QList< QgsBookmark > bookmarks = manager->bookmarks();
352 bool found = false;
353 int i = 0;
354 for ( i = 0; i < bookmarks.count(); ++i )
355 {
356 if ( bookmarks.at( i ).id() == id )
357 {
358 found = true;
359 break;
360 }
361 }
362 if ( !found )
363 return;
364
365 if ( manager == mManager )
366 emit dataChanged( index( i, 0 ), index( i, columnCount() - 1 ) );
367 else
368 emit dataChanged( index( mManager->bookmarks().count() + i, 0 ), index( mManager->bookmarks().count() + i, columnCount() - 1 ) );
369}
370
371QgsBookmark QgsBookmarkManagerModel::bookmarkForIndex( const QModelIndex &index ) const
372{
373 if ( !index.isValid() )
374 return QgsBookmark();
375
376 const int managerCount = mManager->bookmarks().count();
377 const int projectCount = mProjectManager->bookmarks().count();
378 if ( index.row() < managerCount )
379 return mManager->bookmarks().at( index.row() );
380 else if ( index.row() < managerCount + projectCount )
381 return mProjectManager->bookmarks().at( index.row() - managerCount );
382 return QgsBookmark();
383}
384
385//
386// QgsBookmarkManagerProxyModel
387//
388
390 : QSortFilterProxyModel( parent )
391 , mModel( new QgsBookmarkManagerModel( manager, projectManager, this ) )
392{
393 setSourceModel( mModel );
394 setDynamicSortFilter( true );
395 setSortLocaleAware( true );
396 setFilterCaseSensitivity( Qt::CaseInsensitive );
397 sort( 0 );
398}
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
Implements a model for the contents of QgsBookmarkManager objects.
Qt::ItemFlags flags(const QModelIndex &index) const override
@ ColumnXMin
Extent x-minimum.
@ ColumnRotation
Rotation of the map.
@ ColumnYMin
Extent y-minimum.
@ ColumnStore
Manager storing the bookmark (true if stored in project bookmark manager)
@ ColumnXMax
Extent x-maximum.
@ ColumnYMax
Extent y-maximum.
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override
QgsBookmarkManagerModel(QgsBookmarkManager *manager, QgsBookmarkManager *projectManager=nullptr, QObject *parent=nullptr)
Constructor for QgsBookmarkManagerModel, associated with a main manager (usually the application book...
bool insertRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
int columnCount(const QModelIndex &parent=QModelIndex()) const override
int rowCount(const QModelIndex &parent=QModelIndex()) const override
@ Extent
Bookmark extent as a QgsReferencedRectangle.
@ Rotation
Bookmark map rotation.
bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
QgsBookmarkManagerProxyModel(QgsBookmarkManager *manager, QgsBookmarkManager *projectManager=nullptr, QObject *parent=nullptr)
Constructor for QgsBookmarkManagerProxyModel, associated with a main manager (usually the application...
Manages storage of a set of bookmarks.
bool removeBookmark(const QString &id)
Removes the bookmark with matching id from the manager.
void bookmarkAboutToBeRemoved(const QString &id)
Emitted when a bookmark is about to be removed from the manager.
void bookmarkChanged(const QString &id)
Emitted when a bookmark is changed.
void bookmarkAdded(const QString &id)
Emitted when a bookmark has been added to the manager.
bool updateBookmark(const QgsBookmark &bookmark)
Updates the definition of a bookmark in the manager.
void bookmarkAboutToBeAdded(const QString &id)
Emitted when a bookmark is about to be added to the manager.
bool moveBookmark(const QString &id, QgsBookmarkManager *destination)
Moves the bookmark with matching id from this manager to a destination manager.
QString addBookmark(const QgsBookmark &bookmark, bool *ok=nullptr)
Adds a bookmark to the manager.
QList< QgsBookmark > bookmarks() const
Returns a list of all bookmarks contained in the manager.
void bookmarkRemoved(const QString &id)
Emitted when a bookmark was removed from the manager.
Represents a spatial bookmark, with a name, CRS and extent.
void setGroup(const QString &group)
Sets the bookmark's group, which is a user-visible string identifying the bookmark's category.
void setRotation(double rotation)
Sets the bookmark's spatial map rotation.
QString id() const
Returns the bookmark's unique ID.
QgsReferencedRectangle extent() const
Returns the bookmark's spatial extent.
void setExtent(const QgsReferencedRectangle &extent)
Sets the bookmark's spatial extent.
double rotation() const
Returns the bookmark's map rotation.
QString group() const
Returns the bookmark's group, which is a user-visible string identifying the bookmark's category.
void setName(const QString &name)
Sets the bookmark's name, which is a user-visible string identifying the bookmark.
QString name() const
Returns the bookmark's name, which is a user-visible string identifying the bookmark.
This class represents a coordinate reference system (CRS).
bool createFromString(const QString &definition)
Set up this CRS from a string definition.
double xMinimum() const
Returns the x minimum value (left side of rectangle).
void setYMinimum(double y)
Set the minimum y value.
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
void setXMinimum(double x)
Set the minimum x value.
double xMaximum() const
Returns the x maximum value (right side of rectangle).
double yMaximum() const
Returns the y maximum value (top side of rectangle).
void setYMaximum(double y)
Set the maximum y value.
void setXMaximum(double x)
Set the maximum x value.
QgsCoordinateReferenceSystem crs() const
Returns the associated coordinate reference system, or an invalid CRS if no reference system is set.
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets the associated crs.
A QgsRectangle with associated coordinate reference system.
const QgsCoordinateReferenceSystem & crs