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