29 , mDialogTitle( tr(
"Select CRS" ) )
34 mCrsComboBox->setSizePolicy( QSizePolicy::Ignored, QSizePolicy::Preferred );
36 const int labelMargin =
static_cast< int >( std::round( mCrsComboBox->fontMetrics().horizontalAdvance(
'X' ) ) );
37 QHBoxLayout *layout =
new QHBoxLayout();
38 layout->setContentsMargins( 0, 0, 0, 0 );
39 layout->setSpacing( 0 );
43 addProjectCrsOption();
51 addDefaultCrsOption();
56 layout->addWidget( mCrsComboBox, 1 );
61 mWarningLabelContainer =
new QWidget();
62 QHBoxLayout *warningLayout =
new QHBoxLayout();
63 warningLayout->setContentsMargins( 0, 0, 0, 0 );
64 mWarningLabel =
new QLabel();
66 const int size =
static_cast< int >( std::max( 24.0, mCrsComboBox->minimumSize().height() * 0.5 ) );
67 mWarningLabel->setPixmap( icon.pixmap( icon.actualSize( QSize( size, size ) ) ) );
68 warningLayout->insertSpacing( 0, labelMargin / 2 );
69 warningLayout->insertWidget( 1, mWarningLabel );
70 mWarningLabelContainer->setLayout( warningLayout );
71 layout->addWidget( mWarningLabelContainer );
72 mWarningLabelContainer->hide();
74 layout->addSpacing( labelMargin / 2 );
76 mButton =
new QToolButton(
this );
78 mButton->setToolTip( tr(
"Select CRS" ) );
79 layout->addWidget( mButton );
81 setFocusPolicy( Qt::StrongFocus );
82 setFocusProxy( mButton );
83 setAcceptDrops(
true );
86 connect( mCrsComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsProjectionSelectionWidget::comboIndexChanged );
99 switch (
static_cast< CrsOption >( mCrsComboBox->itemData( index ).toInt() ) )
111 const long srsid = mCrsComboBox->itemData( index, Qt::UserRole + 1 ).toLongLong();
123 return crsAtIndex( mCrsComboBox->currentIndex() );
128 const int optionIndex = mCrsComboBox->findData( option );
130 if ( visible && optionIndex < 0 )
142 addProjectCrsOption();
147 addDefaultCrsOption();
152 addCurrentCrsOption();
172 else if ( !visible && optionIndex >= 0 )
175 mCrsComboBox->removeItem( optionIndex );
187 const int optionIndex = mCrsComboBox->findData(
CrsNotSet );
188 if ( optionIndex >= 0 )
190 mCrsComboBox->setItemText( optionIndex, mNotSetText );
201 const int optionIndex = mCrsComboBox->findData( option );
202 return optionIndex >= 0;
209 QSet< QString > ogcFilter;
210 ogcFilter.reserve( mFilter.size( ) );
219 if ( !ogcFilter.isEmpty() )
220 mActivePanel->setOgcWmsCrsFilter( ogcFilter );
221 if ( !mMessage.isEmpty() )
222 mActivePanel->setMessage( mMessage );
223 mActivePanel->setCrs( mCrs );
225 if ( !mNotSetText.isEmpty() )
226 mActivePanel->setNotSetText( mNotSetText );
228 mActivePanel->setPanelTitle( mDialogTitle );
230 if (
optionVisible( QgsProjectionSelectionWidget::CrsOption::CrsNotSet ) )
232 mActivePanel->setShowNoCrs(
true );
237 if ( mIgnorePanelSignals )
240 if ( !mActivePanel->hasValidSelection() )
243 mCrsComboBox->blockSignals(
true );
245 mCrsComboBox->blockSignals(
false );
248 mIgnorePanelSignals++;
250 mIgnorePanelSignals--;
259 if ( !mMessage.isEmpty() )
261 if ( !ogcFilter.isEmpty() )
264 dlg.setWindowTitle( mDialogTitle );
266 if ( !mNotSetText.isEmpty() )
269 if (
optionVisible( QgsProjectionSelectionWidget::CrsOption::CrsNotSet ) )
277 mCrsComboBox->blockSignals(
true );
279 mCrsComboBox->blockSignals(
false );
286 QApplication::restoreOverrideCursor();
293 if ( !( event->possibleActions() & Qt::CopyAction ) )
299 if ( mapLayerFromMimeData( event->mimeData() ) )
302 event->setDropAction( Qt::CopyAction );
329 if ( !( event->possibleActions() & Qt::CopyAction ) )
335 if (
QgsMapLayer *layer = mapLayerFromMimeData( event->mimeData() ) )
338 setFocus( Qt::MouseFocusReason );
339 event->setDropAction( Qt::CopyAction );
342 if ( layer->crs().isValid() )
355 return mSourceEnsemble;
360 mDialogTitle = title;
373 for (
int i = mCrsComboBox->count() - 1; i >= 0; --i )
375 if ( !mFilter.contains( crsAtIndex( i ) ) )
376 mCrsComboBox->removeItem( i );
382 if ( mSourceEnsemble == ensemble )
385 mSourceEnsemble = ensemble;
391 return mShowAccuracyWarnings;
396 mShowAccuracyWarnings = show;
397 if ( !mShowAccuracyWarnings )
398 mWarningLabelContainer->hide();
403void QgsProjectionSelectionWidget::addNotSetOption()
410void QgsProjectionSelectionWidget::comboIndexChanged(
int idx )
412 switch (
static_cast< CrsOption >( mCrsComboBox->itemData( idx ).toInt() ) )
428 const long srsid = mCrsComboBox->itemData( idx, Qt::UserRole + 1 ).toLongLong();
441void QgsProjectionSelectionWidget::updateWarning()
443 if ( !mShowAccuracyWarnings )
445 if ( mWarningLabelContainer->isVisible() )
446 mWarningLabelContainer->hide();
452 const double crsAccuracyWarningThreshold =
QgsSettings().
value( QStringLiteral(
"/projections/crsAccuracyWarningThreshold" ), 0.0,
QgsSettings::App ).toDouble();
455 if ( !ensemble.
isValid() || ensemble.
name() == mSourceEnsemble || ( ensemble.
accuracy() > 0 && ensemble.
accuracy() < crsAccuracyWarningThreshold ) )
457 mWarningLabelContainer->hide();
461 mWarningLabelContainer->show();
463 QString warning = QStringLiteral(
"<p>" );
466 if ( !ensemble.
code().isEmpty() )
467 id = QStringLiteral(
"<i>%1</i> (%2:%3)" ).arg( ensemble.
name(), ensemble.
authority(), ensemble.
code() );
469 id = QStringLiteral(
"<i>%</i>”" ).arg( ensemble.
name() );
473 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() );
477 warning = tr(
"The selected CRS is based on %1, which has a limited accuracy." ).arg(
id );
479 warning += QStringLiteral(
"</p><p>" ) + tr(
"Use an alternative CRS if accurate positioning is required." ) + QStringLiteral(
"</p>" );
481 const QList< QgsDatumEnsembleMember > members = ensemble.
members();
482 if ( !members.isEmpty() )
484 warning += QStringLiteral(
"<p>" ) + tr(
"%1 consists of the datums:" ).arg( ensemble.
name() ) + QStringLiteral(
"</p><ul>" );
488 if ( !member.code().isEmpty() )
489 id = QStringLiteral(
"%1 (%2:%3)" ).arg( member.name(), member.authority(), member.code() );
492 warning += QStringLiteral(
"<li>%1</li>" ).arg(
id );
495 warning += QLatin1String(
"</ul>" );
498 mWarningLabel->setToolTip( warning );
503 mWarningLabelContainer->hide();
515 mCrsComboBox->blockSignals(
true );
517 mCrsComboBox->blockSignals(
false );
522 if ( crsNotSetIndex >= 0 )
524 mCrsComboBox->blockSignals(
true );
525 mCrsComboBox->setCurrentIndex( crsNotSetIndex );
526 mCrsComboBox->blockSignals(
false );
534 if ( mActivePanel && !mIgnorePanelSignals )
536 mIgnorePanelSignals++;
537 mActivePanel->setCrs(
crs );
538 mIgnorePanelSignals--;
553 if ( layerItemIndex > -1 )
564 if ( layerItemIndex > -1 )
566 mCrsComboBox->removeItem( layerItemIndex );
572void QgsProjectionSelectionWidget::addProjectCrsOption()
580void QgsProjectionSelectionWidget::addDefaultCrsOption()
585void QgsProjectionSelectionWidget::addCurrentCrsOption()
597 return tr(
"invalid projection" );
600void QgsProjectionSelectionWidget::addRecentCrs()
608 if ( crsIsShown( srsid ) )
613 if (
crs.
isValid() && ( mFilter.isEmpty() || mFilter.contains(
crs ) ) )
616 mCrsComboBox->setItemData( mCrsComboBox->count() - 1, QVariant( (
long long )srsid ), Qt::UserRole + 1 );
621bool QgsProjectionSelectionWidget::crsIsShown(
const long srsid )
const
623 return srsid == mLayerCrs.
srsid() || srsid == mDefaultCrs.
srsid() || srsid == mProjectCrs.
srsid();
626int QgsProjectionSelectionWidget::firstRecentCrsIndex()
const
628 for (
int i = 0; i < mCrsComboBox->count(); ++i )
638void QgsProjectionSelectionWidget::updateTooltip()
644 setToolTip( QString() );
648QgsMapLayer *QgsProjectionSelectionWidget::mapLayerFromMimeData(
const QMimeData *data )
const
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...
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.
QgsDatumEnsemble datumEnsemble() const SIP_THROW(QgsNotSupportedException)
Attempts to retrieve datum ensemble details from the CRS.
void updateDefinition()
Updates the definition and parameters of the coordinate reference system to their latest values.
static QList< QgsCoordinateReferenceSystem > recentCoordinateReferenceSystems()
Returns a list of recently used CRS.
QString userFriendlyIdentifier(IdentifierType type=MediumString) const
Returns a user friendly identifier for the CRS.
@ WKT_PREFERRED
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
static QgsCoordinateReferenceSystem fromSrsId(long srsId)
Creates a CRS from a specified QGIS SRS ID.
long srsid() const
Returns the internal CRS ID, if available.
Contains information about a member of a datum ensemble.
Contains information about a datum ensemble.
QString code() const
Identification code, e.g.
QString authority() const
Authority name, e.g.
bool isValid() const
Returns true if the datum ensemble is a valid object, or false if it is a null/invalid object.
QList< QgsDatumEnsembleMember > members() const
Contains a list of members of the ensemble.
QString name() const
Display name of datum ensemble.
double accuracy() const
Positional accuracy (in meters).
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.
QList< QgsMimeDataUtils::Uri > UriList
static UriList decodeUriList(const QMimeData *data)
Custom exception class which is raised when an operation is not supported.
static QgsProject * instance()
Returns the QgsProject singleton instance.
QgsCoordinateReferenceSystem crs
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
This class is a composition of two QSettings instances:
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
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
CONSTLATIN1STRING geoEpsgCrsAuthId()
Geographic coord sys from EPSG authority.
const QgsCoordinateReferenceSystem & crs