QGIS API Documentation 3.41.0-Master (45a0abf3bec)
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 "moc_qgsbookmarkmodel.cpp"
19#include "qgsbookmarkmanager.h"
20
21#include <QIcon>
22
24 : QAbstractTableModel( parent )
25 , mManager( manager )
26 , mProjectManager( projectManager )
27{
28 for ( QgsBookmarkManager *obj : { manager, projectManager } )
29 {
30 connect( obj, &QgsBookmarkManager::bookmarkAdded, this, &QgsBookmarkManagerModel::bookmarkAdded );
31 connect( obj, &QgsBookmarkManager::bookmarkAboutToBeAdded, this, &QgsBookmarkManagerModel::bookmarkAboutToBeAdded );
32 connect( obj, &QgsBookmarkManager::bookmarkRemoved, this, &QgsBookmarkManagerModel::bookmarkRemoved );
33 connect( obj, &QgsBookmarkManager::bookmarkAboutToBeRemoved, this, &QgsBookmarkManagerModel::bookmarkAboutToBeRemoved );
34 connect( obj, &QgsBookmarkManager::bookmarkChanged, this, &QgsBookmarkManagerModel::bookmarkChanged );
35 }
36}
37
38int QgsBookmarkManagerModel::rowCount( const QModelIndex & ) const
39{
40 return mManager->bookmarks().count() + mProjectManager->bookmarks().count();
41}
42
43int QgsBookmarkManagerModel::columnCount( const QModelIndex & ) const
44{
45 return ColumnStore + 1;
46}
47
48QVariant QgsBookmarkManagerModel::data( const QModelIndex &index, int role ) const
49{
50 if ( !index.isValid() )
51 return QVariant();
52
53 const QgsBookmark b = bookmarkForIndex( index );
54 const int managerCount = mManager->bookmarks().count();
55
56 switch ( role )
57 {
58 case static_cast< int >( CustomRole::Extent ):
59 return b.extent();
60
61 case static_cast< int >( CustomRole::Rotation ):
62 return b.rotation();
63
64 case static_cast< int >( CustomRole::Name ):
65 return b.name();
66
67 case static_cast< int >( CustomRole::Id ):
68 return b.id();
69
70 case static_cast< int >( CustomRole::Group ):
71 return b.group();
72
73 case Qt::DecorationRole:
74 return index.column() == ColumnName ? QgsApplication::getThemeIcon( QStringLiteral( "/mItemBookmark.svg" ) ) : QIcon();
75
76 case Qt::DisplayRole:
77 case Qt::EditRole:
78 {
79 switch ( index.column() )
80 {
81 case ColumnName:
82 return b.name();
83 case ColumnGroup:
84 return b.group();
85 case ColumnXMin:
86 return b.extent().xMinimum();
87 case ColumnYMin:
88 return b.extent().yMinimum();
89 case ColumnXMax:
90 return b.extent().xMaximum();
91 case ColumnYMax:
92 return b.extent().yMaximum();
93 case ColumnRotation:
94 return b.rotation();
95 case ColumnCrs:
96 return b.extent().crs().authid();
97 case ColumnStore:
98 return QVariant();
99 }
100 break;
101 }
102
103 case Qt::CheckStateRole:
104 {
105 if ( index.column() == ColumnStore )
106 return index.row() < managerCount ? Qt::Unchecked : Qt::Checked;
107 break;
108 }
109 }
110 return QVariant();
111}
112
113Qt::ItemFlags QgsBookmarkManagerModel::flags( const QModelIndex &index ) const
114{
115 if ( !index.isValid() || index.row() < 0 || index.row() >= rowCount() )
116 return Qt::ItemFlags();
117
118 Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
119 if ( index.column() == ColumnStore )
120 {
121 flags |= Qt::ItemIsUserCheckable;
122 }
123 else
124 {
125 // projection column is not editable!
126 if ( index.column() != ColumnCrs )
127 flags |= Qt::ItemIsEditable;
128 }
129 return flags;
130}
131
132bool QgsBookmarkManagerModel::setData( const QModelIndex &index, const QVariant &value, int role )
133{
134 if ( !index.isValid() )
135 return false;
136
137 QgsBookmark b = bookmarkForIndex( index );
138 const int managerCount = mManager->bookmarks().count();
139
140 switch ( role )
141 {
142 case Qt::EditRole:
143 {
144 QgsReferencedRectangle extent = b.extent();
145 switch ( index.column() )
146 {
147 case ColumnName:
148 b.setName( value.toString() );
149 break;
150 case ColumnGroup:
151 b.setGroup( value.toString() );
152 break;
153 case ColumnXMin:
154 {
155 bool ok = false;
156 extent.setXMinimum( value.toDouble( &ok ) );
157 if ( !ok )
158 return false;
159 break;
160 }
161 case ColumnYMin:
162 {
163 bool ok = false;
164 extent.setYMinimum( value.toDouble( &ok ) );
165 if ( !ok )
166 return false;
167 break;
168 }
169 case ColumnXMax:
170 {
171 bool ok = false;
172 extent.setXMaximum( value.toDouble( &ok ) );
173 if ( !ok )
174 return false;
175 break;
176 }
177 case ColumnYMax:
178 {
179 bool ok = false;
180 extent.setYMaximum( value.toDouble( &ok ) );
181 if ( !ok )
182 return false;
183 break;
184 }
185 case ColumnRotation:
186 b.setRotation( value.toDouble() );
187 break;
188 case ColumnCrs:
189 {
191 if ( !crs.createFromString( value.toString() ) )
192 return false;
193 extent.setCrs( crs );
194 break;
195 }
196 default:
197 return false;
198 }
199 b.setExtent( extent );
200 return index.row() < managerCount ? mManager->updateBookmark( b ) : mProjectManager->updateBookmark( b );
201 }
202
203 case Qt::CheckStateRole:
204 {
205 if ( index.column() != ColumnStore )
206 return false;
207
208 if ( index.row() < managerCount )
209 {
210 if ( value.toInt() != Qt::Checked )
211 return false;
212 return mManager->moveBookmark( b.id(), mProjectManager );
213 }
214 else
215 {
216 if ( value.toInt() != Qt::Unchecked )
217 return false;
218 return mProjectManager->moveBookmark( b.id(), mManager );
219 }
220 }
221 }
222
223 return false;
224}
225
226bool QgsBookmarkManagerModel::insertRows( int, int count, const QModelIndex & )
227{
228 // append
229 bool result = true;
230 for ( int i = 0; i < count; ++i )
231 {
232 bool res = false;
233 mBlocked = true;
234 mManager->addBookmark( QgsBookmark(), &res );
235 mBlocked = false;
236 result &= res;
237 }
238 return result;
239}
240
241bool QgsBookmarkManagerModel::removeRows( int row, int count, const QModelIndex & )
242{
243 const QList< QgsBookmark > appBookmarks = mManager->bookmarks();
244 const QList< QgsBookmark > projectBookmarks = mProjectManager->bookmarks();
245 for ( int r = row + count - 1; r >= row; --r )
246 {
247 if ( r >= appBookmarks.count() )
248 mProjectManager->removeBookmark( projectBookmarks.at( r - appBookmarks.size() ).id() );
249 else
250 mManager->removeBookmark( appBookmarks.at( r ).id() );
251 }
252 return true;
253}
254
255QVariant QgsBookmarkManagerModel::headerData( int section, Qt::Orientation orientation, int role ) const
256{
257 if ( role == Qt::DisplayRole )
258 {
259 switch ( section )
260 {
261 case ColumnName:
262 return tr( "Name" );
263 case ColumnGroup:
264 return tr( "Group" );
265 case ColumnXMin:
266 return tr( "xMin" );
267 case ColumnYMin:
268 return tr( "yMin" );
269 case ColumnXMax:
270 return tr( "xMax" );
271 case ColumnYMax:
272 return tr( "yMax" );
273 case ColumnRotation:
274 return tr( "Rotation" );
275 case ColumnCrs:
276 return tr( "CRS" );
277 case ColumnStore:
278 return tr( "In Project" );
279 }
280 }
281 return QAbstractTableModel::headerData( section, orientation, role );
282}
283
284void QgsBookmarkManagerModel::bookmarkAboutToBeAdded( const QString & )
285{
286 if ( mBlocked )
287 return;
288
289 if ( qobject_cast< QgsBookmarkManager * >( sender() ) == mManager )
290 beginInsertRows( QModelIndex(), mManager->bookmarks().count(), mManager->bookmarks().count() );
291 else
292 beginInsertRows( QModelIndex(), mManager->bookmarks().count() + mProjectManager->bookmarks().count(),
293 mManager->bookmarks().count() + mProjectManager->bookmarks().count() );
294}
295
296void QgsBookmarkManagerModel::bookmarkAdded( const QString & )
297{
298 if ( mBlocked )
299 return;
300
301 endInsertRows();
302}
303
304void QgsBookmarkManagerModel::bookmarkAboutToBeRemoved( const QString &id )
305{
306 if ( mBlocked )
307 return;
308
309 QgsBookmarkManager *manager = qobject_cast< QgsBookmarkManager * >( sender() );
310
311 const QList< QgsBookmark > bookmarks = manager->bookmarks();
312 bool found = false;
313 int i = 0;
314 for ( i = 0; i < bookmarks.count(); ++i )
315 {
316 if ( bookmarks.at( i ).id() == id )
317 {
318 found = true;
319 break;
320 }
321 }
322 if ( !found )
323 return;
324
325 if ( manager == mManager )
326 beginRemoveRows( QModelIndex(), i, i );
327 else
328 beginRemoveRows( QModelIndex(), mManager->bookmarks().count() + i,
329 mManager->bookmarks().count() + i );
330}
331
332void QgsBookmarkManagerModel::bookmarkRemoved( const QString & )
333{
334 if ( mBlocked )
335 return;
336
337 endRemoveRows();
338}
339
340void QgsBookmarkManagerModel::bookmarkChanged( const QString &id )
341{
342 if ( mBlocked )
343 return;
344
345 QgsBookmarkManager *manager = qobject_cast< QgsBookmarkManager * >( sender() );
346 const QList< QgsBookmark > bookmarks = manager->bookmarks();
347 bool found = false;
348 int i = 0;
349 for ( i = 0; i < bookmarks.count(); ++i )
350 {
351 if ( bookmarks.at( i ).id() == id )
352 {
353 found = true;
354 break;
355 }
356 }
357 if ( !found )
358 return;
359
360 if ( manager == mManager )
361 emit dataChanged( index( i, 0 ), index( i, columnCount() - 1 ) );
362 else
363 emit dataChanged( index( mManager->bookmarks().count() + i, 0 ), index( mManager->bookmarks().count() + i, columnCount() - 1 ) );
364}
365
366QgsBookmark QgsBookmarkManagerModel::bookmarkForIndex( const QModelIndex &index ) const
367{
368 if ( !index.isValid() )
369 return QgsBookmark();
370
371 const int managerCount = mManager->bookmarks().count();
372 const int projectCount = mProjectManager->bookmarks().count();
373 if ( index.row() < managerCount )
374 return mManager->bookmarks().at( index.row() );
375 else if ( index.row() < managerCount + projectCount )
376 return mProjectManager->bookmarks().at( index.row() - managerCount );
377 return QgsBookmark();
378}
379
380//
381// QgsBookmarkManagerProxyModel
382//
383
385 : QSortFilterProxyModel( parent )
386 , mModel( new QgsBookmarkManagerModel( manager, projectManager, this ) )
387{
388 setSourceModel( mModel );
389 setDynamicSortFilter( true );
390 setSortLocaleAware( true );
391 setFilterCaseSensitivity( Qt::CaseInsensitive );
392 sort( 0 );
393}
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