mirror of
https://github.com/qgis/QGIS.git
synced 2025-06-19 00:02:48 -04:00
Allows setting symbols other map item sizes to Map Units in Meters. This allows setting the size always in meters, regardless of what the underlying map units are (e.g. they can be it geographic degrees). The size in meters is calculated based on the current project ellipsoid setting and a projection of the distances in meters at the center of the current map extent.
298 lines
11 KiB
C++
298 lines
11 KiB
C++
/***************************************************************************
|
|
qgsunitselectionwidget.h
|
|
-------------------
|
|
begin : Mar 24, 2014
|
|
copyright : (C) 2014 Sandro Mani
|
|
email : smani@sourcepole.ch
|
|
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#include "qgsunitselectionwidget.h"
|
|
#include <QDialogButtonBox>
|
|
|
|
QgsMapUnitScaleWidget::QgsMapUnitScaleWidget( QWidget *parent )
|
|
: QgsPanelWidget( parent )
|
|
, mBlockSignals( true )
|
|
{
|
|
setupUi( this );
|
|
mComboBoxMinScale->setScale( 10000000.0 );
|
|
mComboBoxMaxScale->setScale( 1 );
|
|
mSpinBoxMinSize->setShowClearButton( false );
|
|
mSpinBoxMaxSize->setShowClearButton( false );
|
|
connect( mCheckBoxMinScale, &QCheckBox::toggled, this, &QgsMapUnitScaleWidget::configureMinComboBox );
|
|
connect( mCheckBoxMaxScale, &QCheckBox::toggled, this, &QgsMapUnitScaleWidget::configureMaxComboBox );
|
|
connect( mComboBoxMinScale, &QgsScaleWidget::scaleChanged, this, &QgsMapUnitScaleWidget::configureMaxComboBox );
|
|
connect( mComboBoxMinScale, &QgsScaleWidget::scaleChanged, mComboBoxMaxScale, &QgsScaleWidget::setMinScale );
|
|
connect( mComboBoxMaxScale, &QgsScaleWidget::scaleChanged, this, &QgsMapUnitScaleWidget::configureMinComboBox );
|
|
|
|
connect( mCheckBoxMinSize, &QCheckBox::toggled, mSpinBoxMinSize, &QgsDoubleSpinBox::setEnabled );
|
|
connect( mCheckBoxMaxSize, &QCheckBox::toggled, mSpinBoxMaxSize, &QgsDoubleSpinBox::setEnabled );
|
|
|
|
// notification of setting changes
|
|
connect( mCheckBoxMinScale, &QCheckBox::toggled, this, &QgsMapUnitScaleWidget::settingsChanged );
|
|
connect( mCheckBoxMaxScale, &QCheckBox::toggled, this, &QgsMapUnitScaleWidget::settingsChanged );
|
|
connect( mComboBoxMinScale, &QgsScaleWidget::scaleChanged, this, &QgsMapUnitScaleWidget::settingsChanged );
|
|
connect( mComboBoxMaxScale, &QgsScaleWidget::scaleChanged, this, &QgsMapUnitScaleWidget::settingsChanged );
|
|
connect( mCheckBoxMinSize, &QCheckBox::toggled, this, &QgsMapUnitScaleWidget::settingsChanged );
|
|
connect( mCheckBoxMaxSize, &QCheckBox::toggled, this, &QgsMapUnitScaleWidget::settingsChanged );
|
|
connect( mSpinBoxMinSize, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsMapUnitScaleWidget::settingsChanged );
|
|
connect( mSpinBoxMaxSize, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsMapUnitScaleWidget::settingsChanged );
|
|
mBlockSignals = false;
|
|
}
|
|
|
|
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 : 10000000 );
|
|
mCheckBoxMinScale->setChecked( scale.minScale != 0.0 );
|
|
mComboBoxMinScale->setEnabled( scale.minScale != 0.0 );
|
|
mComboBoxMaxScale->setScale( scale.maxScale > 0.0 ? scale.maxScale : 1.0 );
|
|
mCheckBoxMaxScale->setChecked( scale.maxScale > 0.0 );
|
|
mComboBoxMaxScale->setEnabled( scale.maxScale > 0.0 );
|
|
|
|
mCheckBoxMinSize->setChecked( scale.minSizeMMEnabled );
|
|
mSpinBoxMinSize->setEnabled( scale.minSizeMMEnabled );
|
|
mSpinBoxMinSize->setValue( scale.minSizeMM );
|
|
|
|
mCheckBoxMaxSize->setChecked( scale.maxSizeMMEnabled );
|
|
mSpinBoxMaxSize->setEnabled( scale.maxSizeMMEnabled );
|
|
mSpinBoxMaxSize->setValue( scale.maxSizeMM );
|
|
mBlockSignals = false;
|
|
|
|
settingsChanged();
|
|
}
|
|
|
|
void QgsMapUnitScaleWidget::setMapCanvas( QgsMapCanvas *canvas )
|
|
{
|
|
mComboBoxMinScale->setMapCanvas( canvas );
|
|
mComboBoxMinScale->setShowCurrentScaleButton( true );
|
|
mComboBoxMaxScale->setMapCanvas( canvas );
|
|
mComboBoxMaxScale->setShowCurrentScaleButton( true );
|
|
}
|
|
|
|
void QgsMapUnitScaleWidget::configureMinComboBox()
|
|
{
|
|
mComboBoxMinScale->setEnabled( mCheckBoxMinScale->isChecked() );
|
|
if ( mCheckBoxMinScale->isChecked() && mComboBoxMinScale->scale() < mComboBoxMaxScale->scale() )
|
|
{
|
|
mComboBoxMinScale->setScale( mComboBoxMaxScale->scale() );
|
|
}
|
|
}
|
|
|
|
void QgsMapUnitScaleWidget::configureMaxComboBox()
|
|
{
|
|
mComboBoxMaxScale->setEnabled( mCheckBoxMaxScale->isChecked() );
|
|
if ( mCheckBoxMaxScale->isChecked() && mComboBoxMaxScale->scale() > mComboBoxMinScale->scale() )
|
|
{
|
|
mComboBoxMaxScale->setScale( mComboBoxMinScale->scale() );
|
|
}
|
|
}
|
|
|
|
void QgsMapUnitScaleWidget::settingsChanged()
|
|
{
|
|
if ( mBlockSignals )
|
|
return;
|
|
|
|
emit mapUnitScaleChanged( mapUnitScale() );
|
|
}
|
|
|
|
QgsMapUnitScale QgsMapUnitScaleWidget::mapUnitScale() const
|
|
{
|
|
QgsMapUnitScale scale;
|
|
scale.minScale = mCheckBoxMinScale->isChecked() ? mComboBoxMinScale->scale() : 0;
|
|
scale.maxScale = mCheckBoxMaxScale->isChecked() ? mComboBoxMaxScale->scale() : 0;
|
|
scale.minSizeMMEnabled = mCheckBoxMinSize->isChecked();
|
|
scale.minSizeMM = mSpinBoxMinSize->value();
|
|
scale.maxSizeMMEnabled = mCheckBoxMaxSize->isChecked();
|
|
scale.maxSizeMM = mSpinBoxMaxSize->value();
|
|
return scale;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QgsUnitSelectionWidget::QgsUnitSelectionWidget( QWidget *parent )
|
|
: QWidget( parent )
|
|
, mCanvas( nullptr )
|
|
{
|
|
mMapUnitIdx = -1;
|
|
|
|
setupUi( this );
|
|
mMapScaleButton->setVisible( false );
|
|
mMapScaleButton->setToolTip( tr( "Adjust scaling range" ) );
|
|
|
|
setFocusPolicy( Qt::StrongFocus );
|
|
setFocusProxy( mUnitCombo );
|
|
|
|
connect( mUnitCombo, static_cast < void ( QComboBox::* )( int ) > ( &QComboBox::currentIndexChanged ), this, &QgsUnitSelectionWidget::toggleUnitRangeButton );
|
|
connect( mMapScaleButton, &QPushButton::clicked, this, &QgsUnitSelectionWidget::showDialog );
|
|
connect( mUnitCombo, static_cast < void ( QComboBox::* )( int ) > ( &QComboBox::currentIndexChanged ), this, &QgsUnitSelectionWidget::changed );
|
|
}
|
|
|
|
void QgsUnitSelectionWidget::setUnits( const QStringList &units, int mapUnitIdx )
|
|
{
|
|
blockSignals( true );
|
|
mUnitCombo->addItems( units );
|
|
mMapUnitIdx = mapUnitIdx;
|
|
blockSignals( false );
|
|
}
|
|
|
|
void QgsUnitSelectionWidget::setUnits( const QgsUnitTypes::RenderUnitList &units )
|
|
{
|
|
blockSignals( true );
|
|
mUnitCombo->clear();
|
|
|
|
//instead of iterating over the units list, we specifically check for presence of unit types
|
|
//to ensure that the widget always keeps the same order for units, regardless of the
|
|
//order specified in the units list
|
|
mMapUnitIdx = -1;
|
|
if ( units.contains( QgsUnitTypes::RenderMillimeters ) )
|
|
{
|
|
mUnitCombo->addItem( tr( "Millimeter" ), QgsUnitTypes::RenderMillimeters );
|
|
}
|
|
if ( units.contains( QgsUnitTypes::RenderPoints ) )
|
|
{
|
|
mUnitCombo->addItem( tr( "Points" ), QgsUnitTypes::RenderPoints );
|
|
}
|
|
if ( units.contains( QgsUnitTypes::RenderPixels ) )
|
|
{
|
|
mUnitCombo->addItem( tr( "Pixels" ), QgsUnitTypes::RenderPixels );
|
|
}
|
|
if ( units.contains( QgsUnitTypes::RenderMetersInMapUnits ) )
|
|
{
|
|
mUnitCombo->addItem( tr( "Meters in Map unit" ), QgsUnitTypes::RenderMetersInMapUnits );
|
|
}
|
|
if ( units.contains( QgsUnitTypes::RenderMapUnits ) )
|
|
{
|
|
mUnitCombo->addItem( tr( "Map unit" ), QgsUnitTypes::RenderMapUnits );
|
|
}
|
|
if ( units.contains( QgsUnitTypes::RenderPercentage ) )
|
|
{
|
|
mUnitCombo->addItem( tr( "Percentage" ), QgsUnitTypes::RenderPercentage );
|
|
}
|
|
if ( units.contains( QgsUnitTypes::RenderInches ) )
|
|
{
|
|
mUnitCombo->addItem( tr( "Inches" ), QgsUnitTypes::RenderInches );
|
|
}
|
|
blockSignals( false );
|
|
}
|
|
|
|
QgsUnitTypes::RenderUnit QgsUnitSelectionWidget::unit() const
|
|
{
|
|
if ( mUnitCombo->count() == 0 )
|
|
return QgsUnitTypes::RenderUnknownUnit;
|
|
|
|
QVariant currentData = mUnitCombo->currentData();
|
|
if ( currentData.isValid() )
|
|
{
|
|
return ( QgsUnitTypes::RenderUnit ) currentData.toInt();
|
|
}
|
|
//unknown
|
|
return QgsUnitTypes::RenderUnknownUnit;
|
|
}
|
|
|
|
void QgsUnitSelectionWidget::setUnit( int unitIndex )
|
|
{
|
|
blockSignals( true );
|
|
mUnitCombo->setCurrentIndex( unitIndex );
|
|
blockSignals( false );
|
|
}
|
|
|
|
void QgsUnitSelectionWidget::setUnit( QgsUnitTypes::RenderUnit unit )
|
|
{
|
|
int idx = mUnitCombo->findData( QVariant( ( int ) unit ) );
|
|
mUnitCombo->setCurrentIndex( idx == -1 ? 0 : idx );
|
|
}
|
|
|
|
void QgsUnitSelectionWidget::setMapCanvas( QgsMapCanvas *canvas )
|
|
{
|
|
mCanvas = canvas;
|
|
}
|
|
|
|
void QgsUnitSelectionWidget::showDialog()
|
|
{
|
|
QgsPanelWidget *panel = QgsPanelWidget::findParentPanel( this );
|
|
if ( panel && panel->dockMode() )
|
|
{
|
|
QgsMapUnitScaleWidget *widget = new QgsMapUnitScaleWidget( panel );
|
|
widget->setPanelTitle( tr( "Adjust scaling range" ) );
|
|
widget->setMapCanvas( mCanvas );
|
|
widget->setMapUnitScale( mMapUnitScale );
|
|
connect( widget, &QgsMapUnitScaleWidget::mapUnitScaleChanged, this, &QgsUnitSelectionWidget::widgetChanged );
|
|
panel->openPanel( widget );
|
|
return;
|
|
}
|
|
|
|
QgsMapUnitScaleDialog dlg( this );
|
|
dlg.setMapUnitScale( mMapUnitScale );
|
|
dlg.setMapCanvas( mCanvas );
|
|
if ( dlg.exec() == QDialog::Accepted )
|
|
{
|
|
if ( mMapUnitScale != dlg.getMapUnitScale() )
|
|
{
|
|
mMapUnitScale = dlg.getMapUnitScale();
|
|
emit changed();
|
|
}
|
|
}
|
|
}
|
|
|
|
void QgsUnitSelectionWidget::toggleUnitRangeButton()
|
|
{
|
|
if ( unit() != QgsUnitTypes::RenderUnknownUnit )
|
|
{
|
|
mMapScaleButton->setVisible( unit() == QgsUnitTypes::RenderMapUnits );
|
|
}
|
|
else
|
|
{
|
|
mMapScaleButton->setVisible( mMapUnitIdx != -1 && mUnitCombo->currentIndex() == mMapUnitIdx );
|
|
}
|
|
}
|
|
|
|
void QgsUnitSelectionWidget::widgetChanged( const QgsMapUnitScale &scale )
|
|
{
|
|
mMapUnitScale = scale;
|
|
emit changed();
|
|
}
|
|
|
|
|
|
QgsMapUnitScaleDialog::QgsMapUnitScaleDialog( QWidget *parent )
|
|
: QDialog( parent )
|
|
, mWidget( nullptr )
|
|
{
|
|
QVBoxLayout *vLayout = new QVBoxLayout();
|
|
mWidget = new QgsMapUnitScaleWidget();
|
|
vLayout->addWidget( mWidget );
|
|
QDialogButtonBox *bbox = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal );
|
|
connect( bbox, &QDialogButtonBox::accepted, this, &QgsMapUnitScaleDialog::accept );
|
|
connect( bbox, &QDialogButtonBox::rejected, this, &QgsMapUnitScaleDialog::reject );
|
|
vLayout->addWidget( bbox );
|
|
setLayout( vLayout );
|
|
}
|
|
|
|
QgsMapUnitScale QgsMapUnitScaleDialog::getMapUnitScale() const
|
|
{
|
|
return mWidget->mapUnitScale();
|
|
}
|
|
|
|
void QgsMapUnitScaleDialog::setMapUnitScale( const QgsMapUnitScale &scale )
|
|
{
|
|
mWidget->setMapUnitScale( scale );
|
|
}
|
|
|
|
void QgsMapUnitScaleDialog::setMapCanvas( QgsMapCanvas *canvas )
|
|
{
|
|
mWidget->setMapCanvas( canvas );
|
|
}
|