From 12a1be86f2935d50c15b7e12bfacab5e83145304 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Thu, 20 Mar 2025 14:24:47 +1000 Subject: [PATCH] Expose "at equator" scale method in widget When this method is selected, we show a warning icon with an explanatory tooltip: "This method will calculate misleading scales when the map extent is not close to the equator, however it ensures that the scale remains constant and does not change as the map is panned." --- .../qgsscalemethodwidget.sip.in | 1 + .../qgsscalemethodwidget.sip.in | 1 + src/gui/qgsscalemethodwidget.cpp | 51 ++++++++++++++++++- src/gui/qgsscalemethodwidget.h | 11 +++- 4 files changed, 61 insertions(+), 3 deletions(-) diff --git a/python/PyQt6/gui/auto_generated/qgsscalemethodwidget.sip.in b/python/PyQt6/gui/auto_generated/qgsscalemethodwidget.sip.in index e3bf4c6b742..81507ee30b0 100644 --- a/python/PyQt6/gui/auto_generated/qgsscalemethodwidget.sip.in +++ b/python/PyQt6/gui/auto_generated/qgsscalemethodwidget.sip.in @@ -9,6 +9,7 @@ + class QgsScaleMethodWidget : QWidget { %Docstring(signature="appended") diff --git a/python/gui/auto_generated/qgsscalemethodwidget.sip.in b/python/gui/auto_generated/qgsscalemethodwidget.sip.in index e3bf4c6b742..81507ee30b0 100644 --- a/python/gui/auto_generated/qgsscalemethodwidget.sip.in +++ b/python/gui/auto_generated/qgsscalemethodwidget.sip.in @@ -9,6 +9,7 @@ + class QgsScaleMethodWidget : QWidget { %Docstring(signature="appended") diff --git a/src/gui/qgsscalemethodwidget.cpp b/src/gui/qgsscalemethodwidget.cpp index 476025b11ae..f0ee0721984 100644 --- a/src/gui/qgsscalemethodwidget.cpp +++ b/src/gui/qgsscalemethodwidget.cpp @@ -16,8 +16,11 @@ ***************************************************************************/ #include "qgsscalemethodwidget.h" +#include "qgsapplication.h" #include "moc_qgsscalemethodwidget.cpp" #include +#include +#include QgsScaleMethodWidget::QgsScaleMethodWidget( QWidget *parent ) : QWidget( parent ) @@ -29,16 +32,36 @@ QgsScaleMethodWidget::QgsScaleMethodWidget( QWidget *parent ) mCombo->addItem( tr( "Calculate along Top of Map" ), QVariant::fromValue( Qgis::ScaleCalculationMethod::HorizontalTop ) ); mCombo->addItem( tr( "Calculate along Middle of Map" ), QVariant::fromValue( Qgis::ScaleCalculationMethod::HorizontalMiddle ) ); mCombo->addItem( tr( "Calculate along Bottom of Map" ), QVariant::fromValue( Qgis::ScaleCalculationMethod::HorizontalBottom ) ); + mCombo->addItem( tr( "Always Calculate at Equator" ), QVariant::fromValue( Qgis::ScaleCalculationMethod::AtEquator ) ); QHBoxLayout *hLayout = new QHBoxLayout(); hLayout->setContentsMargins( 0, 0, 0, 0 ); - hLayout->addWidget( mCombo ); + hLayout->addWidget( mCombo, 1 ); + + // bit of fiddlyness here -- we want the initial spacing to only be visible + // when the warning label is shown, so it's embedded inside mWarningLabel + // instead of outside it + mWarningLabelContainer = new QWidget(); + QHBoxLayout *warningLayout = new QHBoxLayout(); + warningLayout->setContentsMargins( 0, 0, 0, 0 ); + mWarningLabel = new QLabel(); + const QIcon icon = QgsApplication::getThemeIcon( QStringLiteral( "mIconWarning.svg" ) ); + const int size = static_cast( std::max( 24.0, mCombo->minimumSize().height() * 0.5 ) ); + mWarningLabel->setPixmap( icon.pixmap( icon.actualSize( QSize( size, size ) ) ) ); + const int labelMargin = static_cast( std::round( mCombo->fontMetrics().horizontalAdvance( 'X' ) ) ); + warningLayout->insertSpacing( 0, labelMargin / 2 ); + warningLayout->insertWidget( 1, mWarningLabel ); + mWarningLabelContainer->setLayout( warningLayout ); + hLayout->addWidget( mWarningLabelContainer ); + mWarningLabelContainer->hide(); + setLayout( hLayout ); setFocusPolicy( Qt::FocusPolicy::StrongFocus ); setFocusProxy( mCombo ); connect( mCombo, qOverload( &QComboBox::currentIndexChanged ), this, &QgsScaleMethodWidget::methodChanged ); + connect( mCombo, qOverload( &QComboBox::currentIndexChanged ), this, &QgsScaleMethodWidget::updateWarning ); } Qgis::ScaleCalculationMethod QgsScaleMethodWidget::scaleMethod() const @@ -49,4 +72,30 @@ Qgis::ScaleCalculationMethod QgsScaleMethodWidget::scaleMethod() const void QgsScaleMethodWidget::setScaleMethod( Qgis::ScaleCalculationMethod method ) { mCombo->setCurrentIndex( mCombo->findData( QVariant::fromValue( method ) ) ); + updateWarning(); +} + +void QgsScaleMethodWidget::updateWarning() +{ + switch ( scaleMethod() ) + { + case Qgis::ScaleCalculationMethod::HorizontalTop: + case Qgis::ScaleCalculationMethod::HorizontalMiddle: + case Qgis::ScaleCalculationMethod::HorizontalBottom: + case Qgis::ScaleCalculationMethod::HorizontalAverage: + mWarningLabelContainer->hide(); + break; + + case Qgis::ScaleCalculationMethod::AtEquator: + { + mWarningLabelContainer->show(); + const QString warning = QStringLiteral( "

%1

%2

" ).arg( tr( "This method will calculate misleading scales when the map extent is not close to the " + "equator, however it ensures that the scale remains constant and does not " + "change as the map is panned." ), + tr( "This setting is valid for maps in a geographic (latitude/longitude) CRS only." ) ); + mWarningLabel->setToolTip( warning ); + + break; + } + } } diff --git a/src/gui/qgsscalemethodwidget.h b/src/gui/qgsscalemethodwidget.h index b50282e251b..a3d672ff210 100644 --- a/src/gui/qgsscalemethodwidget.h +++ b/src/gui/qgsscalemethodwidget.h @@ -18,10 +18,12 @@ #ifndef QGSSCALEMETHODWIDGET_H #define QGSSCALEMETHODWIDGET_H -#include #include "qgis_sip.h" -#include // For QPainter::CompositionMode enum #include "qgis_gui.h" +#include + +class QLabel; +class QComboBox; /** * \ingroup gui @@ -56,6 +58,11 @@ class GUI_EXPORT QgsScaleMethodWidget : public QWidget private: QComboBox *mCombo = nullptr; + QWidget *mWarningLabelContainer = nullptr; + QLabel *mWarningLabel = nullptr; + + private slots: + void updateWarning(); }; #endif // QGSSCALEMETHODWIDGET_H