Unify scale widgets API

Flip all scale based widgets to use scale denominators instead
of actual scales (ie 100.0 instead of 0.01 for 1:100).

This is done for consistency with the rest of the API, which
predominantly uses scale denominators. It also helps
precision loss as a result of multiple 1.0 / scale conversions
throughout the code.

Refs #15337
This commit is contained in:
Nyall Dawson 2017-06-02 14:08:42 +10:00
parent 9f71156a13
commit 08a9bcba0a
28 changed files with 646 additions and 267 deletions

View File

@ -2010,6 +2010,32 @@ QgsScaleBarStyle {#qgis_api_break_3_0_QgsScaleBarStyle}
- The interface for QgsScaleBarStyle has been completely rewritten - any code using QgsScaleBarStyle or subclasses will need to update
to the new draw() and calculateBoxSize() methods.
QgsScaleComboBox {#qgis_api_break_3_0_QgsScaleComboBox}
----------------
- All numeric scales reported and used by QgsScaleComboBox now represent the scale denominator (i.e. 2345 for a scale "1:2345"), for consistency with other scale use throughout the API.
QgsScaleRangeWidget {#qgis_api_break_3_0_QgsScaleRangeWidget}
-------------------
- All numeric scales reported and used by QgsScaleRangeWidget now represent the scale denominator (i.e. 2345 for a scale "1:2345"), for consistency with other scale use throughout the API.
- minimumScaleDenom() and maximumScaleDenom() were removed. Now minimumScale() and maximumScale() report the scale denominator.
QgsScaleVisibilityDialog {#qgis_api_break_3_0_QgsScaleVisibilityDialog}
------------------------
- All numeric scales reported and used by QgsScaleVisibilityDialog now represent the scale denominator (i.e. 2345 for a scale "1:2345"), for consistency with other scale use throughout the API.
QgsScaleWidget {#qgis_api_break_3_0_QgsScaleWidget}
--------------
- All numeric scales reported and used by QgsScaleWidget now represent the scale denominator (i.e. 2345 for a scale "1:2345"), for consistency with other scale use throughout the API.
QgsServer {#qgis_api_break_3_0_QgsServer}
----------

View File

@ -50,8 +50,6 @@ gui/qgsrasterformatsaveoptionswidget.sip
gui/qgsrasterlayersaveasdialog.sip
gui/qgsrasterpyramidsoptionswidget.sip
gui/qgsrubberband.sip
gui/qgsscalerangewidget.sip
gui/qgsscalevisibilitydialog.sip
gui/qgsscrollarea.sip
gui/qgssearchquerybuilder.sip
gui/qgsshortcutsmanager.sip

View File

@ -21,57 +21,90 @@ class QgsScaleComboBox : QComboBox
#include "qgsscalecombobox.h"
%End
public:
QgsScaleComboBox( QWidget *parent /TransferThis/ = 0 );
QString scaleString();
QgsScaleComboBox( QWidget *parent /TransferThis/ = 0 );
%Docstring
Function to read the selected scale as text
Constructor for QgsScaleComboBox.
%End
QString scaleString() const;
%Docstring
Returns the selected scale as a string, e.g. "1:150".
.. seealso:: setScaleString()
:rtype: str
%End
bool setScaleString( const QString &scaleTxt );
bool setScaleString( const QString &string );
%Docstring
Function to set the selected scale from text
Set the selected scale from a ``string``, e.g. "1:150".
.. seealso:: scaleString()
:rtype: bool
%End
double scale() const;
%Docstring
Function to read the selected scale as double
Returns the selected scale as a double.
The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
.. seealso:: setScale()
:rtype: float
%End
void setScale( double scale );
%Docstring
Function to set the selected scale from double
%End
double minScale() const;
%Docstring
Function to read the min scale
Returns the minimum scale, or 0 if no minimum scale set.
The ``scale`` value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
Any scale lower than the minimum scale will automatically be converted to the minimum scale.
Except for 0 which is always allowed.
:rtype: float
%End
static QString toString( double scale );
%Docstring
Helper function to convert a ``scale`` double to scale string.
The ``scale`` value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
The returned string will be rounded (e.g. 1:1000, not 1:1000.345).
.. seealso:: toDouble()
:rtype: str
%End
static double toDouble( const QString &scaleString, bool *ok = 0 );
static double toDouble( const QString &string, bool *ok = 0 );
%Docstring
Helper function to convert a scale string to double
Helper function to convert a scale ``string`` to double.
The returned value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
If specified, ``ok`` will be set to true if the string was successfully interpreted as a scale.
.. seealso:: toString()
:rtype: float
%End
signals:
void scaleChanged( double scale );
%Docstring
Signal is emitted when *user* has finished editing/selecting a new scale.
Emitted when *user* has finished editing/selecting a new scale.
The ``scale`` value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
%End
public slots:
void updateScales( const QStringList &scales = QStringList() );
%Docstring
Sets the list of predefined ``scales`` to show in the combobox. List elements
are expected to be valid scale strings, such as "1:1000000".
%End
void setScale( double scale );
%Docstring
Set the selected scale from a double.
The ``scale`` value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
.. seealso:: scale()
%End
void setMinScale( double scale );
%Docstring
Set the minimum allowed scale.
Anything scale lower than the minimum scale will automatically
be converted to the minimum scale.
Set the minimum allowed ``scale``. Set to 0 to disable the minimum scale.
The ``scale`` value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
Any scale lower than the minimum scale will automatically be converted to the minimum scale.
Except for 0 which is always allowed.
%End

View File

@ -1,49 +1,104 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/qgsscalerangewidget.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
class QgsScaleRangeWidget : QWidget
{
%Docstring
A widget allowing entry of a range of map scales, e.g. minimum scale and maximum scale.
%End
%TypeHeaderCode
#include "qgsscalerangewidget.h"
%End
public:
explicit QgsScaleRangeWidget( QWidget *parent /TransferThis/ = 0 );
~QgsScaleRangeWidget();
%Docstring
Constructor for QgsScaleRangeWidget.
%End
//! set the map canvas which will be used for the current scale buttons
/**
* @brief setMapCanvas set the map canvas which will be used for the current scale buttons
* if not set, the buttons are hidden.
*/
void setMapCanvas( QgsMapCanvas *mapCanvas );
void setMapCanvas( QgsMapCanvas *canvas );
%Docstring
Sets the map ``canvas`` which will be used for the current scale buttons.
If not set, the buttons are hidden.
%End
//! return the minimum scale
double minimumScale();
double minimumScale() const;
%Docstring
Returns the selected minimum scale, or 0 if minimum scale is not set.
The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
.. seealso:: maximumScale()
.. seealso:: setMinimumScale()
:rtype: float
%End
//! return the maximum scale
double maximumScale();
double maximumScale() const;
%Docstring
Returns the selected maximum scale, or 0 if maximum scale is not set.
The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
.. seealso:: minimumScale()
.. seealso:: setMaximumScale()
:rtype: float
%End
//! return the minimum scale denominator ( = 1 / maximum scale )
double minimumScaleDenom();
//! return the maximum scale denominator ( = 1 / minimum scale )
double maximumScaleDenom();
//! call to reload the project scales and apply them to the 2 scales combo boxes
void reloadProjectScales();
%Docstring
Call to reload the preset scales from the current project and apply them to the 2 scales combo boxes.
%End
public slots:
void setMinimumScale( double scale );
%Docstring
Set the minimum ``scale``, or 0 to indicate the minimum is not set.
The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
.. seealso:: minimumScale()
.. seealso:: setMaximumScale()
.. seealso:: setScaleRange()
%End
void setMaximumScale( double scale );
%Docstring
Set the maximum ``scale``, or 0 to indicate the minimum is not set.
The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
.. seealso:: maximumScale()
.. seealso:: setMinimumScale()
.. seealso:: setScaleRange()
%End
void setScaleRange( double min, double max );
%Docstring
Sets the scale range, from ``min`` scale to ``max`` scale.
The scale values indicates the scale denominator, e.g. 1000.0 for a 1:1000 map,
or 0 to indicate not set.
.. seealso:: setMinimumScale()
.. seealso:: setMaximumScale()
%End
signals:
/** Emitted when the scale range set in the widget is changed.
* @param min minimum scale
* @param max maximum scale
* @note added in QGIS 2.16
*/
void rangeChanged( double min, double max );
%Docstring
Emitted when the scale range set in the widget is changed.
The scale values indicates the scale denominator, e.g. 1000.0 for a 1:1000 map,
or 0 to indicate not set.
.. versionadded:: 2.16
%End
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/qgsscalerangewidget.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/

View File

@ -1,30 +1,87 @@
class QgsScaleVisibilityDialog : QObject
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/qgsscalevisibilitydialog.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
class QgsScaleVisibilityDialog : QDialog
{
%TypeHeaderCode
#include <qgsscalevisibilitydialog.h>
%Docstring
A dialog allowing users to enter a scale visibility range.
%End
%TypeHeaderCode
#include "qgsscalevisibilitydialog.h"
%End
public:
explicit QgsScaleVisibilityDialog( QWidget *parent /TransferThis/ = 0, const QString &title = QString(), QgsMapCanvas *mapCanvas = 0 );
%Docstring
Constructor for QgsScaleVisibilityDialog, with specified dialog ``title``. The ``mapCanvas`` argument
can be used to associate the dialog with a map canvas, allowing use of the current map scale
within the dialog.
%End
//! return if scale visibilty is enabled
bool hasScaleVisibility();
bool hasScaleVisibility() const;
%Docstring
Return true if scale based visibilty is enabled.
:rtype: bool
%End
//! return minimum scale (true scale, not scale denominator)
double minimumScale();
//! return maximum scale (true scale, not scale denominator)
double maximumScale();
double minimumScale() const;
%Docstring
Returns the selected minimum scale, or 0 if minimum scale is not set.
The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
.. seealso:: maximumScale()
.. seealso:: setMinimumScale()
:rtype: float
%End
double maximumScale() const;
%Docstring
Returns the selected maximum scale, or 0 if maximum scale is not set.
The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
.. seealso:: minimumScale()
.. seealso:: setMaximumScale())
:rtype: float
%End
public slots:
//! set if scale visibility is enabled
void setScaleVisiblity( bool hasScaleVisibility );
%Docstring
Set whether scale based visibility is enabled.
.. seealso:: hasScaleVisibility()
%End
//! set minimum scale (true scale, not scale denominator)
void setMinimumScale( double minScale );
void setMinimumScale( double scale );
%Docstring
Set the minimum ``scale``, or 0 to indicate the minimum is not set.
The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
.. seealso:: minimumScale()
.. seealso:: setMaximumScale()
%End
void setMaximumScale( double scale );
%Docstring
Set the maximum ``scale``, or 0 to indicate the minimum is not set.
The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
.. seealso:: maximumScale()
.. seealso:: setMinimumScale()
%End
//! set maximum scale (true scale, not scale denominator)
void setMaximumScale( double maxScale );
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/qgsscalevisibilitydialog.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/

View File

@ -33,76 +33,111 @@ class QgsScaleWidget : QWidget
void setShowCurrentScaleButton( bool showCurrentScaleButton );
%Docstring
Sets whether to show a button to set the scale to the current scale of the map canvas next to the combobox.
.. note::
the map canvas must be defined to show the button
.. seealso:: showCurrentScaleButton()
.. seealso:: setMapCanvas()
%End
bool showCurrentScaleButton();
%Docstring
returns if a button to set the scale from map canvas is shown or not
Returns whether a button to set the scale from map canvas is shown or not.
.. seealso:: setShowCurrentScaleButton()
:rtype: bool
%End
void setMapCanvas( QgsMapCanvas *canvas );
%Docstring
set the map canvas associated to the current button
Set the map ``canvas`` associated to the current button.
%End
QString scaleString();
QString scaleString() const;
%Docstring
Function to read the selected scale as text
Returns the selected scale as a string, e.g. "1:150".
.. seealso:: setScaleString()
:rtype: str
%End
bool setScaleString( const QString &scaleTxt );
bool setScaleString( const QString &string );
%Docstring
Function to set the selected scale from text
Set the selected scale from a ``string``, e.g. "1:150".
.. seealso:: scaleString()
:rtype: bool
%End
double scale() const;
%Docstring
Function to read the selected scale as double
Returns the selected scale as a double.
The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
.. seealso:: setScale()
:rtype: float
%End
void setScale( double scale );
%Docstring
Function to set the selected scale from double
%End
double minScale() const;
%Docstring
Function to read the min scale
Returns the minimum scale, or 0 if no minimum scale set.
The ``scale`` value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
Any scale lower than the minimum scale will automatically be converted to the minimum scale.
Except for 0 which is always allowed.
:rtype: float
%End
static QString toString( double scale );
%Docstring
Helper function to convert a ``scale`` double to scale string.
The ``scale`` value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
The returned string will be rounded (e.g. 1:1000, not 1:1000.345).
.. seealso:: toDouble()
:rtype: str
%End
static double toDouble( const QString &scaleString, bool *ok = 0 );
%Docstring
Helper function to convert a scale string to double
Helper function to convert a scale ``string`` to double.
The returned value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
If specified, ``ok`` will be set to true if the string was successfully interpreted as a scale.
.. seealso:: toString()
:rtype: float
%End
public slots:
void setScale( double scale );
%Docstring
Set the selected scale from a double.
The ``scale`` value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
.. seealso:: scale()
%End
void updateScales( const QStringList &scales = QStringList() );
%Docstring
updates the list of predefined scales
Sets the list of predefined ``scales`` to show in the combobox. List elements
are expected to be valid scale strings, such as "1:1000000".
%End
void setScaleFromCanvas();
%Docstring
assign the current scale from the map canvas
Assigns the current scale from the map canvas, if set.
.. seealso:: setMapCanvas()
%End
void setMinScale( double scale );
%Docstring
Function to set the min scale
Set the minimum allowed ``scale``. Set to 0 to disable the minimum scale.
The ``scale`` value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
Any scale lower than the minimum scale will automatically be converted to the minimum scale.
Except for 0 which is always allowed.
%End
signals:
void scaleChanged( double scale );
%Docstring
Signal is emitted when *user* has finished editing/selecting a new scale.
Emitted when *user* has finished editing/selecting a new scale.
The ``scale`` value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
%End
};

View File

@ -8979,8 +8979,8 @@ void QgisApp::setLayerScaleVisibility()
if ( layer )
{
dlg->setScaleVisiblity( layer->hasScaleBasedVisibility() );
dlg->setMinimumScale( 1.0 / layer->minimumScale() );
dlg->setMaximumScale( 1.0 / layer->maximumScale() );
dlg->setMinimumScale( layer->minimumScale() );
dlg->setMaximumScale( layer->maximumScale() );
}
if ( dlg->exec() )
{
@ -8988,8 +8988,8 @@ void QgisApp::setLayerScaleVisibility()
Q_FOREACH ( QgsMapLayer *layer, layers )
{
layer->setScaleBasedVisibility( dlg->hasScaleVisibility() );
layer->setMaximumScale( 1.0 / dlg->maximumScale() );
layer->setMinimumScale( 1.0 / dlg->minimumScale() );
layer->setMaximumScale( dlg->maximumScale() );
layer->setMinimumScale( dlg->minimumScale() );
}
freezeCanvases( false );
refreshMapCanvas();

View File

@ -205,7 +205,7 @@ QgsDiagramProperties::QgsDiagramProperties( QgsVectorLayer *layer, QWidget *pare
mIncreaseMinimumSizeLabel->setEnabled( false );
mBarWidthSpinBox->setValue( 5 );
mScaleVisibilityGroupBox->setChecked( layer->hasScaleBasedVisibility() );
mScaleRangeWidget->setScaleRange( 1.0 / layer->minimumScale(), 1.0 / layer->maximumScale() ); // caution: layer uses scale denoms, widget uses true scales
mScaleRangeWidget->setScaleRange( layer->minimumScale(), layer->maximumScale() );
mShowAllCheckBox->setChecked( true );
mCheckBoxAttributeLegend->setChecked( true );
mCheckBoxSizeLegend->setChecked( false );
@ -265,9 +265,8 @@ QgsDiagramProperties::QgsDiagramProperties( QgsVectorLayer *layer, QWidget *pare
mDiagramPenColorButton->setColor( settingList.at( 0 ).penColor );
mPenWidthSpinBox->setValue( settingList.at( 0 ).penWidth );
mDiagramSizeSpinBox->setValue( ( size.width() + size.height() ) / 2.0 );
// caution: layer uses scale denoms, widget uses true scales
mScaleRangeWidget->setScaleRange( 1.0 / ( settingList.at( 0 ).maxScaleDenominator > 0 ? settingList.at( 0 ).maxScaleDenominator : layer->minimumScale() ),
1.0 / ( settingList.at( 0 ).minScaleDenominator > 0 ? settingList.at( 0 ).minScaleDenominator : layer->maximumScale() ) );
mScaleRangeWidget->setScaleRange( ( settingList.at( 0 ).maxScaleDenominator > 0 ? settingList.at( 0 ).maxScaleDenominator : layer->minimumScale() ),
( settingList.at( 0 ).minScaleDenominator > 0 ? settingList.at( 0 ).minScaleDenominator : layer->maximumScale() ) );
mScaleVisibilityGroupBox->setChecked( settingList.at( 0 ).scaleBasedVisibility );
mDiagramUnitComboBox->setUnit( settingList.at( 0 ).sizeType );
mDiagramUnitComboBox->setMapUnitScale( settingList.at( 0 ).sizeScale );
@ -774,8 +773,8 @@ void QgsDiagramProperties::apply()
ds.penColor = mDiagramPenColorButton->color();
ds.penWidth = mPenWidthSpinBox->value();
// caution: layer uses scale denoms, widget uses true scales
ds.maxScaleDenominator = 1.0 / mScaleRangeWidget->minimumScale();
ds.minScaleDenominator = 1.0 / mScaleRangeWidget->maximumScale();
ds.maxScaleDenominator = mScaleRangeWidget->minimumScale();
ds.minScaleDenominator = mScaleRangeWidget->maximumScale();
ds.scaleBasedVisibility = mScaleVisibilityGroupBox->isChecked();
// Diagram angle offset (pie)

View File

@ -453,7 +453,9 @@ QgsDxfExportDialog::QgsDxfExportDialog( QWidget *parent, Qt::WindowFlags f )
//last symbol scale
mScaleWidget->setMapCanvas( QgisApp::instance()->mapCanvas() );
mScaleWidget->setScale( QgsProject::instance()->readEntry( QStringLiteral( "dxf" ), QStringLiteral( "/lastSymbologyExportScale" ), s.value( QStringLiteral( "qgis/lastSymbologyExportScale" ), "1/50000" ).toString() ).toDouble() );
double oldScale = QgsProject::instance()->readEntry( QStringLiteral( "dxf" ), QStringLiteral( "/lastSymbologyExportScale" ), s.value( QStringLiteral( "qgis/lastSymbologyExportScale" ), "1/50000" ).toString() ).toDouble();
if ( oldScale != 0.0 )
mScaleWidget->setScale( 1.0 / oldScale );
mLayerTitleAsName->setChecked( QgsProject::instance()->readEntry( QStringLiteral( "dxf" ), QStringLiteral( "/lastDxfLayerTitleAsName" ), s.value( QStringLiteral( "qgis/lastDxfLayerTitleAsName" ), "false" ).toString() ) != QLatin1String( "false" ) );
mMapExtentCheckBox->setChecked( QgsProject::instance()->readEntry( QStringLiteral( "dxf" ), QStringLiteral( "/lastDxfMapRectangle" ), s.value( QStringLiteral( "qgis/lastDxfMapRectangle" ), "false" ).toString() ) != QLatin1String( "false" ) );
@ -545,10 +547,7 @@ QList< QPair<QgsVectorLayer *, int> > QgsDxfExportDialog::layers() const
double QgsDxfExportDialog::symbologyScale() const
{
if ( qgsDoubleNear( mScaleWidget->scale(), 0.0 ) )
return 1.0;
double scale = 1.0 / mScaleWidget->scale();
double scale = mScaleWidget->scale();
if ( qgsDoubleNear( scale, 0.0 ) )
return 1.0;
@ -613,14 +612,14 @@ void QgsDxfExportDialog::saveSettings()
QFileInfo dxfFileInfo( mFileLineEdit->text() );
s.setValue( QStringLiteral( "qgis/lastDxfDir" ), dxfFileInfo.absolutePath() );
s.setValue( QStringLiteral( "qgis/lastDxfSymbologyMode" ), mSymbologyModeComboBox->currentIndex() );
s.setValue( QStringLiteral( "qgis/lastSymbologyExportScale" ), mScaleWidget->scale() );
s.setValue( QStringLiteral( "qgis/lastSymbologyExportScale" ), mScaleWidget->scale() != 0 ? 1.0 / mScaleWidget->scale() : 0 );
s.setValue( QStringLiteral( "qgis/lastDxfMapRectangle" ), mMapExtentCheckBox->isChecked() );
s.setValue( QStringLiteral( "qgis/lastDxfLayerTitleAsName" ), mLayerTitleAsName->isChecked() );
s.setValue( QStringLiteral( "qgis/lastDxfEncoding" ), mEncoding->currentText() );
s.setValue( QStringLiteral( "qgis/lastDxfCrs" ), QString::number( mCRS.srsid() ) );
QgsProject::instance()->writeEntry( QStringLiteral( "dxf" ), QStringLiteral( "/lastDxfSymbologyMode" ), mSymbologyModeComboBox->currentIndex() );
QgsProject::instance()->writeEntry( QStringLiteral( "dxf" ), QStringLiteral( "/lastSymbologyExportScale" ), mScaleWidget->scale() );
QgsProject::instance()->writeEntry( QStringLiteral( "dxf" ), QStringLiteral( "/lastSymbologyExportScale" ), mScaleWidget->scale() != 0 ? 1.0 / mScaleWidget->scale() : 0 );
QgsProject::instance()->writeEntry( QStringLiteral( "dxf" ), QStringLiteral( "/lastDxfLayerTitleAsName" ), mLayerTitleAsName->isChecked() );
QgsProject::instance()->writeEntry( QStringLiteral( "dxf" ), QStringLiteral( "/lastDxfMapRectangle" ), mMapExtentCheckBox->isChecked() );
QgsProject::instance()->writeEntry( QStringLiteral( "dxf" ), QStringLiteral( "/lastDxfEncoding" ), mEncoding->currentText() );

View File

@ -133,7 +133,7 @@ QgsMapCanvasDockWidget::QgsMapCanvasDockWidget( const QString &name, QWidget *pa
if ( !mBlockScaleUpdate )
{
mBlockScaleUpdate = true;
mMapCanvas->zoomScale( 1.0 / scale );
mMapCanvas->zoomScale( scale );
mBlockScaleUpdate = false;
}
} );
@ -142,7 +142,7 @@ QgsMapCanvasDockWidget::QgsMapCanvasDockWidget( const QString &name, QWidget *pa
if ( !mBlockScaleUpdate )
{
mBlockScaleUpdate = true;
mScaleCombo->setScale( 1.0 / scale );
mScaleCombo->setScale( scale );
mBlockScaleUpdate = false;
}
} );

View File

@ -53,7 +53,7 @@ QgsMapSaveDialog::QgsMapSaveDialog( QWidget *parent, QgsMapCanvas *mapCanvas, co
mExtentGroupBox->setCurrentExtent( mExtent, ms.destinationCrs() );
mExtentGroupBox->setOutputExtentFromCurrent();
mScaleWidget->setScale( 1 / ms.scale() );
mScaleWidget->setScale( ms.scale() );
mScaleWidget->setMapCanvas( mMapCanvas );
mScaleWidget->setShowCurrentScaleButton( true );
@ -144,7 +144,7 @@ void QgsMapSaveDialog::updateScale( double scale )
calculator.setDpi( mDpi );
double oldScale = 1 / ( calculator.calculate( mExtent, mSize.width() ) );
double scaleRatio = oldScale / scale;
double scaleRatio = scale / oldScale;
mExtent.scale( scaleRatio );
mExtentGroupBox->setOutputExtentFromUser( mExtent, mExtentGroupBox->currentCrs() );
}

View File

@ -602,7 +602,7 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl, const QList<QgsOpti
QStringList myScalesList = PROJECT_SCALES.split( ',' );
myScalesList.append( QStringLiteral( "1:1" ) );
mSimplifyMaximumScaleComboBox->updateScales( myScalesList );
mSimplifyMaximumScaleComboBox->setScale( 1.0 / mSettings->value( QStringLiteral( "/qgis/simplifyMaxScale" ), 1 ).toFloat() );
mSimplifyMaximumScaleComboBox->setScale( mSettings->value( QStringLiteral( "/qgis/simplifyMaxScale" ), 1 ).toFloat() );
// Magnifier
double magnifierMin = 100 * QgsGuiUtils::CANVAS_MAGNIFICATION_MIN;
@ -1255,7 +1255,7 @@ void QgsOptions::saveOptions()
mSettings->setValue( QStringLiteral( "/qgis/simplifyAlgorithm" ), mSimplifyAlgorithmComboBox->currentData().toInt() );
mSettings->setValue( QStringLiteral( "/qgis/simplifyDrawingTol" ), mSimplifyDrawingSpinBox->value() );
mSettings->setValue( QStringLiteral( "/qgis/simplifyLocal" ), !mSimplifyDrawingAtProvider->isChecked() );
mSettings->setValue( QStringLiteral( "/qgis/simplifyMaxScale" ), 1.0 / mSimplifyMaximumScaleComboBox->scale() );
mSettings->setValue( QStringLiteral( "/qgis/simplifyMaxScale" ), mSimplifyMaximumScaleComboBox->scale() );
// magnification
mSettings->setValue( QStringLiteral( "/qgis/magnifier_factor_default" ), doubleSpinBoxMagnifierDefault->value() / 100 );

View File

@ -141,7 +141,7 @@ QgsRasterLayerProperties::QgsRasterLayerProperties( QgsMapLayer *lyr, QgsMapCanv
// set up the scale based layer visibility stuff....
mScaleRangeWidget->setMapCanvas( mMapCanvas );
chkUseScaleDependentRendering->setChecked( lyr->hasScaleBasedVisibility() );
mScaleRangeWidget->setScaleRange( 1.0 / lyr->minimumScale(), 1.0 / lyr->maximumScale() ); // caution: layer uses scale denoms, widget uses true scales
mScaleRangeWidget->setScaleRange( lyr->minimumScale(), lyr->maximumScale() );
leNoDataValue->setValidator( new QDoubleValidator( -std::numeric_limits<double>::max(), std::numeric_limits<double>::max(), 1000, this ) );
@ -910,9 +910,8 @@ void QgsRasterLayerProperties::apply()
// set up the scale based layer visibility stuff....
mRasterLayer->setScaleBasedVisibility( chkUseScaleDependentRendering->isChecked() );
// caution: layer uses scale denoms, widget uses true scales
mRasterLayer->setMinimumScale( 1.0 / mScaleRangeWidget->minimumScale() );
mRasterLayer->setMaximumScale( 1.0 / mScaleRangeWidget->maximumScale() );
mRasterLayer->setMinimumScale( mScaleRangeWidget->minimumScale() );
mRasterLayer->setMaximumScale( mScaleRangeWidget->maximumScale() );
mRasterLayer->setAutoRefreshInterval( mRefreshLayerIntervalSpinBox->value() * 1000.0 );
mRasterLayer->setAutoRefreshEnabled( mRefreshLayerCheckBox->isChecked() );

View File

@ -602,9 +602,9 @@ QgsLabelingRulePropsWidget::QgsLabelingRulePropsWidget( QgsRuleBasedLabeling::Ru
groupScale->setChecked( true );
// caution: rule uses scale denom, scale widget uses true scales
if ( rule->scaleMinDenom() > 0 )
mScaleRangeWidget->setMaximumScale( 1.0 / rule->scaleMinDenom() );
mScaleRangeWidget->setMaximumScale( rule->scaleMinDenom() );
if ( rule->scaleMaxDenom() > 0 )
mScaleRangeWidget->setMinimumScale( 1.0 / rule->scaleMaxDenom() );
mScaleRangeWidget->setMinimumScale( rule->scaleMaxDenom() );
}
mScaleRangeWidget->setMapCanvas( mMapCanvas );
@ -704,7 +704,7 @@ void QgsLabelingRulePropsWidget::apply()
mRule->setFilterExpression( editFilter->text() );
mRule->setDescription( editDescription->text() );
// caution: rule uses scale denom, scale widget uses true scales
mRule->setScaleMinDenom( groupScale->isChecked() ? mScaleRangeWidget->minimumScaleDenom() : 0 );
mRule->setScaleMaxDenom( groupScale->isChecked() ? mScaleRangeWidget->maximumScaleDenom() : 0 );
mRule->setScaleMinDenom( groupScale->isChecked() ? mScaleRangeWidget->minimumScale() : 0 );
mRule->setScaleMaxDenom( groupScale->isChecked() ? mScaleRangeWidget->maximumScale() : 0 );
mRule->setSettings( groupSettings->isChecked() ? new QgsPalLayerSettings( mLabelingGui->layerSettings() ) : nullptr );
}

View File

@ -80,7 +80,7 @@ QgsStatusBarScaleWidget::~QgsStatusBarScaleWidget()
void QgsStatusBarScaleWidget::setScale( double scale )
{
mScale->blockSignals( true );
mScale->setScale( scale );
mScale->setScale( 1.0 / scale );
mScale->blockSignals( false );
}
@ -102,6 +102,5 @@ void QgsStatusBarScaleWidget::updateScales( const QStringList &scales )
void QgsStatusBarScaleWidget::userScale() const
{
// Why has MapCanvas the scale inverted?
mMapCanvas->zoomScale( 1.0 / mScale->scale() );
mMapCanvas->zoomScale( mScale->scale() );
}

View File

@ -411,7 +411,7 @@ void QgsVectorLayerProperties::syncToLayer()
mDisplayExpressionWidget->setField( mLayer->displayExpression() );
// set up the scale based layer visibility stuff....
mScaleRangeWidget->setScaleRange( 1.0 / mLayer->minimumScale(), 1.0 / mLayer->maximumScale() ); // caution: layer uses scale denoms, widget uses true scales
mScaleRangeWidget->setScaleRange( mLayer->minimumScale(), mLayer->maximumScale() );
mScaleVisibilityGroupBox->setChecked( mLayer->hasScaleBasedVisibility() );
mScaleRangeWidget->setMapCanvas( QgisApp::instance()->mapCanvas() );
@ -456,7 +456,7 @@ void QgsVectorLayerProperties::syncToLayer()
QStringList myScalesList = PROJECT_SCALES.split( ',' );
myScalesList.append( QStringLiteral( "1:1" ) );
mSimplifyMaximumScaleComboBox->updateScales( myScalesList );
mSimplifyMaximumScaleComboBox->setScale( 1.0 / simplifyMethod.maximumScale() );
mSimplifyMaximumScaleComboBox->setScale( simplifyMethod.maximumScale() );
mForceRasterCheckBox->setChecked( mLayer->renderer() && mLayer->renderer()->forceRasterRender() );
@ -509,9 +509,8 @@ void QgsVectorLayerProperties::apply()
// set up the scale based layer visibility stuff....
mLayer->setScaleBasedVisibility( mScaleVisibilityGroupBox->isChecked() );
// caution: layer uses scale denoms, widget uses true scales
mLayer->setMinimumScale( mScaleRangeWidget->maximumScaleDenom() );
mLayer->setMaximumScale( mScaleRangeWidget->minimumScaleDenom() );
mLayer->setMaximumScale( mScaleRangeWidget->maximumScale() );
mLayer->setMinimumScale( mScaleRangeWidget->minimumScale() );
// provider-specific options
if ( mLayer->dataProvider() )
@ -634,7 +633,7 @@ void QgsVectorLayerProperties::apply()
simplifyMethod.setSimplifyAlgorithm( static_cast< QgsVectorSimplifyMethod::SimplifyAlgorithm >( mSimplifyAlgorithmComboBox->currentData().toInt() ) );
simplifyMethod.setThreshold( mSimplifyDrawingSpinBox->value() );
simplifyMethod.setForceLocalOptimization( !mSimplifyDrawingAtProvider->isChecked() );
simplifyMethod.setMaximumScale( 1.0 / mSimplifyMaximumScaleComboBox->scale() );
simplifyMethod.setMaximumScale( mSimplifyMaximumScaleComboBox->scale() );
mLayer->setSimplifyMethod( simplifyMethod );
if ( mLayer->renderer() )

View File

@ -26,8 +26,6 @@
QgsScaleComboBox::QgsScaleComboBox( QWidget *parent )
: QComboBox( parent )
, mScale( 1.0 )
, mMinScale( 0.0 )
{
updateScales();
@ -71,7 +69,7 @@ void QgsScaleComboBox::updateScales( const QStringList &scales )
denominator = QLocale::system().toDouble( parts[1], &ok );
if ( ok )
{
myScalesList[ i ] = toString( 1.0 / denominator );
myScalesList[ i ] = toString( denominator );
}
}
@ -114,17 +112,17 @@ void QgsScaleComboBox::showPopup()
view()->setMinimumWidth( view()->sizeHintForColumn( 0 ) );
}
QString QgsScaleComboBox::scaleString()
QString QgsScaleComboBox::scaleString() const
{
return toString( mScale );
}
bool QgsScaleComboBox::setScaleString( const QString &scaleTxt )
bool QgsScaleComboBox::setScaleString( const QString &string )
{
bool ok;
double newScale = toDouble( scaleTxt, &ok );
double newScale = toDouble( string, &ok );
double oldScale = mScale;
if ( newScale < mMinScale && newScale != 0 )
if ( newScale > mMinScale && newScale != 0 && mMinScale != 0 )
{
newScale = mMinScale;
}
@ -167,7 +165,7 @@ void QgsScaleComboBox::fixupScale()
if ( ok )
{
// if a user types scale = 2345, we transform to 1:2345
if ( userSetScale && newScale >= 1.0 )
if ( userSetScale && newScale < 1.0 && !qgsDoubleNear( newScale, 0.0 ) )
{
newScale = 1 / newScale;
}
@ -185,13 +183,13 @@ QString QgsScaleComboBox::toString( double scale )
{
return QStringLiteral( "0" );
}
else if ( scale > 1 )
else if ( scale <= 1 )
{
return QStringLiteral( "%1:1" ).arg( QLocale::system().toString( qRound( scale ) ) );
return QStringLiteral( "%1:1" ).arg( QLocale::system().toString( qRound( 1.0 / scale ) ) );
}
else
{
return QStringLiteral( "1:%1" ).arg( QLocale::system().toString( qRound( 1.0 / scale ) ) );
return QStringLiteral( "1:%1" ).arg( QLocale::system().toString( qRound( scale ) ) );
}
}
@ -200,7 +198,8 @@ double QgsScaleComboBox::toDouble( const QString &scaleString, bool *returnOk )
bool ok = false;
QString scaleTxt( scaleString );
double scale = qgsPermissiveToDouble( scaleTxt, ok );
double denominator = qgsPermissiveToDouble( scaleTxt, ok );
double scale = !qgsDoubleNear( denominator, 0.0 ) ? 1.0 / denominator : 0.0;
if ( ok )
{
// Create a text version and set that text and rescan
@ -217,10 +216,10 @@ double QgsScaleComboBox::toDouble( const QString &scaleString, bool *returnOk )
bool okY = false;
int x = qgsPermissiveToInt( txtList[ 0 ], okX );
int y = qgsPermissiveToInt( txtList[ 1 ], okY );
if ( okX && okY )
if ( okX && okY && x != 0 )
{
// Scale is fraction of x and y
scale = ( double )x / ( double )y;
scale = static_cast< double >( y ) / static_cast< double >( x );
ok = true;
}
}
@ -237,8 +236,8 @@ double QgsScaleComboBox::toDouble( const QString &scaleString, bool *returnOk )
void QgsScaleComboBox::setMinScale( double scale )
{
mMinScale = scale;
if ( mScale < scale && mScale != 0 )
if ( mScale > mMinScale && mScale != 0 && mMinScale != 0 )
{
setScale( scale );
setScale( mMinScale );
}
}

View File

@ -29,38 +29,87 @@
class GUI_EXPORT QgsScaleComboBox : public QComboBox
{
Q_OBJECT
Q_PROPERTY( double scale READ scale WRITE setScale NOTIFY scaleChanged )
Q_PROPERTY( double minScale READ minScale WRITE setMinScale )
public:
/**
* Constructor for QgsScaleComboBox.
*/
QgsScaleComboBox( QWidget *parent SIP_TRANSFERTHIS = nullptr );
//! Function to read the selected scale as text
QString scaleString();
//! Function to set the selected scale from text
bool setScaleString( const QString &scaleTxt );
//! Function to read the selected scale as double
/**
* Returns the selected scale as a string, e.g. "1:150".
* \see setScaleString()
*/
QString scaleString() const;
/**
* Set the selected scale from a \a string, e.g. "1:150".
* \see scaleString()
*/
bool setScaleString( const QString &string );
/**
* Returns the selected scale as a double.
* The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
* \see setScale()
*/
double scale() const;
//! Function to set the selected scale from double
void setScale( double scale );
//! Function to read the min scale
/**
* Returns the minimum scale, or 0 if no minimum scale set.
* The \a scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
* Any scale lower than the minimum scale will automatically be converted to the minimum scale.
* Except for 0 which is always allowed.
*/
double minScale() const { return mMinScale; }
//! Helper function to convert a double to scale string
// Performs rounding, so an exact representation is not to
// be expected.
/**
* Helper function to convert a \a scale double to scale string.
* The \a scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
*
* The returned string will be rounded (e.g. 1:1000, not 1:1000.345).
* \see toDouble()
*/
static QString toString( double scale );
//! Helper function to convert a scale string to double
static double toDouble( const QString &scaleString, bool *ok = nullptr );
/**
* Helper function to convert a scale \a string to double.
* The returned value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
* If specified, \a ok will be set to true if the string was successfully interpreted as a scale.
* \see toString()
*/
static double toDouble( const QString &string, bool *ok = nullptr );
signals:
//! Signal is emitted when *user* has finished editing/selecting a new scale.
/**
* Emitted when *user* has finished editing/selecting a new scale.
* The \a scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
*/
void scaleChanged( double scale );
public slots:
/**
* Sets the list of predefined \a scales to show in the combobox. List elements
* are expected to be valid scale strings, such as "1:1000000".
*/
void updateScales( const QStringList &scales = QStringList() );
/**
* Set the minimum allowed scale.
* Anything scale lower than the minimum scale will automatically
* be converted to the minimum scale.
* Set the selected scale from a double.
* The \a scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
* \see scale()
*/
void setScale( double scale );
/**
* Set the minimum allowed \a scale. Set to 0 to disable the minimum scale.
* The \a scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
* Any scale lower than the minimum scale will automatically be converted to the minimum scale.
* Except for 0 which is always allowed.
*/
void setMinScale( double scale );
@ -72,8 +121,8 @@ class GUI_EXPORT QgsScaleComboBox : public QComboBox
void fixupScale();
private:
double mScale;
double mMinScale;
double mScale = 1.0;
double mMinScale = 0.0;
};
#endif // QGSSCALECOMBOBOX_H

View File

@ -48,8 +48,8 @@ QgsScaleRangeWidget::QgsScaleRangeWidget( QWidget *parent )
mMaximumScaleWidget->setShowCurrentScaleButton( true );
reloadProjectScales();
// add start, add comprehension of scales by settings fake ordered values
mMinimumScaleWidget->setScale( 1.0 / 100000 );
mMaximumScaleWidget->setScale( 1.0 / 1000 );
mMinimumScaleWidget->setScale( 100000 );
mMaximumScaleWidget->setScale( 1000 );
mLayout->addWidget( minLbl, 0, 0, 1, 2 );
mLayout->addWidget( mMinimumScaleIconLabel, 1, 0 );
@ -86,46 +86,24 @@ void QgsScaleRangeWidget::setMapCanvas( QgsMapCanvas *mapCanvas )
void QgsScaleRangeWidget::setMinimumScale( double scale )
{
if ( qIsInf( scale ) )
scale = 0;
mMinimumScaleWidget->setScale( scale );
}
double QgsScaleRangeWidget::minimumScale()
double QgsScaleRangeWidget::minimumScale() const
{
return mMinimumScaleWidget->scale();
}
void QgsScaleRangeWidget::setMaximumScale( double scale )
{
if ( qIsInf( scale ) )
scale = 0;
mMaximumScaleWidget->setScale( scale );
}
double QgsScaleRangeWidget::maximumScale()
double QgsScaleRangeWidget::maximumScale() const
{
return mMaximumScaleWidget->scale();
}
double QgsScaleRangeWidget::minimumScaleDenom()
{
double scale = maximumScale();
if ( scale == 0 )
return 0;
else
return qRound( 1.0 / scale );
}
double QgsScaleRangeWidget::maximumScaleDenom()
{
double scale = minimumScale();
if ( scale == 0 )
return 0;
else
return qRound( 1.0 / scale );
}
void QgsScaleRangeWidget::setScaleRange( double min, double max )
{
setMinimumScale( min );

View File

@ -24,64 +24,86 @@
class QgsMapCanvas;
class QgsScaleWidget;
/** \ingroup gui
/**
* \ingroup gui
* \class QgsScaleRangeWidget
* A widget allowing entry of a range of map scales, e.g. minimum scale and maximum scale.
*/
class GUI_EXPORT QgsScaleRangeWidget : public QWidget
{
Q_OBJECT
Q_PROPERTY( double minimumScale READ minimumScale WRITE setMinimumScale )
Q_PROPERTY( double maximumScale READ maximumScale WRITE setMaximumScale )
public:
/**
* Constructor for QgsScaleRangeWidget.
*/
explicit QgsScaleRangeWidget( QWidget *parent SIP_TRANSFERTHIS = 0 );
//! set the map canvas which will be used for the current scale buttons
/**
* Sets the map \a canvas which will be used for the current scale buttons.
* If not set, the buttons are hidden.
*/
void setMapCanvas( QgsMapCanvas *canvas );
/**
* \brief setMapCanvas set the map canvas which will be used for the current scale buttons
* if not set, the buttons are hidden.
* Returns the selected minimum scale, or 0 if minimum scale is not set.
* The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
* \see maximumScale()
* \see setMinimumScale()
*/
void setMapCanvas( QgsMapCanvas *mapCanvas );
//! return the minimum scale
double minimumScale();
//! return the maximum scale
double maximumScale();
double minimumScale() const;
/**
* Returns the minimum scale denominator ( = 1 / maximum scale )
* In case of maximum scale = 0 it will also return 0
* Returns the selected maximum scale, or 0 if maximum scale is not set.
* The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
* \see minimumScale()
* \see setMaximumScale()
*/
double minimumScaleDenom();
double maximumScale() const;
/**
* Returns the maximum scale denominator ( = 1 / minimum scale )
* In case of minimum scale = 0 it will also return 0
* Call to reload the preset scales from the current project and apply them to the 2 scales combo boxes.
*/
double maximumScaleDenom();
//! call to reload the project scales and apply them to the 2 scales combo boxes
void reloadProjectScales();
public slots:
/**
* Set the minimum scale. Infinite will be handled equally to 0 internally.
* Set the minimum \a scale, or 0 to indicate the minimum is not set.
* The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
* \see minimumScale()
* \see setMaximumScale()
* \see setScaleRange()
*/
void setMinimumScale( double scale );
/**
* Set the maximum scale. Infinite will be handled equally to 0 internally.
* Set the maximum \a scale, or 0 to indicate the minimum is not set.
* The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
* \see maximumScale()
* \see setMinimumScale()
* \see setScaleRange()
*/
void setMaximumScale( double scale );
/**
* Sets the scale range, from \a min scale to \a max scale.
* The scale values indicates the scale denominator, e.g. 1000.0 for a 1:1000 map,
* or 0 to indicate not set.
* \see setMinimumScale()
* \see setMaximumScale()
*/
void setScaleRange( double min, double max );
signals:
/** Emitted when the scale range set in the widget is changed.
* \param min minimum scale
* \param max maximum scale
/**
* Emitted when the scale range set in the widget is changed.
* The scale values indicates the scale denominator, e.g. 1000.0 for a 1:1000 map,
* or 0 to indicate not set.
* \since QGIS 2.16
*/
void rangeChanged( double min, double max );

View File

@ -59,7 +59,7 @@ void QgsScaleVisibilityDialog::setScaleVisiblity( bool hasScaleVisibility )
mGroupBox->setChecked( hasScaleVisibility );
}
bool QgsScaleVisibilityDialog::hasScaleVisibility()
bool QgsScaleVisibilityDialog::hasScaleVisibility() const
{
return mGroupBox->isChecked();
}
@ -69,7 +69,7 @@ void QgsScaleVisibilityDialog::setMinimumScale( double minScale )
mScaleWidget->setMinimumScale( minScale );
}
double QgsScaleVisibilityDialog::minimumScale()
double QgsScaleVisibilityDialog::minimumScale() const
{
return mScaleWidget->minimumScale();
}
@ -79,7 +79,7 @@ void QgsScaleVisibilityDialog::setMaximumScale( double maxScale )
mScaleWidget->setMaximumScale( maxScale );
}
double QgsScaleVisibilityDialog::maximumScale()
double QgsScaleVisibilityDialog::maximumScale() const
{
return mScaleWidget->maximumScale();
}

View File

@ -26,33 +26,68 @@ class QgsScaleRangeWidget;
/** \ingroup gui
* \class QgsScaleVisibilityDialog
* A dialog allowing users to enter a scale visibility range.
*/
class GUI_EXPORT QgsScaleVisibilityDialog : public QDialog
{
Q_OBJECT
Q_PROPERTY( bool hasScaleVisibility READ hasScaleVisibility WRITE setScaleVisiblity )
Q_PROPERTY( double minimumScale READ minimumScale WRITE setMinimumScale )
Q_PROPERTY( double maximumScale READ maximumScale WRITE setMaximumScale )
public:
/**
* Constructor for QgsScaleVisibilityDialog, with specified dialog \a title. The \a mapCanvas argument
* can be used to associate the dialog with a map canvas, allowing use of the current map scale
* within the dialog.
*/
explicit QgsScaleVisibilityDialog( QWidget *parent SIP_TRANSFERTHIS = 0, const QString &title = QString(), QgsMapCanvas *mapCanvas = nullptr );
//! return if scale visibilty is enabled
bool hasScaleVisibility();
/**
* Return true if scale based visibilty is enabled.
*/
bool hasScaleVisibility() const;
//! return minimum scale (true scale, not scale denominator)
double minimumScale();
//! return maximum scale (true scale, not scale denominator)
double maximumScale();
/**
* Returns the selected minimum scale, or 0 if minimum scale is not set.
* The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
* \see maximumScale()
* \see setMinimumScale()
*/
double minimumScale() const;
/**
* Returns the selected maximum scale, or 0 if maximum scale is not set.
* The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
* \see minimumScale()
* \see setMaximumScale())
*/
double maximumScale() const;
public slots:
//! set if scale visibility is enabled
/**
* Set whether scale based visibility is enabled.
* \see hasScaleVisibility()
*/
void setScaleVisiblity( bool hasScaleVisibility );
//! set minimum scale (true scale, not scale denominator)
void setMinimumScale( double minScale );
/**
* Set the minimum \a scale, or 0 to indicate the minimum is not set.
* The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
* \see minimumScale()
* \see setMaximumScale()
*/
void setMinimumScale( double scale );
//! set maximum scale (true scale, not scale denominator)
void setMaximumScale( double maxScale );
/**
* Set the maximum \a scale, or 0 to indicate the minimum is not set.
* The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
* \see maximumScale()
* \see setMinimumScale()
*/
void setMaximumScale( double scale );
private:

View File

@ -58,7 +58,7 @@ void QgsScaleWidget::setScaleFromCanvas()
if ( !mCanvas )
return;
setScale( 1 / mCanvas->scale() );
setScale( mCanvas->scale() );
}
void QgsScaleWidget::setScale( double scale )

View File

@ -45,45 +45,104 @@ class GUI_EXPORT QgsScaleWidget : public QWidget
**/
explicit QgsScaleWidget( QWidget *parent SIP_TRANSFERTHIS = nullptr );
//! shows a button to set the scale to the current scale of the map canvas next to the combobox
//! \note the map canvas must be defined to show the button
/**
* Sets whether to show a button to set the scale to the current scale of the map canvas next to the combobox.
* \note the map canvas must be defined to show the button
* \see showCurrentScaleButton()
* \see setMapCanvas()
*/
void setShowCurrentScaleButton( bool showCurrentScaleButton );
//! returns if a button to set the scale from map canvas is shown or not
/**
* Returns whether a button to set the scale from map canvas is shown or not.
* \see setShowCurrentScaleButton()
*/
bool showCurrentScaleButton() { return mShowCurrentScaleButton;}
//! set the map canvas associated to the current button
/**
* Set the map \a canvas associated to the current button.
*/
void setMapCanvas( QgsMapCanvas *canvas );
//! Function to read the selected scale as text
QString scaleString() { return mScaleComboBox->scaleString(); }
//! Function to set the selected scale from text
bool setScaleString( const QString &scaleTxt ) { return mScaleComboBox->setScaleString( scaleTxt ); }
//! Function to read the selected scale as double
double scale() const { return mScaleComboBox->scale();}
//! Function to set the selected scale from double
void setScale( double scale );
//! Function to read the min scale
/**
* Returns the selected scale as a string, e.g. "1:150".
* \see setScaleString()
*/
QString scaleString() const { return mScaleComboBox->scaleString(); }
/**
* Set the selected scale from a \a string, e.g. "1:150".
* \see scaleString()
*/
bool setScaleString( const QString &string ) { return mScaleComboBox->setScaleString( string ); }
/**
* Returns the selected scale as a double.
* The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
* \see setScale()
*/
double scale() const { return mScaleComboBox->scale(); }
/**
* Returns the minimum scale, or 0 if no minimum scale set.
* The \a scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
* Any scale lower than the minimum scale will automatically be converted to the minimum scale.
* Except for 0 which is always allowed.
*/
double minScale() const { return mScaleComboBox->minScale(); }
//! Helper function to convert a double to scale string
// Performs rounding, so an exact representation is not to
// be expected.
/**
* Helper function to convert a \a scale double to scale string.
* The \a scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
*
* The returned string will be rounded (e.g. 1:1000, not 1:1000.345).
* \see toDouble()
*/
static QString toString( double scale ) { return QgsScaleComboBox::toString( scale ); }
//! Helper function to convert a scale string to double
/**
* Helper function to convert a scale \a string to double.
* The returned value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
* If specified, \a ok will be set to true if the string was successfully interpreted as a scale.
* \see toString()
*/
static double toDouble( const QString &scaleString, bool *ok = nullptr ) { return QgsScaleComboBox::toDouble( scaleString, ok ); }
public slots:
//! updates the list of predefined scales
/**
* Set the selected scale from a double.
* The \a scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
* \see scale()
*/
void setScale( double scale );
/**
* Sets the list of predefined \a scales to show in the combobox. List elements
* are expected to be valid scale strings, such as "1:1000000".
*/
void updateScales( const QStringList &scales = QStringList() ) { return mScaleComboBox->updateScales( scales ); }
//! assign the current scale from the map canvas
/**
* Assigns the current scale from the map canvas, if set.
* \see setMapCanvas()
*/
void setScaleFromCanvas();
//! Function to set the min scale
/**
* Set the minimum allowed \a scale. Set to 0 to disable the minimum scale.
* The \a scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
* Any scale lower than the minimum scale will automatically be converted to the minimum scale.
* Except for 0 which is always allowed.
*/
void setMinScale( double scale ) { mScaleComboBox->setMinScale( scale ); }
signals:
//! Signal is emitted when *user* has finished editing/selecting a new scale.
/**
* Emitted when *user* has finished editing/selecting a new scale.
* The \a scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
*/
void scaleChanged( double scale );
private:

View File

@ -482,7 +482,7 @@ void QgsTextFormatWidget::initWidget()
if ( mMapCanvas )
{
lblFontPreview->setMapUnits( mMapCanvas->mapSettings().mapUnits() );
mPreviewScaleComboBox->setScale( 1.0 / mMapCanvas->mapSettings().scale() );
mPreviewScaleComboBox->setScale( mMapCanvas->mapSettings().scale() );
}
}
@ -1227,7 +1227,7 @@ void QgsTextFormatWidget::onSubstitutionsChanged( const QgsStringReplacementColl
void QgsTextFormatWidget::previewScaleChanged( double scale )
{
lblFontPreview->setScale( scale );
lblFontPreview->setScale( 1.0 / scale );
}
void QgsTextFormatWidget::updateSvgWidgets( const QString &svgPath )

View File

@ -24,7 +24,7 @@ QgsMapUnitScaleWidget::QgsMapUnitScaleWidget( QWidget *parent )
, mBlockSignals( true )
{
setupUi( this );
mComboBoxMinScale->setScale( 0.0000001 );
mComboBoxMinScale->setScale( 10000000.0 );
mComboBoxMaxScale->setScale( 1 );
mSpinBoxMinSize->setShowClearButton( false );
mSpinBoxMaxSize->setShowClearButton( false );
@ -54,10 +54,10 @@ void QgsMapUnitScaleWidget::setMapUnitScale( const QgsMapUnitScale &scale )
// can't block signals on the widgets themselves, some use them to update
// internal states
mBlockSignals = true;
mComboBoxMinScale->setScale( scale.minScale > 0.0 ? scale.minScale : 0.0000001 );
mComboBoxMinScale->setScale( 1.0 / ( scale.minScale > 0.0 ? scale.minScale : 0.0000001 ) );
mCheckBoxMinScale->setChecked( scale.minScale > 0.0 );
mComboBoxMinScale->setEnabled( scale.minScale > 0.0 );
mComboBoxMaxScale->setScale( scale.maxScale > 0.0 ? scale.maxScale : 1.0 );
mComboBoxMaxScale->setScale( 1.0 / ( scale.maxScale > 0.0 ? scale.maxScale : 1.0 ) );
mCheckBoxMaxScale->setChecked( scale.maxScale > 0.0 );
mComboBoxMaxScale->setEnabled( scale.maxScale > 0.0 );
@ -84,7 +84,7 @@ void QgsMapUnitScaleWidget::setMapCanvas( QgsMapCanvas *canvas )
void QgsMapUnitScaleWidget::configureMinComboBox()
{
mComboBoxMinScale->setEnabled( mCheckBoxMinScale->isChecked() );
if ( mCheckBoxMinScale->isChecked() && mComboBoxMinScale->scale() > mComboBoxMaxScale->scale() )
if ( mCheckBoxMinScale->isChecked() && mComboBoxMinScale->scale() < mComboBoxMaxScale->scale() )
{
mComboBoxMinScale->setScale( mComboBoxMaxScale->scale() );
}
@ -93,7 +93,7 @@ void QgsMapUnitScaleWidget::configureMinComboBox()
void QgsMapUnitScaleWidget::configureMaxComboBox()
{
mComboBoxMaxScale->setEnabled( mCheckBoxMaxScale->isChecked() );
if ( mCheckBoxMaxScale->isChecked() && mComboBoxMaxScale->scale() < mComboBoxMinScale->scale() )
if ( mCheckBoxMaxScale->isChecked() && mComboBoxMaxScale->scale() > mComboBoxMinScale->scale() )
{
mComboBoxMaxScale->setScale( mComboBoxMinScale->scale() );
}
@ -110,8 +110,8 @@ void QgsMapUnitScaleWidget::settingsChanged()
QgsMapUnitScale QgsMapUnitScaleWidget::mapUnitScale() const
{
QgsMapUnitScale scale;
scale.minScale = mCheckBoxMinScale->isChecked() ? mComboBoxMinScale->scale() : 0;
scale.maxScale = mCheckBoxMaxScale->isChecked() ? mComboBoxMaxScale->scale() : 0;
scale.minScale = mCheckBoxMinScale->isChecked() ? 1.0 / mComboBoxMinScale->scale() : 0;
scale.maxScale = mCheckBoxMaxScale->isChecked() ? 1.0 / mComboBoxMaxScale->scale() : 0;
scale.minSizeMMEnabled = mCheckBoxMinSize->isChecked();
scale.minSizeMM = mSpinBoxMinSize->value();
scale.maxSizeMMEnabled = mCheckBoxMaxSize->isChecked();

View File

@ -623,9 +623,9 @@ QgsRendererRulePropsWidget::QgsRendererRulePropsWidget( QgsRuleBasedRenderer::Ru
groupScale->setChecked( true );
// caution: rule uses scale denom, scale widget uses true scales
if ( rule->scaleMinDenom() > 0 )
mScaleRangeWidget->setMaximumScale( 1.0 / rule->scaleMinDenom() );
mScaleRangeWidget->setMaximumScale( rule->scaleMinDenom() );
if ( rule->scaleMaxDenom() > 0 )
mScaleRangeWidget->setMinimumScale( 1.0 / rule->scaleMaxDenom() );
mScaleRangeWidget->setMinimumScale( rule->scaleMaxDenom() );
}
mScaleRangeWidget->setMapCanvas( mContext.mapCanvas() );
@ -770,8 +770,8 @@ void QgsRendererRulePropsWidget::apply()
mRule->setLabel( editLabel->text() );
mRule->setDescription( editDescription->text() );
// caution: rule uses scale denom, scale widget uses true scales
mRule->setScaleMinDenom( groupScale->isChecked() ? mScaleRangeWidget->minimumScaleDenom() : 0 );
mRule->setScaleMaxDenom( groupScale->isChecked() ? mScaleRangeWidget->maximumScaleDenom() : 0 );
mRule->setScaleMinDenom( groupScale->isChecked() ? mScaleRangeWidget->minimumScale() : 0 );
mRule->setScaleMaxDenom( groupScale->isChecked() ? mScaleRangeWidget->maximumScale() : 0 );
mRule->setSymbol( groupSymbol->isChecked() ? mSymbol->clone() : nullptr );
}

View File

@ -40,6 +40,9 @@ class TestQgsScaleComboBox : public QObject
void basic();
void slot_test();
void min_test();
void toString();
void toDouble();
private:
void enterScale( const QString &scale );
void enterScale( double scale );
@ -70,23 +73,23 @@ void TestQgsScaleComboBox::basic()
// Testing conversion from "1:nnn".
enterScale( QStringLiteral( "1:2345" ) );
QCOMPARE( s->scaleString(), QString( "1:%1" ).arg( QLocale::system().toString( 2345 ) ) );
QCOMPARE( s->scale(), 1.0 / 2345.0 );
QCOMPARE( s->scale(), 2345.0 );
// Testing conversion from number to "1:x"
enterScale( 0.02 );
QCOMPARE( s->scaleString(), QString( "1:%1" ).arg( QLocale::system().toString( 50 ) ) );
QCOMPARE( s->scale(), 0.02 );
QCOMPARE( s->scale(), 1.0 / 0.02 );
// Testing conversion from number to "1:x"
enterScale( 42 );
QCOMPARE( s->scaleString(), QString( "1:%1" ).arg( QLocale::system().toString( 42 ) ) );
QCOMPARE( s->scale(), 1.0 / 42.0 );
QCOMPARE( s->scale(), 42.0 );
// Testing conversion from number to "1:x,000"
QString str = QStringLiteral( "1%01000%01000" ).arg( QLocale::system().groupSeparator() );
enterScale( str );
QCOMPARE( s->scaleString(), QString( "1:%1" ).arg( str ) );
QCOMPARE( s->scale(), 1.0 / 1000000.0 );
QCOMPARE( s->scale(), 1000000.0 );
// Testing conversion from number to "1:x,000" with wonky separators
//(e.g., four digits between thousands, which should be fixed automatically)
@ -94,7 +97,7 @@ void TestQgsScaleComboBox::basic()
QString fixedStr = QStringLiteral( "10%01000%01000" ).arg( QLocale::system().groupSeparator() );
enterScale( str );
QCOMPARE( s->scaleString(), QString( "1:%1" ).arg( fixedStr ) );
QCOMPARE( s->scale(), 1.0 / 10000000.0 );
QCOMPARE( s->scale(), 10000000.0 );
// Testing rounding and conversion from illegal
@ -102,22 +105,22 @@ void TestQgsScaleComboBox::basic()
enterScale( QStringLiteral( "1:x:2" ) );
QCOMPARE( s->scaleString(), QString( "1:%1" ).arg( QLocale::system().toString( 4 ) ) );
QCOMPARE( s->scale(), 0.25 );
QCOMPARE( s->scale(), 4.0 );
// Test setting programmatically
s->setScale( 0.19 );
s->setScale( 1.0 / 0.19 );
QCOMPARE( s->scaleString(), QString( "1:%1" ).arg( QLocale::system().toString( 5 ) ) );
QCOMPARE( s->scale(), 0.2 );
QCOMPARE( s->scale(), 5.0 );
// Test setting programmatically
s->setScaleString( QStringLiteral( "1:240" ) );
QCOMPARE( s->scaleString(), QString( "1:%1" ).arg( QLocale::system().toString( 240 ) ) );
QCOMPARE( s->scale(), 1.0 / 240.0 );
QCOMPARE( s->scale(), 240.0 );
// Test setting programmatically illegal string
s->setScaleString( QStringLiteral( "1:2" ) + QLocale::system().decimalPoint() + "4" );
QCOMPARE( s->scaleString(), QString( "1:%1" ).arg( QLocale::system().toString( 240 ) ) );
QCOMPARE( s->scale(), 1.0 / 240.0 );
QCOMPARE( s->scale(), 240.0 );
}
@ -135,19 +138,54 @@ void TestQgsScaleComboBox::slot_test()
void TestQgsScaleComboBox::min_test()
{
s->setMinScale( 0.01 );
s->setMinScale( 100.0 );
enterScale( 0.02 );
QCOMPARE( s->scale(), 0.02 );
QCOMPARE( s->scale(), 1.0 / 0.02 );
enterScale( 0.002 );
QCOMPARE( s->scale(), 0.01 );
QCOMPARE( s->scale(), 100.0 );
s->setMinScale( 0.015 );
QCOMPARE( s->scale(), 0.015 );
s->setMinScale( 1.0 / 0.015 );
QCOMPARE( s->scale(), 1.0 / 0.015 );
s->setScale( 0.5 );
QCOMPARE( s->scale(), 0.5 );
s->setScale( 2.0 );
QCOMPARE( s->scale(), 2.0 );
}
void TestQgsScaleComboBox::toString()
{
QCOMPARE( QgsScaleComboBox::toString( 100 ), QStringLiteral( "1:100" ) );
QCOMPARE( QgsScaleComboBox::toString( 100.02134234 ), QStringLiteral( "1:100" ) );
QCOMPARE( QgsScaleComboBox::toString( 1 ), QStringLiteral( "1:1" ) );
QCOMPARE( QgsScaleComboBox::toString( 1.0 / 100 ), QStringLiteral( "100:1" ) );
}
void TestQgsScaleComboBox::toDouble()
{
bool ok = false;
QCOMPARE( QgsScaleComboBox::toDouble( QStringLiteral( "1:100" ), &ok ), 100.0 );
QVERIFY( ok );
QCOMPARE( QgsScaleComboBox::toDouble( QStringLiteral( "1:1" ), &ok ), 1.0 );
QVERIFY( ok );
QCOMPARE( QgsScaleComboBox::toDouble( QStringLiteral( "100:1" ), &ok ), 1.0 / 100 );
QVERIFY( ok );
QCOMPARE( QgsScaleComboBox::toDouble( QStringLiteral( "0.01" ), &ok ), 100.0 );
QVERIFY( ok );
QCOMPARE( QgsScaleComboBox::toDouble( QStringLiteral( "100" ), &ok ), 1.0 / 100.0 );
QVERIFY( ok );
//bad
QgsScaleComboBox::toDouble( QStringLiteral( "abc" ), &ok );
QVERIFY( !ok );
QgsScaleComboBox::toDouble( QStringLiteral( "" ), &ok );
QVERIFY( !ok );
QgsScaleComboBox::toDouble( QStringLiteral( "1:" ), &ok );
QVERIFY( !ok );
QgsScaleComboBox::toDouble( QStringLiteral( "1:a" ), &ok );
QVERIFY( !ok );
QgsScaleComboBox::toDouble( QStringLiteral( "a:1" ), &ok );
QVERIFY( !ok );
}
void TestQgsScaleComboBox::enterScale( const QString &scale )