23#include <QAbstractItemView>
33 setInsertPolicy( QComboBox::NoInsert );
34 setCompleter(
nullptr );
35 connect(
this, qOverload< int >( &QComboBox::activated ),
this, &QgsScaleComboBox::fixupScale );
36 connect( lineEdit(), &QLineEdit::editingFinished,
this, &QgsScaleComboBox::fixupScale );
42 QStringList myScalesList;
43 const QString oldScale = currentText();
45 if ( scales.isEmpty() )
51 QStringList::const_iterator scaleIt = scales.constBegin();
52 for ( ; scaleIt != scales.constEnd(); ++scaleIt )
54 myScalesList.append( *scaleIt );
58 QStringList myCleanedScalesList;
60 for (
int i = 0; i < myScalesList.size(); ++i )
62 const QStringList parts = myScalesList[ i ] .split(
':' );
63 if ( parts.size() < 2 )
67 const double denominator = QLocale().toDouble( parts[1], &ok );
70 myCleanedScalesList.push_back(
toString( denominator ) );
74 const double denominator = parts[1].toDouble( &ok );
77 myCleanedScalesList.push_back(
toString( denominator ) );
84 addItems( myCleanedScalesList );
86 blockSignals(
false );
91 QComboBox::showPopup();
93 if ( !currentText().contains(
':' ) )
97 QStringList parts = currentText().split(
':' );
101 const long currScale = parts.at( 1 ).toLong( &ok );
102 long nextScale, delta;
103 for (
int i = 0; i < count(); i++ )
105 parts = itemText( i ).split(
':' );
106 nextScale = parts.at( 1 ).toLong( &ok );
107 delta = std::labs( currScale - nextScale );
115 blockSignals(
true );
116 view()->setCurrentIndex( model()->index( idx, 0 ) );
117 blockSignals(
false );
118 view()->setMinimumWidth( view()->sizeHintForColumn( 0 ) );
128 const double oldScale = mScale;
129 if ( mAllowNull &&
string.trimmed().isEmpty() )
131 mScale = std::numeric_limits< double >::quiet_NaN();
134 if ( !std::isnan( oldScale ) )
142 double newScale =
toDouble(
string, &ok );
143 if ( newScale > mMinScale && newScale != 0 && mMinScale != 0 )
145 newScale = mMinScale;
156 if ( mScale != oldScale )
171 return std::isnan( mScale );
179void QgsScaleComboBox::fixupScale()
181 if ( mAllowNull && currentText().trimmed().isEmpty() )
183 setScale( std::numeric_limits< double >::quiet_NaN() );
187 const QStringList txtList = currentText().split(
':' );
188 const bool userSetScale = txtList.size() != 2;
191 double newScale =
toDouble( currentText(), &ok );
197 if ( userSetScale && newScale < 1.0 && !
qgsDoubleNear( newScale, 0.0 ) )
199 newScale = 1 / newScale;
211 if ( std::isnan(
scale ) )
217 return QStringLiteral(
"0" );
219 else if (
scale <= 1 )
221 return QStringLiteral(
"%1:1" ).arg( QLocale().
toString(
static_cast< int >( std::round( 1.0 /
scale ) ) ) );
225 return QStringLiteral(
"1:%1" ).arg( QLocale().
toString(
static_cast< float >( std::round(
scale ) ),
'f', 0 ) );
245 QStringList txtList = scaleTxt.split(
':' );
246 if ( 2 == txtList.size() )
252 if ( okX && okY && x != 0 )
255 scale =
static_cast< double >( y ) /
static_cast< double >( x );
272 lineEdit()->setClearButtonEnabled(
allowNull );
284 if ( mScale > mMinScale && mScale != 0 && mMinScale != 0 )
293 setScale( std::numeric_limits< double >::quiet_NaN() );
static QString toString(double scale)
Helper function to convert a scale double to scale string.
void updateScales(const QStringList &scales=QStringList())
Sets the list of predefined scales to show in the combobox.
QString scaleString() const
Returns the selected scale as a string, e.g.
bool setScaleString(const QString &string)
Set the selected scale from a string, e.g.
void setAllowNull(bool allowNull)
Sets whether the scale combobox can be set to a NULL value.
QgsScaleComboBox(QWidget *parent=nullptr)
Constructor for QgsScaleComboBox.
bool isNull() const
Returns true if the combo box is currently set to a "null" value.
bool allowNull() const
Returns true if the combobox can be set to a NULL value.
static double toDouble(const QString &string, bool *ok=nullptr)
Helper function to convert a scale string to double.
void setScale(double scale)
Set the selected scale from a double.
void showPopup() override
void setNull()
Sets the combo box to the null value.
void setMinScale(double scale)
Set the minimum allowed scale.
void scaleChanged(double scale)
Emitted when user has finished editing/selecting a new scale.
T value(const QString &dynamicKeyPart=QString()) const
Returns settings value.
static const QgsSettingsEntryStringList * settingsMapScales
double qgsPermissiveToDouble(QString string, bool &ok)
Converts a string to a double in a permissive way, e.g., allowing for incorrect numbers of digits bet...
int qgsPermissiveToInt(QString string, bool &ok)
Converts a string to an integer in a permissive way, e.g., allowing for incorrect numbers of digits b...
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)