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