QGIS API Documentation 4.1.0-Master (5bf3c20f3c9)
Loading...
Searching...
No Matches
qgsprojectionselectionwidget.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsprojectionselectionwidget.cpp
3 --------------------------------------
4 Date : 05.01.2015
5 Copyright : (C) 2015 Denis Rouzaud
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
17
18#include "qgsapplication.h"
20#include "qgsdatums.h"
22#include "qgsproject.h"
25#include "qgssettings.h"
26
27#include <QHBoxLayout>
28#include <QString>
29
30#include "moc_qgsprojectionselectionwidget.cpp"
31
32using namespace Qt::StringLiterals;
33
34#ifdef ENABLE_MODELTEST
35#include "modeltest.h"
36#endif
37
38
40StandardCoordinateReferenceSystemsModel::StandardCoordinateReferenceSystemsModel( QObject *parent )
41 : QAbstractItemModel( parent )
42 , mProjectCrs( QgsProject::instance()->crs() )
43{
44#ifdef ENABLE_MODELTEST
45 new ModelTest( this, this );
46#endif
47
48 const QgsSettings settings;
49 mDefaultCrs = QgsCoordinateReferenceSystem( settings.value( u"/projections/defaultProjectCrs"_s, Qgis::geographicCrsAuthId(), QgsSettings::App ).toString() );
50
52 mCurrentCrs.updateDefinition();
53 mLayerCrs.updateDefinition();
54 mProjectCrs.updateDefinition();
55 mDefaultCrs.updateDefinition();
56 } );
57
58 connect( QgsProject::instance(), &QgsProject::crsChanged, this, [this] { mProjectCrs = QgsProject::instance()->crs(); } );
59}
60
61Qt::ItemFlags StandardCoordinateReferenceSystemsModel::flags( const QModelIndex &index ) const
62{
63 if ( !index.isValid() )
64 {
65 return Qt::ItemFlags();
66 }
67
68 return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
69}
70
71QVariant StandardCoordinateReferenceSystemsModel::data( const QModelIndex &index, int role ) const
72{
73 const QgsProjectionSelectionWidget::CrsOption option = optionForIndex( index );
75 return QVariant();
76
77 const QgsCoordinateReferenceSystem crs = StandardCoordinateReferenceSystemsModel::crs( index );
78 switch ( role )
79 {
80 case Qt::DisplayRole:
81 case Qt::ToolTipRole:
82 switch ( option )
83 {
85 return tr( "Project CRS: %1" ).arg( mProjectCrs.userFriendlyIdentifier() );
87 return tr( "Default CRS: %1" ).arg( mDefaultCrs.userFriendlyIdentifier() );
89 return tr( "Layer CRS: %1" ).arg( mLayerCrs.userFriendlyIdentifier() );
91 return mNotSetText;
96 break;
97 }
98 break;
99
100 case RoleCrs:
101 return crs;
102
103 case RoleOption:
104 return static_cast<int>( option );
105
106 default:
107 break;
108 }
109
110 return QVariant();
111}
112
113int StandardCoordinateReferenceSystemsModel::rowCount( const QModelIndex &parent ) const
114{
115 if ( parent.isValid() )
116 return 0;
117
118 return 5;
119}
120
121int StandardCoordinateReferenceSystemsModel::columnCount( const QModelIndex & ) const
122{
123 return 1;
124}
125
126QModelIndex StandardCoordinateReferenceSystemsModel::index( int row, int column, const QModelIndex &parent ) const
127{
128 if ( row < 0 || row >= rowCount() || column != 0 || parent.isValid() )
129 return QModelIndex();
130
131 return createIndex( row, column );
132}
133
134QModelIndex StandardCoordinateReferenceSystemsModel::parent( const QModelIndex & ) const
135{
136 return QModelIndex();
137}
138
139QgsCoordinateReferenceSystem StandardCoordinateReferenceSystemsModel::crs( const QModelIndex &index ) const
140{
141 if ( !index.isValid() )
143
144 const QgsProjectionSelectionWidget::CrsOption option = optionForIndex( index );
145 switch ( option )
146 {
148 return mProjectCrs;
150 return mDefaultCrs;
152 return mCurrentCrs;
154 return mLayerCrs;
159 }
161}
162
163QgsProjectionSelectionWidget::CrsOption StandardCoordinateReferenceSystemsModel::optionForIndex( const QModelIndex &index ) const
164{
165 if ( !index.isValid() )
167
168 const int row = index.row();
169 switch ( row )
170 {
171 case 0:
173 case 1:
175 case 2:
177 case 3:
179 case 4:
181 default:
182 break;
183 }
184
186}
187
188QModelIndex StandardCoordinateReferenceSystemsModel::indexForOption( QgsProjectionSelectionWidget::CrsOption option ) const
189{
190 int row = 0;
191 switch ( option )
192 {
195 return QModelIndex();
197 row = 0;
198 break;
200 row = 1;
201 break;
203 row = 2;
204 break;
206 row = 3;
207 break;
209 row = 4;
210 break;
211 }
212
213 return index( row, 0, QModelIndex() );
214}
215
216void StandardCoordinateReferenceSystemsModel::setLayerCrs( const QgsCoordinateReferenceSystem &crs )
217{
218 mLayerCrs = crs;
219 const QModelIndex index = indexForOption( QgsProjectionSelectionWidget::LayerCrs );
220 emit dataChanged( index, index );
221}
222
223void StandardCoordinateReferenceSystemsModel::setCurrentCrs( const QgsCoordinateReferenceSystem &crs )
224{
225 mCurrentCrs = crs;
226 const QModelIndex index = indexForOption( QgsProjectionSelectionWidget::LayerCrs );
227 emit dataChanged( index, index );
228}
229
230void StandardCoordinateReferenceSystemsModel::setNotSetText( const QString &text )
231{
232 mNotSetText = text;
233 const QModelIndex index = indexForOption( QgsProjectionSelectionWidget::CrsNotSet );
234 emit dataChanged( index, index );
235}
236
237//
238// CombinedCoordinateReferenceSystemsModel
239//
240
241CombinedCoordinateReferenceSystemsModel::CombinedCoordinateReferenceSystemsModel( QObject *parent )
242 : QConcatenateTablesProxyModel( parent )
243 , mStandardModel( new StandardCoordinateReferenceSystemsModel( this ) )
244 , mRecentModel( new QgsRecentCoordinateReferenceSystemsProxyModel( this ) )
245{
246 addSourceModel( mStandardModel );
247 addSourceModel( mRecentModel );
248}
249
250void CombinedCoordinateReferenceSystemsModel::setNotSetText( const QString &text )
251{
252 mStandardModel->setNotSetText( text );
253}
254
255QString CombinedCoordinateReferenceSystemsModel::notSetText() const
256{
257 return mStandardModel->notSetText();
258}
259
260QgsCoordinateReferenceSystem CombinedCoordinateReferenceSystemsModel::currentCrs() const
261{
262 return mStandardModel->currentCrs();
263}
264
265//
266// CombinedCoordinateReferenceSystemsProxyModel
267//
268CombinedCoordinateReferenceSystemsProxyModel::CombinedCoordinateReferenceSystemsProxyModel( QObject *parent )
269 : QSortFilterProxyModel( parent )
270 , mModel( new CombinedCoordinateReferenceSystemsModel( this ) )
271{
272 mVisibleOptions.setFlag( QgsProjectionSelectionWidget::CurrentCrs, true );
273 mVisibleOptions.setFlag( QgsProjectionSelectionWidget::ProjectCrs, true );
274 mVisibleOptions.setFlag( QgsProjectionSelectionWidget::DefaultCrs, true );
275
276 setSourceModel( mModel );
277 setDynamicSortFilter( true );
278}
279
280bool CombinedCoordinateReferenceSystemsProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent ) const
281{
282 const QModelIndex sourceIndex = mModel->index( sourceRow, 0, sourceParent );
283
284 const QgsCoordinateReferenceSystem crs = mModel->data( sourceIndex, StandardCoordinateReferenceSystemsModel::RoleCrs ).value<QgsCoordinateReferenceSystem>();
285 if ( !mFilteredCrs.isEmpty() && !mFilteredCrs.contains( crs ) )
286 return false;
287
288 switch ( crs.type() )
289 {
292 break;
293
304 return false;
305 break;
306
309 return false;
310 break;
311
314 return false;
315 break;
316 }
317
318 const QVariant optionInt = mModel->data( sourceIndex, StandardCoordinateReferenceSystemsModel::RoleOption );
319 if ( optionInt.isValid() )
320 {
321 if ( optionInt.toInt() > 0 )
322 {
323 const QgsProjectionSelectionWidget::CrsOption option = static_cast<QgsProjectionSelectionWidget::CrsOption>( optionInt.toInt() );
324 if ( !mVisibleOptions.testFlag( option ) )
325 return false;
326
327 // specific logic for showing/hiding options:
328 switch ( option )
329 {
331 break;
332
335 // only show these options if the crs is valid
336 return crs.isValid();
337
339 // hide invalid current CRS value option only if "not set" option is shown
340 return crs.isValid() || !mVisibleOptions.testFlag( QgsProjectionSelectionWidget::CrsNotSet );
341
345 // always shown
346 break;
347 }
348 return true;
349 }
350 }
351 else
352 {
353 // a recent crs
354 // these are only shown if they aren't duplicates of a standard item already shown in the list
355 for ( QgsProjectionSelectionWidget::CrsOption standardOption :
360 {
361 const QModelIndexList standardItemIndex = mModel->match( mModel->index( 0, 0 ), StandardCoordinateReferenceSystemsModel::RoleOption, static_cast<int>( standardOption ) );
362 if ( standardItemIndex.empty() )
363 continue;
364
365 const QgsCoordinateReferenceSystem standardItemCrs = mModel->data( standardItemIndex.at( 0 ), StandardCoordinateReferenceSystemsModel::RoleCrs ).value<QgsCoordinateReferenceSystem>();
366 if ( standardItemCrs == crs && filterAcceptsRow( standardItemIndex.at( 0 ).row(), QModelIndex() ) )
367 return false;
368 }
369 }
370
371 return true;
372}
373
374void CombinedCoordinateReferenceSystemsProxyModel::setLayerCrs( const QgsCoordinateReferenceSystem &crs )
375{
376 mModel->standardModel()->setLayerCrs( crs );
377 invalidateFilter();
378}
379
380void CombinedCoordinateReferenceSystemsProxyModel::setCurrentCrs( const QgsCoordinateReferenceSystem &crs )
381{
382 mModel->standardModel()->setCurrentCrs( crs );
383 invalidateFilter();
384}
385
386void CombinedCoordinateReferenceSystemsProxyModel::setFilters( QgsCoordinateReferenceSystemProxyModel::Filters filters )
387{
388 mFilters = filters;
389 invalidateFilter();
390}
391
392QgsCoordinateReferenceSystemProxyModel::Filters CombinedCoordinateReferenceSystemsProxyModel::filters() const
393{
394 return mFilters;
395}
396
397void CombinedCoordinateReferenceSystemsProxyModel::setFilteredCrs( const QList<QgsCoordinateReferenceSystem> &crses )
398{
399 mFilteredCrs = crses;
400 invalidateFilter();
401}
402
403void CombinedCoordinateReferenceSystemsProxyModel::setOption( QgsProjectionSelectionWidget::CrsOption option, bool enabled )
404{
405 mVisibleOptions.setFlag( option, enabled );
406 invalidateFilter();
407}
408
410
411
413 : QWidget( parent )
414 , mDialogTitle( tr( "Coordinate Reference System Selector" ) )
415{
416 mCrsComboBox = new QgsHighlightableComboBox( this );
417 mCrsComboBox->setSizePolicy( QSizePolicy::Ignored, QSizePolicy::Preferred );
418
419 mModel = new CombinedCoordinateReferenceSystemsProxyModel( this );
420 mModel->setFilters( filters );
421 mCrsComboBox->setModel( mModel );
422
423 const int labelMargin = static_cast<int>( std::round( mCrsComboBox->fontMetrics().horizontalAdvance( 'X' ) ) );
424 QHBoxLayout *layout = new QHBoxLayout();
425 layout->setContentsMargins( 0, 0, 0, 0 );
426 layout->setSpacing( 0 );
427 setLayout( layout );
428
429 layout->addWidget( mCrsComboBox, 1 );
430
431 // bit of fiddlyness here -- we want the initial spacing to only be visible
432 // when the warning label is shown, so it's embedded inside mWarningLabel
433 // instead of outside it
434 mWarningLabelContainer = new QWidget();
435 QHBoxLayout *warningLayout = new QHBoxLayout();
436 warningLayout->setContentsMargins( 0, 0, 0, 0 );
437 mWarningLabel = new QLabel();
438 const QIcon icon = QgsApplication::getThemeIcon( u"mIconWarning.svg"_s );
439 const int size = static_cast<int>( std::max( 24.0, mCrsComboBox->minimumSize().height() * 0.5 ) );
440 mWarningLabel->setPixmap( icon.pixmap( icon.actualSize( QSize( size, size ) ) ) );
441 warningLayout->insertSpacing( 0, labelMargin / 2 );
442 warningLayout->insertWidget( 1, mWarningLabel );
443 mWarningLabelContainer->setLayout( warningLayout );
444 layout->addWidget( mWarningLabelContainer );
445 mWarningLabelContainer->hide();
446
447 layout->addSpacing( labelMargin / 2 );
448
449 mButton = new QToolButton( this );
450 mButton->setIcon( QgsApplication::getThemeIcon( u"mActionSetProjection.svg"_s ) );
451 mButton->setToolTip( tr( "Select CRS" ) );
452 layout->addWidget( mButton );
453
454 setFocusPolicy( Qt::StrongFocus );
455 setFocusProxy( mButton );
456 setAcceptDrops( true );
457
458 connect( mButton, &QToolButton::clicked, this, &QgsProjectionSelectionWidget::selectCrs );
459 connect( mCrsComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsProjectionSelectionWidget::comboIndexChanged );
460}
461
463{
464 const int idx = mCrsComboBox->currentIndex();
465 if ( idx >= 0 && idx < mModel->rowCount() )
466 return mModel->data( mModel->index( idx, 0 ), StandardCoordinateReferenceSystemsModel::RoleCrs ).value<QgsCoordinateReferenceSystem>();
467 else
469}
470
472{
473 switch ( option )
474 {
479 {
480 mModel->setOption( option, visible );
481 updateTooltip();
482 return;
483 }
485 //recently used CRS option cannot be readded
486 return;
488 {
489 mModel->setOption( CrsNotSet, visible );
490
491 if ( !visible )
492 {
494 }
495 else
496 {
497 if ( !mModel->combinedModel()->currentCrs().isValid() )
498 whileBlocking( mCrsComboBox )->setCurrentIndex( 0 );
499 }
500 updateTooltip();
501
502 return;
503 }
504 case Invalid:
505 return;
506 }
507}
508
510{
511 mModel->combinedModel()->setNotSetText( text );
512}
513
515{
516 mMessage = text;
517}
518
520{
521 const QModelIndexList matches = mModel->match( mModel->index( 0, 0 ), StandardCoordinateReferenceSystemsModel::Role::RoleOption, static_cast<int>( option ) );
522 return !matches.empty();
523}
524
526{
528 const QList<QgsCoordinateReferenceSystem> filteredCrses = mModel->filteredCrs();
529
530 QSet<QString> ogcFilter;
531 ogcFilter.reserve( filteredCrses.size() );
532 for ( const QgsCoordinateReferenceSystem &crs : std::as_const( filteredCrses ) )
533 {
534 ogcFilter << crs.authid();
535 }
536
537 if ( panel && panel->dockMode() )
538 {
539 mActivePanel = new QgsCrsSelectionWidget( this, mModel->filters() );
540 if ( !ogcFilter.isEmpty() )
541 mActivePanel->setOgcWmsCrsFilter( ogcFilter );
542 if ( !mMessage.isEmpty() )
543 mActivePanel->setMessage( mMessage );
544 mActivePanel->setCrs( crs() );
545
546 if ( !mModel->combinedModel()->notSetText().isEmpty() )
547 mActivePanel->setNotSetText( mModel->combinedModel()->notSetText() );
548
549 mActivePanel->setPanelTitle( mDialogTitle );
550
552 {
553 mActivePanel->setShowNoCrs( true );
554 }
555
556 connect( mActivePanel, &QgsCrsSelectionWidget::crsChanged, this, [this] {
557 if ( mIgnorePanelSignals )
558 return;
559
560 if ( !mActivePanel->hasValidSelection() )
561 return;
562
563 mCrsComboBox->blockSignals( true );
564 mCrsComboBox->setCurrentIndex( mCrsComboBox->findData( QgsProjectionSelectionWidget::CurrentCrs, StandardCoordinateReferenceSystemsModel::Role::RoleOption ) );
565 mCrsComboBox->blockSignals( false );
566 const QgsCoordinateReferenceSystem crs = mActivePanel->crs();
567
568 mIgnorePanelSignals++;
569 setCrs( crs );
570 mIgnorePanelSignals--;
571
572 emit crsChanged( crs );
573 } );
574 panel->openPanel( mActivePanel );
575 }
576 else
577 {
578 QgsProjectionSelectionDialog dlg( this, QgsGuiUtils::ModalDialogFlags, mModel->filters() );
579 if ( !mMessage.isEmpty() )
580 dlg.setMessage( mMessage );
581 if ( !ogcFilter.isEmpty() )
582 dlg.setOgcWmsCrsFilter( ogcFilter );
583 dlg.setCrs( crs() );
584 dlg.setWindowTitle( mDialogTitle );
585
586 if ( !mModel->combinedModel()->notSetText().isEmpty() )
587 dlg.setNotSetText( mModel->combinedModel()->notSetText() );
588
590 {
591 dlg.setShowNoProjection( true );
592 }
594
595 if ( dlg.exec() )
596 {
597 mCrsComboBox->blockSignals( true );
598 mCrsComboBox->setCurrentIndex( mCrsComboBox->findData( QgsProjectionSelectionWidget::CurrentCrs, StandardCoordinateReferenceSystemsModel::Role::RoleOption ) );
599 mCrsComboBox->blockSignals( false );
601 // setCrs will emit crsChanged for us
602 setCrs( crs );
603 }
604 else
605 {
606 QApplication::restoreOverrideCursor();
607 }
608 }
609}
610
612{
613 if ( !( event->possibleActions() & Qt::CopyAction ) )
614 {
615 event->ignore();
616 return;
617 }
618
619 if ( mapLayerFromMimeData( event->mimeData() ) )
620 {
621 // dragged an acceptable layer, phew
622 event->setDropAction( Qt::CopyAction );
623 event->accept();
624 mCrsComboBox->setHighlighted( true );
625 update();
626 }
627 else
628 {
629 event->ignore();
630 }
631}
632
634{
635 if ( mCrsComboBox->isHighlighted() )
636 {
637 event->accept();
638 mCrsComboBox->setHighlighted( false );
639 update();
640 }
641 else
642 {
643 event->ignore();
644 }
645}
646
648{
649 if ( !( event->possibleActions() & Qt::CopyAction ) )
650 {
651 event->ignore();
652 return;
653 }
654
655 if ( QgsMapLayer *layer = mapLayerFromMimeData( event->mimeData() ) )
656 {
657 // dropped a map layer
658 setFocus( Qt::MouseFocusReason );
659 event->setDropAction( Qt::CopyAction );
660 event->accept();
661
662 if ( layer->crs().isValid() )
663 setCrs( layer->crs() );
664 }
665 else
666 {
667 event->ignore();
668 }
669 mCrsComboBox->setHighlighted( false );
670 update();
671}
672
674{
675 return mSourceEnsemble;
676}
677
679{
680 mDialogTitle = title;
681}
682
684{
685 return mDialogTitle;
686}
687
688void QgsProjectionSelectionWidget::setFilter( const QList<QgsCoordinateReferenceSystem> &crses )
689{
690 mModel->setFilteredCrs( crses );
691}
692
697
699{
700 mModel->setFilters( filters );
701 if ( mActivePanel )
702 mActivePanel->setFilters( filters );
703}
704
706{
707 if ( mSourceEnsemble == ensemble )
708 return;
709
710 mSourceEnsemble = ensemble;
711 updateWarning();
712}
713
715{
716 return mShowAccuracyWarnings;
717}
718
720{
721 mShowAccuracyWarnings = show;
722 if ( !mShowAccuracyWarnings )
723 mWarningLabelContainer->hide();
724 else
725 updateWarning();
726}
727
728void QgsProjectionSelectionWidget::comboIndexChanged( int idx )
729{
730 if ( idx >= 0 && idx < mModel->rowCount() )
731 {
732 const QgsCoordinateReferenceSystem crs = mModel->data( mModel->index( idx, 0 ), StandardCoordinateReferenceSystemsModel::RoleCrs ).value<QgsCoordinateReferenceSystem>();
733 const QVariant optionData = mModel->data( mModel->index( idx, 0 ), StandardCoordinateReferenceSystemsModel::RoleOption );
734 if ( !optionData.isValid() || static_cast<CrsOption>( optionData.toInt() ) != QgsProjectionSelectionWidget::CrsNotSet )
735 {
736 // RoleOption is only available for items from the standard coordinate reference system model, but we
737 // are using a combined model which also has items from QgsRecentCoordinateReferenceSystemsModel
738 emit crsChanged( crs );
739 }
740 else
741 {
742 emit cleared();
743 emit crsChanged( QgsCoordinateReferenceSystem() );
744 }
745 }
746
747 updateTooltip();
748}
749
750void QgsProjectionSelectionWidget::updateWarning()
751{
752 if ( !mShowAccuracyWarnings )
753 {
754 if ( mWarningLabelContainer->isVisible() )
755 mWarningLabelContainer->hide();
756 return;
757 }
758
759 try
760 {
761 const double crsAccuracyWarningThreshold = QgsSettings().value( u"/projections/crsAccuracyWarningThreshold"_s, 0.0, QgsSettings::App ).toDouble();
762
763 const QgsDatumEnsemble ensemble = crs().datumEnsemble();
764 if ( !ensemble.isValid() || ensemble.name() == mSourceEnsemble || ( ensemble.accuracy() > 0 && ensemble.accuracy() < crsAccuracyWarningThreshold ) )
765 {
766 mWarningLabelContainer->hide();
767 }
768 else
769 {
770 mWarningLabelContainer->show();
771
772 QString warning = u"<p>"_s;
773
774 QString id;
775 if ( !ensemble.code().isEmpty() )
776 id = u"<i>%1</i> (%2:%3)"_s.arg( ensemble.name(), ensemble.authority(), ensemble.code() );
777 else
778 id = u"<i>%1</i>”"_s.arg( ensemble.name() );
779
780 if ( ensemble.accuracy() > 0 )
781 {
782 warning = tr( "The selected CRS is based on %1, which has a limited accuracy of <b>at best %2 meters</b>." ).arg( id ).arg( ensemble.accuracy() );
783 }
784 else
785 {
786 warning = tr( "The selected CRS is based on %1, which has a limited accuracy." ).arg( id );
787 }
788 warning += u"</p><p>"_s + tr( "Use an alternative CRS if accurate positioning is required." ) + u"</p>"_s;
789
790 const QList<QgsDatumEnsembleMember> members = ensemble.members();
791 if ( !members.isEmpty() )
792 {
793 warning += u"<p>"_s + tr( "%1 consists of the datums:" ).arg( ensemble.name() ) + u"</p><ul>"_s;
794
795 for ( const QgsDatumEnsembleMember &member : members )
796 {
797 if ( !member.code().isEmpty() )
798 id = u"%1 (%2:%3)"_s.arg( member.name(), member.authority(), member.code() );
799 else
800 id = member.name();
801 warning += u"<li>%1</li>"_s.arg( id );
802 }
803
804 warning += "</ul>"_L1;
805 }
806
807 mWarningLabel->setToolTip( warning );
808 }
809 }
810 catch ( QgsNotSupportedException & )
811 {
812 mWarningLabelContainer->hide();
813 }
814}
815
817{
818 const QgsCoordinateReferenceSystem prevCrs = mModel->combinedModel()->currentCrs();
819 mModel->setCurrentCrs( crs );
820
821 if ( crs.isValid() )
822 {
824 mCrsComboBox->blockSignals( true );
825 mCrsComboBox->setCurrentIndex( mCrsComboBox->findData( QgsProjectionSelectionWidget::CurrentCrs, StandardCoordinateReferenceSystemsModel::Role::RoleOption ) );
826 mCrsComboBox->blockSignals( false );
827 }
828 else
829 {
830 const int crsNotSetIndex = mCrsComboBox->findData( QgsProjectionSelectionWidget::CrsNotSet, StandardCoordinateReferenceSystemsModel::Role::RoleOption );
831 if ( crsNotSetIndex >= 0 )
832 {
833 mCrsComboBox->blockSignals( true );
834 mCrsComboBox->setCurrentIndex( crsNotSetIndex );
835 mCrsComboBox->blockSignals( false );
836 }
837 }
838 if ( mActivePanel && !mIgnorePanelSignals )
839 {
840 mIgnorePanelSignals++;
841 mActivePanel->setCrs( crs );
842 mIgnorePanelSignals--;
843 }
844 if ( prevCrs != crs )
845 {
846 emit crsChanged( crs );
847 }
848 updateTooltip();
849}
850
852{
853 mModel->setLayerCrs( crs );
854}
855
857{
858 if ( crs.isValid() )
859 return crs.userFriendlyIdentifier();
860 else
861 return tr( "invalid projection" );
862}
863
864void QgsProjectionSelectionWidget::updateTooltip()
865{
867 if ( c.isValid() )
868 setToolTip( c.toWkt( Qgis::CrsWktVariant::Preferred, true ) );
869 else
870 setToolTip( QString() );
871 updateWarning();
872}
873
874QgsMapLayer *QgsProjectionSelectionWidget::mapLayerFromMimeData( const QMimeData *data ) const
875{
877 for ( const QgsMimeDataUtils::Uri &u : uriList )
878 {
879 // is this uri from the current project?
880 if ( QgsMapLayer *layer = u.mapLayer() )
881 {
882 return layer;
883 }
884 }
885 return nullptr;
886}
@ Vertical
Vertical CRS.
Definition qgis.h:2415
@ Temporal
Temporal CRS.
Definition qgis.h:2418
@ Compound
Compound (horizontal + vertical) CRS.
Definition qgis.h:2417
@ Projected
Projected CRS.
Definition qgis.h:2416
@ Other
Other type.
Definition qgis.h:2421
@ Bound
Bound CRS.
Definition qgis.h:2420
@ DerivedProjected
Derived projected CRS.
Definition qgis.h:2422
@ Unknown
Unknown type.
Definition qgis.h:2410
@ Engineering
Engineering CRS.
Definition qgis.h:2419
@ Geographic3d
3D geopraphic CRS
Definition qgis.h:2414
@ Geodetic
Geodetic CRS.
Definition qgis.h:2411
@ Geographic2d
2D geographic CRS
Definition qgis.h:2413
@ Geocentric
Geocentric CRS.
Definition qgis.h:2412
static QString geographicCrsAuthId()
Geographic coordinate system auth:id string for a default geographic CRS (EPSG:4326).
Definition qgis.h:6714
@ Preferred
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
Definition qgis.h:2527
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...
@ FilterVertical
Include vertical CRS (excludes compound CRS containing a vertical component).
@ FilterHorizontal
Include horizontal CRS (excludes compound CRS containing a horizontal component).
void userCrsChanged(const QString &id)
Emitted whenever an existing user CRS definition is changed.
Represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
QgsDatumEnsemble datumEnsemble() const
Attempts to retrieve datum ensemble details from the CRS.
Qgis::CrsType type() const
Returns the type of the CRS.
A generic widget allowing users to pick a Coordinate Reference System (or define their own).
void crsChanged()
Emitted when the CRS defined in the widget is changed.
QString code() const
Identification code, e.g.
Definition qgsdatums.h:126
QString authority() const
Authority name, e.g.
Definition qgsdatums.h:121
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:106
QList< QgsDatumEnsembleMember > members() const
Contains a list of members of the ensemble.
Definition qgsdatums.h:141
QString name() const
Display name of datum ensemble.
Definition qgsdatums.h:111
double accuracy() const
Positional accuracy (in meters).
Definition qgsdatums.h:116
A QComboBox subclass with the ability to "highlight" the edges of the widget.
Base class for all map layer types.
Definition qgsmaplayer.h:83
QList< QgsMimeDataUtils::Uri > UriList
static UriList decodeUriList(const QMimeData *data)
Base class for any widget that can be shown as an inline panel.
void openPanel(QgsPanelWidget *panel)
Open a panel or dialog depending on dock mode setting If dock mode is true this method will emit the ...
bool dockMode() const
Returns the dock mode state.
static QgsPanelWidget * findParentPanel(QWidget *widget)
Traces through the parents of a widget to find if it is contained within a QgsPanelWidget widget.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition qgsproject.h:113
static QgsProject * instance()
Returns the QgsProject singleton instance.
void crsChanged()
Emitted when the crs() of the project has changed.
QgsCoordinateReferenceSystem crs
Definition qgsproject.h:119
A generic dialog to prompt the user for a Coordinate Reference System.
void setShowNoProjection(bool show)
Sets whether a "no/invalid" projection option should be shown.
void setNotSetText(const QString &text, const QString &description=QString())
Sets the text to show for the not set option.
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets the initial crs to show within the dialog.
void setMessage(const QString &message)
Sets a message to show in the dialog.
QgsCoordinateReferenceSystem crs() const
Returns the CRS currently selected in the widget.
void setRequireValidSelection()
Sets the dialog to require a valid selection only, preventing users from accepting the dialog if no s...
void setOgcWmsCrsFilter(const QSet< QString > &crsFilter)
filters this dialog by the given CRSs
void setFilter(const QList< QgsCoordinateReferenceSystem > &crses)
Sets a filtered list of CRSes to show in the widget.
bool showAccuracyWarnings() const
Returns true if the widget will show a warning to users when they select a CRS which has low accuracy...
void cleared()
Emitted when the not set option is selected.
void selectCrs()
Opens the dialog for selecting a new CRS.
CrsOption
Predefined CRS options shown in widget.
@ CrsNotSet
Not set (hidden by default).
@ ProjectCrs
Current project CRS (if OTF reprojection enabled).
@ Invalid
Invalid option, since QGIS 3.36.
@ CurrentCrs
Current user selected CRS.
bool optionVisible(CrsOption option) const
Returns whether the specified CRS option is visible in the widget.
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets the current CRS for the widget.
void setNotSetText(const QString &text)
Sets the text to show for the not set option.
void setLayerCrs(const QgsCoordinateReferenceSystem &crs)
Sets the layer CRS for the widget.
void setOptionVisible(CrsOption option, bool visible)
Sets whether a predefined CRS option should be shown in the widget.
QString sourceEnsemble() const
Returns the original source ensemble datum name.
QgsCoordinateReferenceSystem crs() const
Returns the currently selected CRS for the widget.
QString dialogTitle() const
Returns the title for the CRS selector dialog window.
void setFilters(QgsCoordinateReferenceSystemProxyModel::Filters filters)
Sets filters for the available CRS.
void dragEnterEvent(QDragEnterEvent *event) override
void setMessage(const QString &text)
Sets a message to show in the dialog.
static QString crsOptionText(const QgsCoordinateReferenceSystem &crs)
Returns display text for the specified crs.
void dragLeaveEvent(QDragLeaveEvent *event) override
void setShowAccuracyWarnings(bool show)
Sets whether the widget will show warnings to users when they select a CRS which has low accuracy.
void setDialogTitle(const QString &title)
Sets the title for the CRS selector dialog window.
void crsChanged(const QgsCoordinateReferenceSystem &crs)
Emitted when the selected CRS is changed.
void setSourceEnsemble(const QString &ensemble)
Sets the original source ensemble datum name.
QgsCoordinateReferenceSystemProxyModel::Filters filters() const
Returns the filters set on the available CRS.
QgsProjectionSelectionWidget(QWidget *parent=nullptr, QgsCoordinateReferenceSystemProxyModel::Filters filters=QgsCoordinateReferenceSystemProxyModel::FilterHorizontal|QgsCoordinateReferenceSystemProxyModel::FilterCompound)
Constructor for QgsProjectionSelectionWidget, with the specified parent widget.
void dropEvent(QDropEvent *event) override
A sort/filter proxy model for recent coordinate reference systems.
Stores settings for use within QGIS.
Definition qgssettings.h:68
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
#define BUILTIN_UNREACHABLE
Definition qgis.h:7540
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition qgis.h:6880