16 #include <QHBoxLayout>
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->currentData().toInt() ) )
111 const long srsid = mCrsComboBox->currentData( Qt::UserRole + 1 ).toLongLong();
123 const int optionIndex = mCrsComboBox->findData( option );
125 if ( visible && optionIndex < 0 )
137 addProjectCrsOption();
142 addDefaultCrsOption();
147 addCurrentCrsOption();
167 else if ( !visible && optionIndex >= 0 )
170 mCrsComboBox->removeItem( optionIndex );
182 const int optionIndex = mCrsComboBox->findData(
CrsNotSet );
183 if ( optionIndex >= 0 )
185 mCrsComboBox->setItemText( optionIndex, mNotSetText );
196 const int optionIndex = mCrsComboBox->findData( option );
197 return optionIndex >= 0;
206 if ( !mMessage.isEmpty() )
207 mActivePanel->setMessage( mMessage );
208 mActivePanel->setCrs( mCrs );
210 if ( !mNotSetText.isEmpty() )
211 mActivePanel->setNotSetText( mNotSetText );
213 mActivePanel->setPanelTitle( mDialogTitle );
215 if (
optionVisible( QgsProjectionSelectionWidget::CrsOption::CrsNotSet ) )
217 mActivePanel->setShowNoCrs(
true );
222 if ( mIgnorePanelSignals )
225 if ( !mActivePanel->hasValidSelection() )
228 mCrsComboBox->blockSignals(
true );
230 mCrsComboBox->blockSignals(
false );
233 mIgnorePanelSignals++;
235 mIgnorePanelSignals--;
244 if ( !mMessage.isEmpty() )
247 dlg.setWindowTitle( mDialogTitle );
249 if ( !mNotSetText.isEmpty() )
252 if (
optionVisible( QgsProjectionSelectionWidget::CrsOption::CrsNotSet ) )
260 mCrsComboBox->blockSignals(
true );
262 mCrsComboBox->blockSignals(
false );
269 QApplication::restoreOverrideCursor();
276 if ( !( event->possibleActions() & Qt::CopyAction ) )
282 if ( mapLayerFromMimeData( event->mimeData() ) )
285 event->setDropAction( Qt::CopyAction );
312 if ( !( event->possibleActions() & Qt::CopyAction ) )
318 if (
QgsMapLayer *layer = mapLayerFromMimeData( event->mimeData() ) )
321 setFocus( Qt::MouseFocusReason );
322 event->setDropAction( Qt::CopyAction );
325 if ( layer->crs().isValid() )
338 return mSourceEnsemble;
343 mDialogTitle = title;
353 if ( mSourceEnsemble == ensemble )
356 mSourceEnsemble = ensemble;
362 return mShowAccuracyWarnings;
367 mShowAccuracyWarnings = show;
368 if ( !mShowAccuracyWarnings )
369 mWarningLabelContainer->hide();
374 void QgsProjectionSelectionWidget::addNotSetOption()
381 void QgsProjectionSelectionWidget::comboIndexChanged(
int idx )
383 switch (
static_cast< CrsOption >( mCrsComboBox->itemData( idx ).toInt() ) )
399 const long srsid = mCrsComboBox->itemData( idx, Qt::UserRole + 1 ).toLongLong();
412 void QgsProjectionSelectionWidget::updateWarning()
414 if ( !mShowAccuracyWarnings )
416 if ( mWarningLabelContainer->isVisible() )
417 mWarningLabelContainer->hide();
423 const double crsAccuracyWarningThreshold =
QgsSettings().
value( QStringLiteral(
"/projections/crsAccuracyWarningThreshold" ), 0.0,
QgsSettings::App ).toDouble();
426 if ( !ensemble.
isValid() || ensemble.
name() == mSourceEnsemble || ( ensemble.
accuracy() > 0 && ensemble.
accuracy() < crsAccuracyWarningThreshold ) )
428 mWarningLabelContainer->hide();
432 mWarningLabelContainer->show();
434 QString warning = QStringLiteral(
"<p>" );
437 if ( !ensemble.
code().isEmpty() )
438 id = QStringLiteral(
"<i>%1</i> (%2:%3)" ).arg( ensemble.
name(), ensemble.
authority(), ensemble.
code() );
440 id = QStringLiteral(
"<i>%</i>”" ).arg( ensemble.
name() );
444 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() );
448 warning = tr(
"The selected CRS is based on %1, which has a limited accuracy." ).arg(
id );
450 warning += QStringLiteral(
"</p><p>" ) + tr(
"Use an alternative CRS if accurate positioning is required." ) + QStringLiteral(
"</p>" );
452 const QList< QgsDatumEnsembleMember > members = ensemble.
members();
453 if ( !members.isEmpty() )
455 warning += QStringLiteral(
"<p>" ) + tr(
"%1 consists of the datums:" ).arg( ensemble.
name() ) + QStringLiteral(
"</p><ul>" );
459 if ( !member.code().isEmpty() )
460 id = QStringLiteral(
"%1 (%2:%3)" ).arg( member.name(), member.authority(), member.code() );
463 warning += QStringLiteral(
"<li>%1</li>" ).arg(
id );
466 warning += QLatin1String(
"</ul>" );
469 mWarningLabel->setToolTip( warning );
474 mWarningLabelContainer->hide();
486 mCrsComboBox->blockSignals(
true );
488 mCrsComboBox->blockSignals(
false );
493 if ( crsNotSetIndex >= 0 )
495 mCrsComboBox->blockSignals(
true );
496 mCrsComboBox->setCurrentIndex( crsNotSetIndex );
497 mCrsComboBox->blockSignals(
false );
505 if ( mActivePanel && !mIgnorePanelSignals )
507 mIgnorePanelSignals++;
508 mActivePanel->setCrs(
crs );
509 mIgnorePanelSignals--;
524 if ( layerItemIndex > -1 )
535 if ( layerItemIndex > -1 )
537 mCrsComboBox->removeItem( layerItemIndex );
543 void QgsProjectionSelectionWidget::addProjectCrsOption()
551 void QgsProjectionSelectionWidget::addDefaultCrsOption()
556 void QgsProjectionSelectionWidget::addCurrentCrsOption()
568 return tr(
"invalid projection" );
571 void QgsProjectionSelectionWidget::addRecentCrs()
579 if ( crsIsShown( srsid ) )
587 mCrsComboBox->setItemData( mCrsComboBox->count() - 1, QVariant( (
long long )srsid ), Qt::UserRole + 1 );
592 bool QgsProjectionSelectionWidget::crsIsShown(
const long srsid )
const
594 return srsid == mLayerCrs.
srsid() || srsid == mDefaultCrs.
srsid() || srsid == mProjectCrs.
srsid();
597 int QgsProjectionSelectionWidget::firstRecentCrsIndex()
const
599 for (
int i = 0; i < mCrsComboBox->count(); ++i )
609 void QgsProjectionSelectionWidget::updateTooltip()
615 setToolTip( QString() );
619 QgsMapLayer *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...
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