QGIS API Documentation 3.39.0-Master (3aed037ce22)
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
16#include <QHBoxLayout>
17
19#include "qgsapplication.h"
21#include "qgsproject.h"
22#include "qgssettings.h"
26#include "qgsdatums.h"
27
28#ifdef ENABLE_MODELTEST
29#include "modeltest.h"
30#endif
31
32
34StandardCoordinateReferenceSystemsModel::StandardCoordinateReferenceSystemsModel( QObject *parent )
35 : QAbstractItemModel( parent )
36 , mProjectCrs( QgsProject::instance()->crs() )
37{
38#ifdef ENABLE_MODELTEST
39 new ModelTest( this, this );
40#endif
41
42 const QgsSettings settings;
43 mDefaultCrs = QgsCoordinateReferenceSystem( settings.value( QStringLiteral( "/projections/defaultProjectCrs" ), geoEpsgCrsAuthId(), QgsSettings::App ).toString() );
44
46 {
47 mCurrentCrs.updateDefinition();
48 mLayerCrs.updateDefinition();
49 mProjectCrs.updateDefinition();
50 mDefaultCrs.updateDefinition();
51 } );
52}
53
54Qt::ItemFlags StandardCoordinateReferenceSystemsModel::flags( const QModelIndex &index ) const
55{
56 if ( !index.isValid() )
57 {
58 return Qt::ItemFlags();
59 }
60
61 return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
62}
63
64QVariant StandardCoordinateReferenceSystemsModel::data( const QModelIndex &index, int role ) const
65{
66 const QgsProjectionSelectionWidget::CrsOption option = optionForIndex( index );
68 return QVariant();
69
70 const QgsCoordinateReferenceSystem crs = StandardCoordinateReferenceSystemsModel::crs( index );
71 switch ( role )
72 {
73 case Qt::DisplayRole:
74 case Qt::ToolTipRole:
75 switch ( option )
76 {
78 return tr( "Project CRS: %1" ).arg( crs.userFriendlyIdentifier() );
80 return tr( "Default CRS: %1" ).arg( crs.userFriendlyIdentifier() );
82 return tr( "Layer CRS: %1" ).arg( crs.userFriendlyIdentifier() );
84 return mNotSetText;
89 break;
90 }
91 break;
92
93 case RoleCrs:
94 return crs;
95
96 case RoleOption:
97 return static_cast< int >( option );
98
99 default:
100 break;
101 }
102
103 return QVariant();
104}
105
106int StandardCoordinateReferenceSystemsModel::rowCount( const QModelIndex &parent ) const
107{
108 if ( parent.isValid() )
109 return 0;
110
111 return 5;
112}
113
114int StandardCoordinateReferenceSystemsModel::columnCount( const QModelIndex & ) const
115{
116 return 1;
117}
118
119QModelIndex StandardCoordinateReferenceSystemsModel::index( int row, int column, const QModelIndex &parent ) const
120{
121 if ( row < 0 || row >= rowCount() || column != 0 || parent.isValid() )
122 return QModelIndex();
123
124 return createIndex( row, column );
125}
126
127QModelIndex StandardCoordinateReferenceSystemsModel::parent( const QModelIndex & ) const
128{
129 return QModelIndex();
130}
131
132QgsCoordinateReferenceSystem StandardCoordinateReferenceSystemsModel::crs( const QModelIndex &index ) const
133{
134 if ( !index.isValid() )
136
137 const QgsProjectionSelectionWidget::CrsOption option = optionForIndex( index );
138 switch ( option )
139 {
141 return mProjectCrs;
143 return mDefaultCrs;
145 return mCurrentCrs;
147 return mLayerCrs;
152 }
154}
155
156QgsProjectionSelectionWidget::CrsOption StandardCoordinateReferenceSystemsModel::optionForIndex( const QModelIndex &index ) const
157{
158 if ( !index.isValid() )
160
161 const int row = index.row();
162 switch ( row )
163 {
164 case 0:
166 case 1:
168 case 2:
170 case 3:
172 case 4:
174 default:
175 break;
176 }
177
179}
180
181QModelIndex StandardCoordinateReferenceSystemsModel::indexForOption( QgsProjectionSelectionWidget::CrsOption option ) const
182{
183 int row = 0;
184 switch ( option )
185 {
188 return QModelIndex();
190 row = 0;
191 break;
193 row = 1;
194 break;
196 row = 2;
197 break;
199 row = 3;
200 break;
202 row = 4;
203 break;
204 }
205
206 return index( row, 0, QModelIndex() );
207}
208
209void StandardCoordinateReferenceSystemsModel::setLayerCrs( const QgsCoordinateReferenceSystem &crs )
210{
211 mLayerCrs = crs;
212 const QModelIndex index = indexForOption( QgsProjectionSelectionWidget::LayerCrs );
213 emit dataChanged( index, index );
214}
215
216void StandardCoordinateReferenceSystemsModel::setCurrentCrs( const QgsCoordinateReferenceSystem &crs )
217{
218 mCurrentCrs = crs;
219 const QModelIndex index = indexForOption( QgsProjectionSelectionWidget::LayerCrs );
220 emit dataChanged( index, index );
221}
222
223void StandardCoordinateReferenceSystemsModel::setNotSetText( const QString &text )
224{
225 mNotSetText = text;
226 const QModelIndex index = indexForOption( QgsProjectionSelectionWidget::CrsNotSet );
227 emit dataChanged( index, index );
228}
229
230//
231// CombinedCoordinateReferenceSystemsModel
232//
233
234CombinedCoordinateReferenceSystemsModel::CombinedCoordinateReferenceSystemsModel( QObject *parent )
235 : QConcatenateTablesProxyModel( parent )
236 , mStandardModel( new StandardCoordinateReferenceSystemsModel( this ) )
237 , mRecentModel( new QgsRecentCoordinateReferenceSystemsProxyModel( this ) )
238{
239 addSourceModel( mStandardModel );
240 addSourceModel( mRecentModel );
241}
242
243void CombinedCoordinateReferenceSystemsModel::setNotSetText( const QString &text )
244{
245 mStandardModel->setNotSetText( text );
246}
247
248QString CombinedCoordinateReferenceSystemsModel::notSetText() const
249{
250 return mStandardModel->notSetText();
251}
252
253QgsCoordinateReferenceSystem CombinedCoordinateReferenceSystemsModel::currentCrs() const
254{
255 return mStandardModel->currentCrs();
256}
257
258//
259// CombinedCoordinateReferenceSystemsProxyModel
260//
261CombinedCoordinateReferenceSystemsProxyModel::CombinedCoordinateReferenceSystemsProxyModel( QObject *parent )
262 : QSortFilterProxyModel( parent )
263 , mModel( new CombinedCoordinateReferenceSystemsModel( this ) )
264{
265 mVisibleOptions.setFlag( QgsProjectionSelectionWidget::CurrentCrs, true );
266 mVisibleOptions.setFlag( QgsProjectionSelectionWidget::ProjectCrs, true );
267 mVisibleOptions.setFlag( QgsProjectionSelectionWidget::DefaultCrs, true );
268
269 setSourceModel( mModel );
270 setDynamicSortFilter( true );
271}
272
273bool CombinedCoordinateReferenceSystemsProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent ) const
274{
275 const QModelIndex sourceIndex = mModel->index( sourceRow, 0, sourceParent );
276
277 const QgsCoordinateReferenceSystem crs = mModel->data( sourceIndex, StandardCoordinateReferenceSystemsModel::RoleCrs ).value< QgsCoordinateReferenceSystem >();
278 if ( !mFilteredCrs.isEmpty() && !mFilteredCrs.contains( crs ) )
279 return false;
280
281 switch ( crs.type() )
282 {
285 break;
286
297 return false;
298 break;
299
302 return false;
303 break;
304
307 return false;
308 break;
309 }
310
311 const QVariant optionInt = mModel->data( sourceIndex, StandardCoordinateReferenceSystemsModel::RoleOption );
312 if ( optionInt.isValid() )
313 {
314 if ( optionInt.toInt() > 0 )
315 {
316 const QgsProjectionSelectionWidget::CrsOption option = static_cast< QgsProjectionSelectionWidget::CrsOption >( optionInt.toInt() );
317 if ( !mVisibleOptions.testFlag( option ) )
318 return false;
319
320 // specific logic for showing/hiding options:
321 switch ( option )
322 {
324 break;
325
328 // only show these options if the crs is valid
329 return crs.isValid();
330
332 // hide invalid current CRS value option only if "not set" option is shown
333 return crs.isValid() || !mVisibleOptions.testFlag( QgsProjectionSelectionWidget::CrsNotSet );
334
338 // always shown
339 break;
340 }
341 return true;
342 }
343 }
344 else
345 {
346 // a recent crs
347 // these are only shown if they aren't duplicates of a standard item already shown in the list
348 for ( QgsProjectionSelectionWidget::CrsOption standardOption :
349 {
354 } )
355 {
356 const QModelIndexList standardItemIndex = mModel->match( mModel->index( 0, 0 ), StandardCoordinateReferenceSystemsModel::RoleOption, static_cast< int >( standardOption ) );
357 if ( standardItemIndex.empty() )
358 continue;
359
360 const QgsCoordinateReferenceSystem standardItemCrs = mModel->data( standardItemIndex.at( 0 ), StandardCoordinateReferenceSystemsModel::RoleCrs ).value< QgsCoordinateReferenceSystem >();
361 if ( standardItemCrs == crs && filterAcceptsRow( standardItemIndex.at( 0 ).row(), QModelIndex() ) )
362 return false;
363 }
364 }
365
366 return true;
367}
368
369void CombinedCoordinateReferenceSystemsProxyModel::setLayerCrs( const QgsCoordinateReferenceSystem &crs )
370{
371 mModel->standardModel()->setLayerCrs( crs );
372 invalidateFilter();
373}
374
375void CombinedCoordinateReferenceSystemsProxyModel::setCurrentCrs( const QgsCoordinateReferenceSystem &crs )
376{
377 mModel->standardModel()->setCurrentCrs( crs );
378 invalidateFilter();
379}
380
381void CombinedCoordinateReferenceSystemsProxyModel::setFilters( QgsCoordinateReferenceSystemProxyModel::Filters filters )
382{
383 mFilters = filters;
384 invalidateFilter();
385}
386
387QgsCoordinateReferenceSystemProxyModel::Filters CombinedCoordinateReferenceSystemsProxyModel::filters() const
388{
389 return mFilters;
390}
391
392void CombinedCoordinateReferenceSystemsProxyModel::setFilteredCrs( const QList<QgsCoordinateReferenceSystem> &crses )
393{
394 mFilteredCrs = crses;
395 invalidateFilter();
396}
397
398void CombinedCoordinateReferenceSystemsProxyModel::setOption( QgsProjectionSelectionWidget::CrsOption option, bool enabled )
399{
400 mVisibleOptions.setFlag( option, enabled );
401 invalidateFilter();
402}
403
405
406
409 : QWidget( parent )
410 , mDialogTitle( tr( "Coordinate Reference System Selector" ) )
411{
412 mCrsComboBox = new QgsHighlightableComboBox( this );
413 mCrsComboBox->setSizePolicy( QSizePolicy::Ignored, QSizePolicy::Preferred );
414
415 mModel = new CombinedCoordinateReferenceSystemsProxyModel( this );
416 mModel->setFilters( filters );
417 mCrsComboBox->setModel( mModel );
418
419 const int labelMargin = static_cast< int >( std::round( mCrsComboBox->fontMetrics().horizontalAdvance( 'X' ) ) );
420 QHBoxLayout *layout = new QHBoxLayout();
421 layout->setContentsMargins( 0, 0, 0, 0 );
422 layout->setSpacing( 0 );
423 setLayout( layout );
424
425 layout->addWidget( mCrsComboBox, 1 );
426
427 // bit of fiddlyness here -- we want the initial spacing to only be visible
428 // when the warning label is shown, so it's embedded inside mWarningLabel
429 // instead of outside it
430 mWarningLabelContainer = new QWidget();
431 QHBoxLayout *warningLayout = new QHBoxLayout();
432 warningLayout->setContentsMargins( 0, 0, 0, 0 );
433 mWarningLabel = new QLabel();
434 const QIcon icon = QgsApplication::getThemeIcon( QStringLiteral( "mIconWarning.svg" ) );
435 const int size = static_cast< int >( std::max( 24.0, mCrsComboBox->minimumSize().height() * 0.5 ) );
436 mWarningLabel->setPixmap( icon.pixmap( icon.actualSize( QSize( size, size ) ) ) );
437 warningLayout->insertSpacing( 0, labelMargin / 2 );
438 warningLayout->insertWidget( 1, mWarningLabel );
439 mWarningLabelContainer->setLayout( warningLayout );
440 layout->addWidget( mWarningLabelContainer );
441 mWarningLabelContainer->hide();
442
443 layout->addSpacing( labelMargin / 2 );
444
445 mButton = new QToolButton( this );
446 mButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "mActionSetProjection.svg" ) ) );
447 mButton->setToolTip( tr( "Select CRS" ) );
448 layout->addWidget( mButton );
449
450 setFocusPolicy( Qt::StrongFocus );
451 setFocusProxy( mButton );
452 setAcceptDrops( true );
453
454 connect( mButton, &QToolButton::clicked, this, &QgsProjectionSelectionWidget::selectCrs );
455 connect( mCrsComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsProjectionSelectionWidget::comboIndexChanged );
456}
457
459{
460 const int idx = mCrsComboBox->currentIndex();
461 if ( idx >= 0 && idx < mModel->rowCount() )
462 return mModel->data( mModel->index( idx, 0 ), StandardCoordinateReferenceSystemsModel::RoleCrs ).value< QgsCoordinateReferenceSystem >();
463 else
465}
466
468{
469 switch ( option )
470 {
475 {
476 mModel->setOption( option, visible );
477 updateTooltip();
478 return;
479 }
481 //recently used CRS option cannot be readded
482 return;
484 {
485 mModel->setOption( CrsNotSet, visible );
486
487 if ( !visible )
488 {
490 }
491 else
492 {
493 if ( !mModel->combinedModel()->currentCrs().isValid() )
494 whileBlocking( mCrsComboBox )->setCurrentIndex( 0 );
495 }
496 updateTooltip();
497
498 return;
499 }
500 case Invalid:
501 return;
502 }
503}
504
506{
507 mModel->combinedModel()->setNotSetText( text );
508}
509
511{
512 mMessage = text;
513}
514
516{
517 const QModelIndexList matches = mModel->match( mModel->index( 0, 0 ), StandardCoordinateReferenceSystemsModel::Role::RoleOption, static_cast< int >( option ) );
518 return !matches.empty();
519}
520
522{
524 const QList< QgsCoordinateReferenceSystem > filteredCrses = mModel->filteredCrs();
525
526 QSet< QString > ogcFilter;
527 ogcFilter.reserve( filteredCrses.size( ) );
528 for ( const QgsCoordinateReferenceSystem &crs : std::as_const( filteredCrses ) )
529 {
530 ogcFilter << crs.authid();
531 }
532
533 if ( panel && panel->dockMode() )
534 {
535 mActivePanel = new QgsCrsSelectionWidget( this, mModel->filters() );
536 if ( !ogcFilter.isEmpty() )
537 mActivePanel->setOgcWmsCrsFilter( ogcFilter );
538 if ( !mMessage.isEmpty() )
539 mActivePanel->setMessage( mMessage );
540 mActivePanel->setCrs( crs() );
541
542 if ( !mModel->combinedModel()->notSetText().isEmpty() )
543 mActivePanel->setNotSetText( mModel->combinedModel()->notSetText() );
544
545 mActivePanel->setPanelTitle( mDialogTitle );
546
548 {
549 mActivePanel->setShowNoCrs( true );
550 }
551
552 connect( mActivePanel, &QgsCrsSelectionWidget::crsChanged, this, [ this ]
553 {
554 if ( mIgnorePanelSignals )
555 return;
556
557 if ( !mActivePanel->hasValidSelection() )
558 return;
559
560 mCrsComboBox->blockSignals( true );
561 mCrsComboBox->setCurrentIndex( mCrsComboBox->findData( QgsProjectionSelectionWidget::CurrentCrs, StandardCoordinateReferenceSystemsModel::Role::RoleOption ) );
562 mCrsComboBox->blockSignals( false );
563 const QgsCoordinateReferenceSystem crs = mActivePanel->crs();
564
565 mIgnorePanelSignals++;
566 setCrs( crs );
567 mIgnorePanelSignals--;
568
569 emit crsChanged( crs );
570 } );
571 panel->openPanel( mActivePanel );
572 }
573 else
574 {
575 QgsProjectionSelectionDialog dlg( this, QgsGuiUtils::ModalDialogFlags, mModel->filters() );
576 if ( !mMessage.isEmpty() )
577 dlg.setMessage( mMessage );
578 if ( !ogcFilter.isEmpty() )
579 dlg.setOgcWmsCrsFilter( ogcFilter );
580 dlg.setCrs( crs() );
581 dlg.setWindowTitle( mDialogTitle );
582
583 if ( !mModel->combinedModel()->notSetText().isEmpty() )
584 dlg.setNotSetText( mModel->combinedModel()->notSetText() );
585
587 {
588 dlg.setShowNoProjection( true );
589 }
591
592 if ( dlg.exec() )
593 {
594 mCrsComboBox->blockSignals( true );
595 mCrsComboBox->setCurrentIndex( mCrsComboBox->findData( QgsProjectionSelectionWidget::CurrentCrs, StandardCoordinateReferenceSystemsModel::Role::RoleOption ) );
596 mCrsComboBox->blockSignals( false );
598 // setCrs will emit crsChanged for us
599 setCrs( crs );
600 }
601 else
602 {
603 QApplication::restoreOverrideCursor();
604 }
605 }
606}
607
609{
610 if ( !( event->possibleActions() & Qt::CopyAction ) )
611 {
612 event->ignore();
613 return;
614 }
615
616 if ( mapLayerFromMimeData( event->mimeData() ) )
617 {
618 // dragged an acceptable layer, phew
619 event->setDropAction( Qt::CopyAction );
620 event->accept();
621 mCrsComboBox->setHighlighted( true );
622 update();
623 }
624 else
625 {
626 event->ignore();
627 }
628}
629
631{
632 if ( mCrsComboBox->isHighlighted() )
633 {
634 event->accept();
635 mCrsComboBox->setHighlighted( false );
636 update();
637 }
638 else
639 {
640 event->ignore();
641 }
642}
643
645{
646 if ( !( event->possibleActions() & Qt::CopyAction ) )
647 {
648 event->ignore();
649 return;
650 }
651
652 if ( QgsMapLayer *layer = mapLayerFromMimeData( event->mimeData() ) )
653 {
654 // dropped a map layer
655 setFocus( Qt::MouseFocusReason );
656 event->setDropAction( Qt::CopyAction );
657 event->accept();
658
659 if ( layer->crs().isValid() )
660 setCrs( layer->crs() );
661 }
662 else
663 {
664 event->ignore();
665 }
666 mCrsComboBox->setHighlighted( false );
667 update();
668}
669
671{
672 return mSourceEnsemble;
673}
674
676{
677 mDialogTitle = title;
678}
679
681{
682 return mDialogTitle;
683}
684
685void QgsProjectionSelectionWidget::setFilter( const QList<QgsCoordinateReferenceSystem> &crses )
686{
687 mModel->setFilteredCrs( crses );
688}
689
694
696{
697 mModel->setFilters( filters );
698 if ( mActivePanel )
699 mActivePanel->setFilters( filters );
700}
701
703{
704 if ( mSourceEnsemble == ensemble )
705 return;
706
707 mSourceEnsemble = ensemble;
708 updateWarning();
709}
710
712{
713 return mShowAccuracyWarnings;
714}
715
717{
718 mShowAccuracyWarnings = show;
719 if ( !mShowAccuracyWarnings )
720 mWarningLabelContainer->hide();
721 else
722 updateWarning();
723}
724
725void QgsProjectionSelectionWidget::comboIndexChanged( int idx )
726{
727 if ( idx >= 0 && idx < mModel->rowCount() )
728 {
729 const QgsCoordinateReferenceSystem crs = mModel->data( mModel->index( idx, 0 ), StandardCoordinateReferenceSystemsModel::RoleCrs ).value< QgsCoordinateReferenceSystem >();
730 const QVariant optionData = mModel->data( mModel->index( idx, 0 ), StandardCoordinateReferenceSystemsModel::RoleOption );
731 if ( !optionData.isValid() || static_cast< CrsOption >( optionData.toInt() ) != QgsProjectionSelectionWidget::CrsNotSet )
732 {
733 // RoleOption is only available for items from the standard coordinate reference system model, but we
734 // are using a combined model which also has items from QgsRecentCoordinateReferenceSystemsModel
735 emit crsChanged( crs );
736 }
737 else
738 {
739 emit cleared();
741 }
742 }
743
744 updateTooltip();
745}
746
747void QgsProjectionSelectionWidget::updateWarning()
748{
749 if ( !mShowAccuracyWarnings )
750 {
751 if ( mWarningLabelContainer->isVisible() )
752 mWarningLabelContainer->hide();
753 return;
754 }
755
756 try
757 {
758 const double crsAccuracyWarningThreshold = QgsSettings().value( QStringLiteral( "/projections/crsAccuracyWarningThreshold" ), 0.0, QgsSettings::App ).toDouble();
759
760 const QgsDatumEnsemble ensemble = crs().datumEnsemble();
761 if ( !ensemble.isValid() || ensemble.name() == mSourceEnsemble || ( ensemble.accuracy() > 0 && ensemble.accuracy() < crsAccuracyWarningThreshold ) )
762 {
763 mWarningLabelContainer->hide();
764 }
765 else
766 {
767 mWarningLabelContainer->show();
768
769 QString warning = QStringLiteral( "<p>" );
770
771 QString id;
772 if ( !ensemble.code().isEmpty() )
773 id = QStringLiteral( "<i>%1</i> (%2:%3)" ).arg( ensemble.name(), ensemble.authority(), ensemble.code() );
774 else
775 id = QStringLiteral( "<i>%</i>”" ).arg( ensemble.name() );
776
777 if ( ensemble.accuracy() > 0 )
778 {
779 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() );
780 }
781 else
782 {
783 warning = tr( "The selected CRS is based on %1, which has a limited accuracy." ).arg( id );
784 }
785 warning += QStringLiteral( "</p><p>" ) + tr( "Use an alternative CRS if accurate positioning is required." ) + QStringLiteral( "</p>" );
786
787 const QList< QgsDatumEnsembleMember > members = ensemble.members();
788 if ( !members.isEmpty() )
789 {
790 warning += QStringLiteral( "<p>" ) + tr( "%1 consists of the datums:" ).arg( ensemble.name() ) + QStringLiteral( "</p><ul>" );
791
792 for ( const QgsDatumEnsembleMember &member : members )
793 {
794 if ( !member.code().isEmpty() )
795 id = QStringLiteral( "%1 (%2:%3)" ).arg( member.name(), member.authority(), member.code() );
796 else
797 id = member.name();
798 warning += QStringLiteral( "<li>%1</li>" ).arg( id );
799 }
800
801 warning += QLatin1String( "</ul>" );
802 }
803
804 mWarningLabel->setToolTip( warning );
805 }
806 }
807 catch ( QgsNotSupportedException & )
808 {
809 mWarningLabelContainer->hide();
810 }
811}
812
814{
815 const QgsCoordinateReferenceSystem prevCrs = mModel->combinedModel()->currentCrs();
816 mModel->setCurrentCrs( crs );
817
818 if ( crs.isValid() )
819 {
821 mCrsComboBox->blockSignals( true );
822 mCrsComboBox->setCurrentIndex( mCrsComboBox->findData( QgsProjectionSelectionWidget::CurrentCrs, StandardCoordinateReferenceSystemsModel::Role::RoleOption ) );
823 mCrsComboBox->blockSignals( false );
824 }
825 else
826 {
827 const int crsNotSetIndex = mCrsComboBox->findData( QgsProjectionSelectionWidget::CrsNotSet, StandardCoordinateReferenceSystemsModel::Role::RoleOption );
828 if ( crsNotSetIndex >= 0 )
829 {
830 mCrsComboBox->blockSignals( true );
831 mCrsComboBox->setCurrentIndex( crsNotSetIndex );
832 mCrsComboBox->blockSignals( false );
833 }
834 }
835 if ( mActivePanel && !mIgnorePanelSignals )
836 {
837 mIgnorePanelSignals++;
838 mActivePanel->setCrs( crs );
839 mIgnorePanelSignals--;
840 }
841 if ( prevCrs != crs )
842 {
843 emit crsChanged( crs );
844 }
845 updateTooltip();
846}
847
849{
850 mModel->setLayerCrs( crs );
851}
852
854{
855 if ( crs.isValid() )
857 else
858 return tr( "invalid projection" );
859}
860
861void QgsProjectionSelectionWidget::updateTooltip()
862{
864 if ( c.isValid() )
865 setToolTip( c.toWkt( Qgis::CrsWktVariant::Preferred, true ) );
866 else
867 setToolTip( QString() );
868 updateWarning();
869}
870
871QgsMapLayer *QgsProjectionSelectionWidget::mapLayerFromMimeData( const QMimeData *data ) const
872{
874 for ( const QgsMimeDataUtils::Uri &u : uriList )
875 {
876 // is this uri from the current project?
877 if ( QgsMapLayer *layer = u.mapLayer() )
878 {
879 return layer;
880 }
881 }
882 return nullptr;
883}
@ Vertical
Vertical CRS.
@ Temporal
Temporal CRS.
@ Compound
Compound (horizontal + vertical) CRS.
@ Projected
Projected CRS.
@ Other
Other type.
@ Bound
Bound CRS.
@ DerivedProjected
Derived projected CRS.
@ Unknown
Unknown type.
@ Engineering
Engineering CRS.
@ Geographic3d
3D geopraphic CRS
@ Geodetic
Geodetic CRS.
@ Geographic2d
2D geographic CRS
@ Geocentric
Geocentric CRS.
@ Preferred
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
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.
This class represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
QString userFriendlyIdentifier(Qgis::CrsIdentifierType type=Qgis::CrsIdentifierType::MediumString) const
Returns a user friendly identifier for the CRS.
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.
Contains information about a member of a datum ensemble.
Definition qgsdatums.h:35
Contains information about a datum ensemble.
Definition qgsdatums.h:95
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
QList< QgsDatumEnsembleMember > members() const
Contains a list of members of the ensemble.
Definition qgsdatums.h:137
QString name() const
Display name of datum ensemble.
Definition qgsdatums.h:107
double accuracy() const
Positional accuracy (in meters).
Definition qgsdatums.h:112
A QComboBox subclass with the ability to "highlight" the edges of the widget.
void setHighlighted(bool highlighted)
Sets whether the combo box is currently highlighted.
bool isHighlighted() const
Returns true if the combo box is currently highlighted.
Base class for all map layer types.
Definition qgsmaplayer.h:75
QList< QgsMimeDataUtils::Uri > UriList
static UriList decodeUriList(const QMimeData *data)
Custom exception class which is raised when an operation is not supported.
Base class for any widget that can be shown as a 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 ...
static QgsPanelWidget * findParentPanel(QWidget *widget)
Traces through the parents of a widget to find if it is contained within a QgsPanelWidget widget.
bool dockMode()
Returns the dock mode state.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition qgsproject.h:107
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.
void crsChanged(const QgsCoordinateReferenceSystem &)
Emitted when the selected CRS is changed.
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 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.
This class is a composition of two QSettings instances:
Definition qgssettings.h:64
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:6306
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition qgis.h:5556
CONSTLATIN1STRING geoEpsgCrsAuthId()
Geographic coord sys from EPSG authority.
Definition qgis.h:6141
const QgsCoordinateReferenceSystem & crs