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