QGIS API Documentation 3.99.0-Master (26c88405ac0)
Loading...
Searching...
No Matches
qgsprojectionselectiontreewidget.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * qgsprojectionselector.cpp *
3 * Copyright (C) 2005 by Tim Sutton *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 ***************************************************************************/
12
13#include "moc_qgsprojectionselectiontreewidget.cpp"
14
15//standard includes
16#include <sqlite3.h>
17
18//qgis includes
19#include "qgis.h" //magic numbers here
20#include "qgsapplication.h"
21#include "qgslogger.h"
23#include "qgssettings.h"
24#include "qgsrectangle.h"
25#include "qgsdatums.h"
26#include "qgsprojoperation.h"
27#include "qgsstringutils.h"
28#include "qgsunittypes.h"
30
31//qt includes
32#include <QAction>
33#include <QToolButton>
34#include <QMenu>
35#include <QFileInfo>
36#include <QHeaderView>
37#include <QResizeEvent>
38#include <QMessageBox>
39#include <QRegularExpression>
40
41#ifdef ENABLE_MODELTEST
42#include "modeltest.h"
43#endif
44
46 : QWidget( parent )
47{
48 setupUi( this );
49
50 mCrsModel = new QgsCoordinateReferenceSystemProxyModel( this );
51 mCrsModel->setFilters( filters );
52
53 mRecentCrsModel = new QgsRecentCoordinateReferenceSystemTableModel( this );
54 mRecentCrsModel->setFilters( filters );
55
56 lstCoordinateSystems->setModel( mCrsModel );
57 lstCoordinateSystems->setSelectionBehavior( QAbstractItemView::SelectRows );
58
59 lstRecent->setModel( mRecentCrsModel );
60 lstRecent->viewport()->setAttribute( Qt::WA_Hover );
61 lstRecent->setSelectionBehavior( QAbstractItemView::SelectRows );
62 lstRecent->setRootIsDecorated( false );
63
64 RemoveRecentCrsDelegate *removeDelegate = new RemoveRecentCrsDelegate( lstRecent );
65 lstRecent->setItemDelegateForColumn( 2, removeDelegate );
66 lstRecent->viewport()->installEventFilter( removeDelegate );
67
68 if ( mCrsModel->rowCount() == 1 )
69 {
70 // if only one group, expand it by default
71 lstCoordinateSystems->expand( mCrsModel->index( 0, 0, QModelIndex() ) );
72 }
73
74 QFont f = teProjection->font();
75 f.setPointSize( f.pointSize() - 2 );
76 teProjection->setFont( f );
77
78 leSearch->setShowSearchIcon( true );
79
80 connect( lstCoordinateSystems, &QTreeView::doubleClicked, this, &QgsProjectionSelectionTreeWidget::lstCoordinateSystemsDoubleClicked );
81 connect( lstRecent, &QTreeView::doubleClicked, this, &QgsProjectionSelectionTreeWidget::lstRecentDoubleClicked );
82 connect( lstRecent, &QTreeView::clicked, this, &QgsProjectionSelectionTreeWidget::lstRecentClicked );
83 connect( lstCoordinateSystems->selectionModel(), &QItemSelectionModel::selectionChanged, this, &QgsProjectionSelectionTreeWidget::lstCoordinateSystemsSelectionChanged );
84 connect( lstRecent->selectionModel(), &QItemSelectionModel::selectionChanged, this, &QgsProjectionSelectionTreeWidget::lstRecentSelectionChanged );
85 connect( cbxHideDeprecated, &QCheckBox::toggled, this, [this]( bool selected ) {
86 mCrsModel->setFilterDeprecated( selected );
87 mRecentCrsModel->setFilterDeprecated( selected );
88 } );
89 connect( leSearch, &QgsFilterLineEdit::textChanged, this, [this]( const QString &filter ) {
90 mCrsModel->setFilterString( filter );
91 mRecentCrsModel->setFilterString( filter );
92 if ( filter.length() >= 3 )
93 lstCoordinateSystems->expandAll();
94 } );
95
96 mAreaCanvas->setVisible( mShowMap );
97
98 lstCoordinateSystems->header()->setSectionResizeMode( AuthidColumn, QHeaderView::Stretch );
99 lstRecent->header()->setSectionResizeMode( AuthidColumn, QHeaderView::Stretch );
100
101 // Clear Crs Column
102 lstRecent->header()->setMinimumSectionSize( 10 );
103 lstRecent->header()->setStretchLastSection( false );
104 lstRecent->header()->resizeSection( ClearColumn, 20 );
105
106 // Clear recent crs context menu
107 lstRecent->setContextMenuPolicy( Qt::CustomContextMenu );
108 connect( lstRecent, &QTreeView::customContextMenuRequested, this, [this]( const QPoint &pos ) {
109 // If list is empty, do nothing
110 if ( lstRecent->model()->rowCount() == 0 )
111 return;
112 QMenu menu;
113 // Clear selected
114 const QModelIndex currentIndex = lstRecent->indexAt( pos );
115 if ( currentIndex.isValid() )
116 {
117 QAction *clearSelected = menu.addAction( QgsApplication::getThemeIcon( "/mIconClearItem.svg" ), tr( "Remove Selected CRS from Recently Used CRS" ) );
118 connect( clearSelected, &QAction::triggered, this, [this, currentIndex] { removeRecentCrsItem( currentIndex ); } );
119 menu.addSeparator();
120 }
121 // Clear all
122 QAction *clearAll = menu.addAction( QgsApplication::getThemeIcon( "/console/iconClearConsole.svg" ), tr( "Clear All Recently Used CRS" ) );
123 connect( clearAll, &QAction::triggered, this, &QgsProjectionSelectionTreeWidget::clearRecentCrs );
124 menu.exec( lstRecent->viewport()->mapToGlobal( pos ) );
125 } );
126
127 // Install event filter to catch delete key press on the recent crs list
128 lstRecent->installEventFilter( this );
129
130 mCheckBoxNoProjection->setHidden( true );
131 mCheckBoxNoProjection->setEnabled( false );
132 connect( mCheckBoxNoProjection, &QCheckBox::toggled, this, [this] {
133 if ( !mBlockSignals )
134 {
135 emit crsSelected();
137 }
138 } );
139 connect( mCheckBoxNoProjection, &QCheckBox::toggled, this, [this]( bool checked ) {
140 if ( mCheckBoxNoProjection->isEnabled() )
141 {
142 mFrameProjections->setDisabled( checked );
143 }
144 } );
145
146 QgsSettings settings;
147 mSplitter->restoreState( settings.value( QStringLiteral( "Windows/ProjectionSelector/splitterState" ) ).toByteArray() );
148}
149
151{
152 QgsSettings settings;
153 settings.setValue( QStringLiteral( "Windows/ProjectionSelector/splitterState" ), mSplitter->saveState() );
154
155 // Push current projection to front, only if set
156 const QgsCoordinateReferenceSystem selectedCrs = crs();
157 if ( selectedCrs.isValid() )
159}
160
162{
163 lstCoordinateSystems->header()->resizeSection( NameColumn, event->size().width() - 240 );
164 lstCoordinateSystems->header()->resizeSection( AuthidColumn, 240 );
165
166 lstRecent->header()->resizeSection( NameColumn, event->size().width() - 260 );
167 lstRecent->header()->resizeSection( AuthidColumn, 240 );
168 lstRecent->header()->resizeSection( ClearColumn, 20 );
169}
170
171bool QgsProjectionSelectionTreeWidget::eventFilter( QObject *obj, QEvent *ev )
172{
173 if ( obj != lstRecent )
174 return false;
175
176 if ( ev->type() != QEvent::KeyPress )
177 return false;
178
179 QKeyEvent *keyEvent = static_cast<QKeyEvent *>( ev );
180 if ( keyEvent->matches( QKeySequence::Delete ) )
181 {
182 const QModelIndex currentIndex = lstRecent->selectionModel()->selectedRows( 0 ).value( 0 );
183 if ( currentIndex.isValid() )
184 removeRecentCrsItem( currentIndex );
185 return true;
186 }
187
188 return false;
189}
190
191void QgsProjectionSelectionTreeWidget::selectCrsByAuthId( const QString &authid )
192{
193 const QModelIndex sourceIndex = mCrsModel->coordinateReferenceSystemModel()->authIdToIndex( authid );
194 if ( !sourceIndex.isValid() )
195 return;
196
197 const QModelIndex proxyIndex = mCrsModel->mapFromSource( sourceIndex );
198 if ( proxyIndex.isValid() )
199 {
200 lstCoordinateSystems->selectionModel()->select( proxyIndex, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
201 lstCoordinateSystems->scrollTo( proxyIndex );
202 }
203 else
204 {
205 // deselect the selected item to avoid confusing the user
206 lstCoordinateSystems->clearSelection();
207 lstRecent->clearSelection();
208 teProjection->clear();
209 }
210}
211
213{
214 if ( !crs.isValid() )
215 {
216 mCheckBoxNoProjection->setChecked( true );
217 }
218 else
219 {
220 mBlockSignals = true;
221 mCheckBoxNoProjection->setChecked( false );
222 mBlockSignals = false;
223
224 if ( !crs.authid().isEmpty() )
225 selectCrsByAuthId( crs.authid() );
226 else
227 loadUnknownCrs( crs );
228
229 const bool changed = crs != QgsProjectionSelectionTreeWidget::crs();
230 if ( changed )
231 {
232 emit crsSelected();
234 }
235 }
236}
237
239{
240 mAreaCanvas->setCanvasRect( rect );
241}
242
244{
245 return mAreaCanvas->canvasRect();
246}
247
252
254{
255 mCrsModel->setFilters( filters );
256 mRecentCrsModel->setFilters( filters );
257 if ( mCrsModel->rowCount() == 1 )
258 {
259 // if only one group, expand it by default
260 lstCoordinateSystems->expand( mCrsModel->index( 0, 0, QModelIndex() ) );
261 }
262}
263
265{
266 if ( mCheckBoxNoProjection->isEnabled() && mCheckBoxNoProjection->isChecked() )
268
269 const QModelIndex currentIndex = lstCoordinateSystems->selectionModel()->selectedRows( 0 ).value( 0 );
270 const QString authid = currentIndex.data( static_cast<int>( QgsCoordinateReferenceSystemModel::CustomRole::AuthId ) ).toString();
271 if ( !authid.isEmpty() )
272 {
274 }
275 else
276 {
277 // custom CRS
278 const QString wkt = currentIndex.data( static_cast<int>( QgsCoordinateReferenceSystemModel::CustomRole::Wkt ) ).toString();
279 const QString proj = currentIndex.data( static_cast<int>( QgsCoordinateReferenceSystemModel::CustomRole::Proj ) ).toString();
280
281 if ( !wkt.isEmpty() )
283 else if ( !proj.isEmpty() )
285 else
287 }
288}
289
291{
292 mCheckBoxNoProjection->setVisible( show );
293 mCheckBoxNoProjection->setEnabled( show );
294 if ( show )
295 {
296 mFrameProjections->setDisabled( mCheckBoxNoProjection->isChecked() );
297 }
298}
299
301{
302 mShowMap = show;
303 mAreaCanvas->setVisible( show );
304}
305
307{
308 return !mCheckBoxNoProjection->isHidden();
309}
310
312{
313 mCheckBoxNoProjection->setText( text );
314}
315
317{
318 return mShowMap;
319}
320
322{
323 if ( mCheckBoxNoProjection->isChecked() )
324 {
325 return true;
326 }
327 else
328 {
329 const QModelIndex currentIndex = lstCoordinateSystems->selectionModel()->selectedRows( 0 ).value( 0 );
330 const QString authid = currentIndex.data( static_cast<int>( QgsCoordinateReferenceSystemModel::CustomRole::AuthId ) ).toString();
331 const QString wkt = currentIndex.data( static_cast<int>( QgsCoordinateReferenceSystemModel::CustomRole::Wkt ) ).toString();
332 const QString proj = currentIndex.data( static_cast<int>( QgsCoordinateReferenceSystemModel::CustomRole::Proj ) ).toString();
333 return !authid.isEmpty() || !wkt.isEmpty() || !proj.isEmpty();
334 }
335}
336
337void QgsProjectionSelectionTreeWidget::setOgcWmsCrsFilter( const QSet<QString> &crsFilter )
338{
339 mCrsModel->setFilterAuthIds( crsFilter );
340}
341
342void QgsProjectionSelectionTreeWidget::loadUnknownCrs( const QgsCoordinateReferenceSystem &crs )
343{
344 const QModelIndex sourceIndex = mCrsModel->coordinateReferenceSystemModel()->addCustomCrs( crs );
345 lstCoordinateSystems->selectionModel()->select( mCrsModel->mapFromSource( sourceIndex ), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
346 lstCoordinateSystems->scrollTo( mCrsModel->mapFromSource( sourceIndex ) );
347}
348
349// New coordinate system selected from the list
350void QgsProjectionSelectionTreeWidget::lstCoordinateSystemsSelectionChanged( const QItemSelection &selected, const QItemSelection & )
351{
352 if ( selected.isEmpty() )
353 {
354 QgsDebugMsgLevel( QStringLiteral( "no current item" ), 4 );
355 return;
356 }
357
358 const QModelIndex selectedProxyIndex = lstCoordinateSystems->selectionModel()->selectedRows( 0 ).value( 0 );
359 if ( !selectedProxyIndex.isValid() )
360 return;
361
362 lstCoordinateSystems->scrollTo( selectedProxyIndex );
363 const QModelIndex sourceIndex = mCrsModel->mapToSource( selectedProxyIndex );
364
365 // If the item has children, it's not an end node in the tree, and
366 // hence is just a grouping thingy, not an actual CRS.
367 if ( mCrsModel->coordinateReferenceSystemModel()->rowCount( sourceIndex ) == 0 )
368 {
369 // Found a real CRS
370 if ( !mBlockSignals )
371 {
372 emit crsSelected();
373 emit hasValidSelectionChanged( true );
374 }
375
376 updateBoundsPreview();
377
378 const QString crsAuthId = mCrsModel->coordinateReferenceSystemModel()->data( sourceIndex, static_cast<int>( QgsCoordinateReferenceSystemModel::CustomRole::AuthId ) ).toString();
379 if ( !crsAuthId.isEmpty() )
380 {
381 const QModelIndexList recentMatches = mRecentCrsModel->match( mRecentCrsModel->index( 0, 0 ), static_cast<int>( QgsRecentCoordinateReferenceSystemsModel::CustomRole::AuthId ), crsAuthId );
382 if ( !recentMatches.isEmpty() )
383 {
384 QgsDebugMsgLevel( QStringLiteral( "found srs %1 in recent" ).arg( crsAuthId ), 4 );
385
386 lstRecent->selectionModel()->select( recentMatches.at( 0 ), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
387 lstRecent->scrollTo( recentMatches.at( 0 ) );
388 }
389 else
390 {
391 QgsDebugMsgLevel( QStringLiteral( "srs %1 not recent" ).arg( crsAuthId ), 4 );
392 lstRecent->clearSelection();
393 lstCoordinateSystems->setFocus( Qt::OtherFocusReason );
394 }
395 }
396 else
397 {
398 lstRecent->clearSelection();
399 lstCoordinateSystems->setFocus( Qt::OtherFocusReason );
400 }
401 }
402 else
403 {
404 // Not a CRS
405 teProjection->clear();
406 lstRecent->clearSelection();
407 emit hasValidSelectionChanged( false );
408 }
409}
410
411void QgsProjectionSelectionTreeWidget::lstCoordinateSystemsDoubleClicked( const QModelIndex &index )
412{
413 if ( !index.isValid() )
414 {
415 QgsDebugMsgLevel( QStringLiteral( "no current item" ), 4 );
416 return;
417 }
418
419 // If the item has children, it's not an end node in the tree, and
420 // hence is just a grouping thingy, not an actual CRS.
421 if ( !mCrsModel->coordinateReferenceSystemModel()->hasChildren( mCrsModel->mapToSource( index ) ) )
423}
424
425void QgsProjectionSelectionTreeWidget::lstRecentSelectionChanged( const QItemSelection &selected, const QItemSelection & )
426{
427 if ( selected.isEmpty() )
428 {
429 QgsDebugMsgLevel( QStringLiteral( "no current item" ), 4 );
430 return;
431 }
432
433 const QModelIndex selectedIndex = lstRecent->selectionModel()->selectedRows( 0 ).value( 0 );
434 if ( !selectedIndex.isValid() )
435 return;
436
437 lstRecent->scrollTo( selectedIndex );
438
439 const QString selectedAuthId = mRecentCrsModel->crs( selectedIndex ).authid();
440 const QModelIndex sourceIndex = mCrsModel->coordinateReferenceSystemModel()->authIdToIndex( selectedAuthId );
441 if ( sourceIndex.isValid() )
442 {
443 const QModelIndex proxyIndex = mCrsModel->mapFromSource( sourceIndex );
444 if ( proxyIndex.isValid() )
445 {
446 lstCoordinateSystems->selectionModel()->select( proxyIndex, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
447 lstCoordinateSystems->scrollTo( proxyIndex );
448 }
449 }
450}
451
452void QgsProjectionSelectionTreeWidget::lstRecentDoubleClicked( const QModelIndex &index )
453{
454 QgsDebugMsgLevel( QStringLiteral( "Entered." ), 4 );
455 if ( !index.isValid() )
456 {
457 QgsDebugMsgLevel( QStringLiteral( "no current item" ), 4 );
458 return;
459 }
460
462}
463
464void QgsProjectionSelectionTreeWidget::lstRecentClicked( const QModelIndex &index )
465{
466 if ( index.column() == ClearColumn )
467 {
468 removeRecentCrsItem( index );
469 }
470}
471
475
476void QgsProjectionSelectionTreeWidget::updateBoundsPreview()
477{
478 const QgsCoordinateReferenceSystem currentCrs = crs();
479 if ( !currentCrs.isValid() )
480 return;
481
482 QgsRectangle rect = currentCrs.bounds();
483 QString extentString = tr( "Extent not known" );
484 mAreaCanvas->setPreviewRect( rect );
485 if ( !rect.isNull() && !rect.isEmpty() )
486 {
487 extentString = QStringLiteral( "%1, %2, %3, %4" )
488 .arg( rect.xMinimum(), 0, 'f', 2 )
489 .arg( rect.yMinimum(), 0, 'f', 2 )
490 .arg( rect.xMaximum(), 0, 'f', 2 )
491 .arg( rect.yMaximum(), 0, 'f', 2 );
492 }
493
494 QStringList properties;
495 if ( currentCrs.isGeographic() )
496 properties << tr( "Geographic (uses latitude and longitude for coordinates)" );
497 else
498 {
499 properties << tr( "Units: %1" ).arg( QgsUnitTypes::toString( currentCrs.mapUnits() ) );
500 }
501 properties << ( currentCrs.isDynamic() ? tr( "Dynamic (relies on a datum which is not plate-fixed)" ) : tr( "Static (relies on a datum which is plate-fixed)" ) );
502
503 try
504 {
505 const QString celestialBody = currentCrs.celestialBodyName();
506 if ( !celestialBody.isEmpty() )
507 {
508 properties << tr( "Celestial body: %1" ).arg( celestialBody );
509 }
510 }
511 catch ( QgsNotSupportedException & )
512 {
513 }
514
515 try
516 {
517 const QgsDatumEnsemble ensemble = currentCrs.datumEnsemble();
518 if ( ensemble.isValid() )
519 {
520 QString id;
521 if ( !ensemble.code().isEmpty() )
522 id = QStringLiteral( "<i>%1</i> (%2:%3)" ).arg( ensemble.name(), ensemble.authority(), ensemble.code() );
523 else
524 id = QStringLiteral( "<i>%1</i>”" ).arg( ensemble.name() );
525 if ( ensemble.accuracy() > 0 )
526 {
527 properties << tr( "Based on %1, which has a limited accuracy of <b>at best %2 meters</b>." ).arg( id ).arg( ensemble.accuracy() );
528 }
529 else
530 {
531 properties << tr( "Based on %1, which has a limited accuracy." ).arg( id );
532 }
533 }
534 }
535 catch ( QgsNotSupportedException & )
536 {
537 }
538
539 const QgsProjOperation operation = currentCrs.operation();
540 properties << tr( "Method: %1" ).arg( operation.description() );
541
542 const QString propertiesString = QStringLiteral( "<dt><b>%1</b></dt><dd><ul><li>%2</li></ul></dd>" ).arg( tr( "Properties" ), properties.join( QLatin1String( "</li><li>" ) ) );
543
544 const QString extentHtml = QStringLiteral( "<dt><b>%1</b></dt><dd>%2</dd>" ).arg( tr( "Extent" ), extentString );
545 const QString wktString = QStringLiteral( "<dt><b>%1</b></dt><dd><code>%2</code></dd>" ).arg( tr( "WKT" ), currentCrs.toWkt( Qgis::CrsWktVariant::Preferred, true ).replace( '\n', QLatin1String( "<br>" ) ).replace( ' ', QLatin1String( "&nbsp;" ) ) );
546 const QString proj4String = QStringLiteral( "<dt><b>%1</b></dt><dd><code>%2</code></dd>" ).arg( tr( "Proj4" ), currentCrs.toProj() );
547
548#ifdef Q_OS_WIN
549 const int smallerPointSize = std::max( font().pointSize() - 1, 8 ); // bit less on windows, due to poor rendering of small point sizes
550#else
551 const int smallerPointSize = std::max( font().pointSize() - 2, 6 );
552#endif
553
554 const QModelIndex currentIndex = lstCoordinateSystems->selectionModel()->selectedRows( 0 ).value( 0 );
555 QString selectedName;
556 if ( currentIndex.isValid() )
557 {
558 selectedName = currentIndex.data( static_cast<int>( QgsCoordinateReferenceSystemModel::CustomRole::Name ) ).toString();
559 }
560 teProjection->setText( QStringLiteral( "<div style=\"font-size: %1pt\"><h3>%2</h3><dl>" ).arg( smallerPointSize ).arg( selectedName ) + propertiesString + wktString + proj4String + extentHtml + QStringLiteral( "</dl></div>" ) );
561}
562
564{
565 // If the list is empty, there is nothing to do
566 if ( QgsApplication::coordinateReferenceSystemRegistry()->recentCrs().isEmpty() )
567 {
568 return;
569 }
570
571 // Ask for confirmation
572 if ( QMessageBox::question( this, tr( "Clear Recent CRS" ), tr( "Are you sure you want to clear the list of recently used coordinate reference system?" ), QMessageBox::Yes | QMessageBox::No ) != QMessageBox::Yes )
573 {
574 return;
575 }
577}
578
579void QgsProjectionSelectionTreeWidget::removeRecentCrsItem( const QModelIndex &index )
580{
581 const QgsCoordinateReferenceSystem selectedRecentCrs = mRecentCrsModel->crs( index );
583}
584
585
587QgsRecentCoordinateReferenceSystemTableModel::QgsRecentCoordinateReferenceSystemTableModel( QObject *parent )
589{
590#ifdef ENABLE_MODELTEST
591 new ModelTest( this, this );
592#endif
593}
594
595QVariant QgsRecentCoordinateReferenceSystemTableModel::headerData( int section, Qt::Orientation orientation, int role ) const
596{
597 if ( orientation == Qt::Horizontal )
598 {
599 switch ( role )
600 {
601 case Qt::DisplayRole:
602 switch ( section )
603 {
604 case 0:
605 return tr( "Coordinate Reference System" );
606 case 1:
607 return tr( "Authority ID" );
608 case 2:
609 return QString();
610 default:
611 break;
612 }
613 break;
614
615 default:
616 break;
617 }
618 }
619 return QVariant();
620}
621
622QVariant QgsRecentCoordinateReferenceSystemTableModel::data( const QModelIndex &index, int role ) const
623{
624 if ( !index.isValid() )
625 return QVariant();
626
627 const int column = index.column();
628 switch ( column )
629 {
630 case 1:
631 {
632 const QgsCoordinateReferenceSystem lCrs = crs( index );
633 switch ( role )
634 {
635 case Qt::DisplayRole:
636 case Qt::ToolTipRole:
637 return lCrs.authid();
638
639 default:
640 break;
641 }
642 break;
643 }
644
645 case 2:
646 {
647 switch ( role )
648 {
649 case Qt::ToolTipRole:
650 return tr( "Remove from recently used CRS" );
651
652 default:
653 break;
654 }
655 break;
656 }
657
658 default:
659 break;
660 }
661 return QgsRecentCoordinateReferenceSystemsProxyModel::data( index, role );
662}
663
664
665//
666// RemoveRecentCrsDelegate
667//
668
669RemoveRecentCrsDelegate::RemoveRecentCrsDelegate( QObject *parent )
670 : QStyledItemDelegate( parent )
671{
672}
673
674bool RemoveRecentCrsDelegate::eventFilter( QObject *obj, QEvent *event )
675{
676 if ( event->type() == QEvent::HoverEnter || event->type() == QEvent::HoverMove )
677 {
678 QHoverEvent *hoverEvent = static_cast<QHoverEvent *>( event );
679 if ( QAbstractItemView *view = qobject_cast<QAbstractItemView *>( obj->parent() ) )
680 {
681 const QModelIndex indexUnderMouse = view->indexAt( hoverEvent->pos() );
682 setHoveredIndex( indexUnderMouse );
683 view->viewport()->update();
684 }
685 }
686 else if ( event->type() == QEvent::HoverLeave )
687 {
688 setHoveredIndex( QModelIndex() );
689 qobject_cast<QWidget *>( obj )->update();
690 }
691 return QStyledItemDelegate::eventFilter( obj, event );
692}
693
694void RemoveRecentCrsDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
695{
696 QStyledItemDelegate::paint( painter, option, index );
697
698 if ( index == mHoveredIndex )
699 {
700 QStyleOptionButton buttonOption;
701 buttonOption.initFrom( option.widget );
702 buttonOption.rect = option.rect;
703
704 option.widget->style()->drawControl( QStyle::CE_PushButton, &buttonOption, painter );
705 }
706
707 const QIcon icon = QgsApplication::getThemeIcon( "/mIconClearItem.svg" );
708 const QRect iconRect( option.rect.left() + ( option.rect.width() - 16 ) / 2, option.rect.top() + ( option.rect.height() - 16 ) / 2, 16, 16 );
709
710 icon.paint( painter, iconRect );
711}
712
713void RemoveRecentCrsDelegate::setHoveredIndex( const QModelIndex &index )
714{
715 mHoveredIndex = index;
716}
717
@ Preferred
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
Definition qgis.h:2439
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QgsCoordinateReferenceSystemRegistry * coordinateReferenceSystemRegistry()
Returns the application's coordinate reference system (CRS) registry, which handles known CRS definit...
QModelIndex addCustomCrs(const QgsCoordinateReferenceSystem &crs)
Adds a custom crs to the model.
QModelIndex authIdToIndex(const QString &authId) const
Retrieves the model index corresponding to a CRS with the specified authId.
@ AuthId
The coordinate reference system authority name and id.
@ Wkt
The coordinate reference system's WKT representation. This is only used for non-standard CRS (i....
@ Proj
The coordinate reference system's PROJ representation. This is only used for non-standard CRS (i....
A sort/filter proxy model for coordinate reference systems.
QgsCoordinateReferenceSystemModel * coordinateReferenceSystemModel()
Returns the underlying source model.
void removeRecent(const QgsCoordinateReferenceSystem &crs)
Removes a CRS from the list of recently used CRS.
void clearRecent()
Cleans the list of recently used CRS.
void pushRecent(const QgsCoordinateReferenceSystem &crs)
Pushes a recently used CRS to the top of the recent CRS list.
Represents a coordinate reference system (CRS).
static QgsCoordinateReferenceSystem fromOgcWmsCrs(const QString &ogcCrs)
Creates a CRS from a given OGC WMS-format Coordinate Reference System string.
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
QgsRectangle bounds() const
Returns the approximate bounds for the region the CRS is usable within.
QString toProj() const
Returns a Proj string representation of this CRS.
QgsDatumEnsemble datumEnsemble() const
Attempts to retrieve datum ensemble details from the CRS.
bool isDynamic() const
Returns true if the CRS is a dynamic CRS.
static QgsCoordinateReferenceSystem fromProj(const QString &proj)
Creates a CRS from a proj style formatted string.
QString toWkt(Qgis::CrsWktVariant variant=Qgis::CrsWktVariant::Wkt1Gdal, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.
QString celestialBodyName() const
Attempts to retrieve the name of the celestial body associated with the CRS (e.g.
static QgsCoordinateReferenceSystem fromWkt(const QString &wkt)
Creates a CRS from a WKT spatial ref sys definition string.
QgsProjOperation operation() const
Returns information about the PROJ operation associated with the coordinate reference system,...
QString code() const
Identification code, e.g.
Definition qgsdatums.h:122
QString authority() const
Authority name, e.g.
Definition qgsdatums.h:117
bool isValid() const
Returns true if the datum ensemble is a valid object, or false if it is a null/invalid object.
Definition qgsdatums.h:102
QString name() const
Display name of datum ensemble.
Definition qgsdatums.h:107
double accuracy() const
Positional accuracy (in meters).
Definition qgsdatums.h:112
QString description() const
Description.
void resizeEvent(QResizeEvent *event) override
void setPreviewRect(const QgsRectangle &rect)
Sets the initial "preview" rectangle for the bounds overview map.
void setShowBoundsMap(bool show)
Sets whether to show the bounds preview map.
void crsSelected()
Emitted when a projection is selected in the widget.
Q_DECL_DEPRECATED void pushProjectionToFront()
Marks the current selected projection for push to front of recent projections list.
QgsCoordinateReferenceSystem crs() const
Returns the CRS currently selected in the widget.
bool showNoProjection() const
Returns whether the "no/invalid" projection option is shown.
void setShowNoProjection(bool show)
Sets whether a "no/invalid" projection option should be shown.
bool showBoundsMap() const
Returns whether the bounds preview map is shown.
QgsRectangle previewRect() const
The initial "preview" rectangle for the bounds overview map.
void projectionDoubleClicked()
Emitted when a projection is double clicked in the list.
bool hasValidSelection() const
Returns true if the current selection in the widget is a valid choice.
QgsCoordinateReferenceSystemProxyModel::Filters filters() const
Returns the filters set on the available CRS.
void setOgcWmsCrsFilter(const QSet< QString > &crsFilter)
Filters this widget by the given CRSs.
void setFilters(QgsCoordinateReferenceSystemProxyModel::Filters filters)
Sets filters for the available CRS.
bool eventFilter(QObject *obj, QEvent *ev) override
void setNotSetText(const QString &text)
Sets the text to show for the not set option.
void clearRecentCrs()
Clear the list of recent projections.
QgsProjectionSelectionTreeWidget(QWidget *parent=nullptr, QgsCoordinateReferenceSystemProxyModel::Filters filters=QgsCoordinateReferenceSystemProxyModel::FilterHorizontal|QgsCoordinateReferenceSystemProxyModel::FilterCompound)
Constructor for QgsProjectionSelectionTreeWidget, with the specified parent widget.
void hasValidSelectionChanged(bool isValid)
Emitted when the selection in the tree is changed from a valid selection to an invalid selection,...
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets the initial crs to show within the dialog.
A sort/filter proxy model for recent coordinate reference systems.
A rectangle specified with double values.
double xMinimum
double yMinimum
double xMaximum
double yMaximum
Stores settings for use within QGIS.
Definition qgssettings.h:65
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
static Q_INVOKABLE QString toString(Qgis::DistanceUnit unit)
Returns a translated string representing a distance unit.
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:61