QGIS/src/gui/symbology-ng/qgspointdisplacementrendererwidget.cpp

345 lines
10 KiB
C++

/***************************************************************************
qgspointdisplacementrendererwidget.cpp
--------------------------------------
begin : January 26, 2010
copyright : (C) 2010 by Marco Hugentobler
email : marco at hugis dot net
***************************************************************************/
/***************************************************************************
* *
* 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 "qgspointdisplacementrendererwidget.h"
#include "qgspointdisplacementrenderer.h"
#include "qgsrendererv2registry.h"
#include "qgsfield.h"
#include "qgsstylev2.h"
#include "qgssymbolv2selectordialog.h"
#include "qgssymbollayerv2utils.h"
#include "qgsvectorlayer.h"
#include <QColorDialog>
#include <QFontDialog>
QgsRendererV2Widget* QgsPointDisplacementRendererWidget::create( QgsVectorLayer* layer, QgsStyleV2* style, QgsFeatureRendererV2* renderer )
{
return new QgsPointDisplacementRendererWidget( layer, style, renderer );
}
QgsPointDisplacementRendererWidget::QgsPointDisplacementRendererWidget( QgsVectorLayer* layer, QgsStyleV2* style, QgsFeatureRendererV2* renderer )
: QgsRendererV2Widget( layer, style ), mEmbeddedRendererWidget( 0 )
{
if ( !layer )
{
return;
}
//the renderer only applies to point vector layers
if ( layer->wkbType() != QGis::WKBPoint && layer->wkbType() != QGis::WKBPoint25D )
{
//setup blank dialog
mRenderer = 0;
setupBlankUi( layer->name() );
return;
}
setupUi( this );
if ( renderer && renderer->type() == "pointDisplacement" )
{
mRenderer = dynamic_cast<QgsPointDisplacementRenderer*>( renderer->clone() );
}
else
{
mRenderer = new QgsPointDisplacementRenderer();
}
blockAllSignals( true );
//insert attributes into combo box
if ( layer )
{
const QgsFields& layerAttributes = layer->pendingFields();
for ( int idx = 0; idx < layerAttributes.count(); ++idx )
{
mLabelFieldComboBox->addItem( layerAttributes[idx].name() );
}
mLabelFieldComboBox->addItem( tr( "None" ) );
QString currentLabelAttribute = mRenderer->labelAttributeName();
if ( !currentLabelAttribute.isEmpty() )
{
mLabelFieldComboBox->setCurrentIndex( mLabelFieldComboBox->findText( currentLabelAttribute ) );
}
else
{
mLabelFieldComboBox->setCurrentIndex( mLabelFieldComboBox->findText( tr( "None" ) ) );
}
}
//insert possible renderer types
QStringList rendererList = QgsRendererV2Registry::instance()->renderersList();
QStringList::const_iterator it = rendererList.constBegin();
for ( ; it != rendererList.constEnd(); ++it )
{
if ( *it != "pointDisplacement" )
{
QgsRendererV2AbstractMetadata* m = QgsRendererV2Registry::instance()->rendererMetadata( *it );
mRendererComboBox->addItem( m->icon(), m->visibleName(), *it );
}
}
mCircleWidthSpinBox->setValue( mRenderer->circleWidth() );
mCircleColorButton->setColor( mRenderer->circleColor() );
mLabelColorButton->setColor( mRenderer->labelColor() );
mCircleModificationSpinBox->setValue( mRenderer->circleRadiusAddition() );
mDistanceSpinBox->setValue( mRenderer->tolerance() );
//scale dependent labelling
mMaxScaleDenominatorEdit->setText( QString::number( mRenderer->maxLabelScaleDenominator() ) );
mMaxScaleDenominatorEdit->setValidator( new QDoubleValidator( mMaxScaleDenominatorEdit ) );
if ( mRenderer->maxLabelScaleDenominator() > 0 )
{
mScaleDependentLabelsCheckBox->setCheckState( Qt::Checked );
}
else
{
mScaleDependentLabelsCheckBox->setCheckState( Qt::Unchecked );
mMaxScaleDenominatorEdit->setEnabled( false );
}
blockAllSignals( false );
//set the appropriate renderer dialog
if ( mRenderer && mRenderer->embeddedRenderer() )
{
QString rendererName = mRenderer->embeddedRenderer()->type();
int rendererIndex = mRendererComboBox->findData( rendererName );
if ( rendererIndex != -1 )
{
mRendererComboBox->setCurrentIndex( rendererIndex );
on_mRendererComboBox_currentIndexChanged( rendererIndex );
}
}
updateCenterIcon();
}
QgsPointDisplacementRendererWidget::~QgsPointDisplacementRendererWidget()
{
delete mRenderer;
delete mEmbeddedRendererWidget;
}
QgsFeatureRendererV2* QgsPointDisplacementRendererWidget::renderer()
{
if ( mRenderer && mEmbeddedRendererWidget )
{
QgsFeatureRendererV2* embeddedRenderer = mEmbeddedRendererWidget->renderer();
if ( embeddedRenderer )
{
mRenderer->setEmbeddedRenderer( embeddedRenderer->clone() );
}
}
return mRenderer;
}
void QgsPointDisplacementRendererWidget::on_mLabelFieldComboBox_currentIndexChanged( const QString& text )
{
if ( mRenderer )
{
if ( text == tr( "None" ) )
{
mRenderer->setLabelAttributeName( "" );
}
else
{
mRenderer->setLabelAttributeName( text );
}
}
}
void QgsPointDisplacementRendererWidget::on_mRendererComboBox_currentIndexChanged( int index )
{
QString rendererId = mRendererComboBox->itemData( index ).toString();
QgsRendererV2AbstractMetadata* m = QgsRendererV2Registry::instance()->rendererMetadata( rendererId );
if ( m )
{
delete mEmbeddedRendererWidget;
mEmbeddedRendererWidget = m->createRendererWidget( mLayer, mStyle, mRenderer->embeddedRenderer()->clone() );
}
}
void QgsPointDisplacementRendererWidget::on_mRendererSettingsButton_clicked()
{
if ( mEmbeddedRendererWidget )
{
//create a dialog with the embedded widget
#ifdef Q_WS_MAC
QDialog* d = new QDialog( this->window() );
d->setWindowModality( Qt::WindowModal );
#else
QDialog* d = new QDialog();
#endif
QGridLayout* layout = new QGridLayout( d );
mEmbeddedRendererWidget->setParent( d );
QDialogButtonBox* buttonBox = new QDialogButtonBox( d );
buttonBox->addButton( QDialogButtonBox::Ok );
QObject::connect( buttonBox, SIGNAL( accepted() ), d, SLOT( accept() ) );
layout->addWidget( mEmbeddedRendererWidget, 0, 0 );
layout->addWidget( buttonBox, 1, 0 );
d->exec();
mEmbeddedRendererWidget->setParent( 0 );
delete d;
}
}
void QgsPointDisplacementRendererWidget::on_mLabelFontButton_clicked()
{
if ( !mRenderer )
{
return;
}
bool ok;
#if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)
// Native Mac dialog works only for QT Carbon
QFont newFont = QFontDialog::getFont( &ok, mRenderer->labelFont(), 0, tr( "Label Font" ), QFontDialog::DontUseNativeDialog );
#else
QFont newFont = QFontDialog::getFont( &ok, mRenderer->labelFont(), 0, tr( "Label Font" ) );
#endif
if ( ok )
{
mRenderer->setLabelFont( newFont );
}
}
void QgsPointDisplacementRendererWidget::on_mCircleWidthSpinBox_valueChanged( double d )
{
if ( mRenderer )
{
mRenderer->setCircleWidth( d );
}
}
void QgsPointDisplacementRendererWidget::on_mCircleColorButton_colorChanged( const QColor& newColor )
{
if ( !mRenderer )
{
return;
}
mRenderer->setCircleColor( newColor );
}
void QgsPointDisplacementRendererWidget::on_mLabelColorButton_colorChanged( const QColor& newColor )
{
if ( !mRenderer )
{
return;
}
mRenderer->setLabelColor( newColor );
}
void QgsPointDisplacementRendererWidget::on_mCircleModificationSpinBox_valueChanged( double d )
{
if ( !mRenderer )
{
return;
}
mRenderer->setCircleRadiusAddition( d );
}
void QgsPointDisplacementRendererWidget::on_mDistanceSpinBox_valueChanged( double d )
{
if ( mRenderer )
{
mRenderer->setTolerance( d );
}
}
void QgsPointDisplacementRendererWidget::on_mScaleDependentLabelsCheckBox_stateChanged( int state )
{
if ( state == Qt::Unchecked )
{
mMaxScaleDenominatorEdit->setText( "-1" );
mMaxScaleDenominatorEdit->setEnabled( false );
}
else
{
mMaxScaleDenominatorEdit->setEnabled( true );
}
}
void QgsPointDisplacementRendererWidget::on_mMaxScaleDenominatorEdit_textChanged( const QString & text )
{
if ( !mRenderer )
{
return;
}
bool ok;
double scaleDenominator = text.toDouble( &ok );
if ( ok )
{
mRenderer->setMaxLabelScaleDenominator( scaleDenominator );
}
}
void QgsPointDisplacementRendererWidget::blockAllSignals( bool block )
{
mLabelFieldComboBox->blockSignals( block );
mLabelFontButton->blockSignals( block );
mCircleWidthSpinBox->blockSignals( block );
mCircleColorButton->blockSignals( block );
mRendererComboBox->blockSignals( block );
mLabelColorButton->blockSignals( block );
mCircleModificationSpinBox->blockSignals( block );
mScaleDependentLabelsCheckBox->blockSignals( block );
mMaxScaleDenominatorEdit->blockSignals( block );
mCenterSymbolPushButton->blockSignals( block );
mDistanceSpinBox->blockSignals( block );
}
void QgsPointDisplacementRendererWidget::on_mCenterSymbolPushButton_clicked()
{
if ( !mRenderer || !mRenderer->centerSymbol() )
{
return;
}
QgsMarkerSymbolV2* markerSymbol = dynamic_cast<QgsMarkerSymbolV2*>( mRenderer->centerSymbol()->clone() );
QgsSymbolV2SelectorDialog dlg( markerSymbol, QgsStyleV2::defaultStyle(), mLayer, this );
if ( dlg.exec() == QDialog::Rejected )
{
delete markerSymbol;
return;
}
mRenderer->setCenterSymbol( markerSymbol );
updateCenterIcon();
}
void QgsPointDisplacementRendererWidget::updateCenterIcon()
{
QgsMarkerSymbolV2* symbol = mRenderer->centerSymbol();
if ( !symbol )
{
return;
}
QIcon icon = QgsSymbolLayerV2Utils::symbolPreviewIcon( symbol, mCenterSymbolPushButton->iconSize() );
mCenterSymbolPushButton->setIcon( icon );
}
void QgsPointDisplacementRendererWidget::setupBlankUi( const QString& layerName )
{
QGridLayout* layout = new QGridLayout( this );
QLabel* label = new QLabel( tr( "The point displacement renderer only applies to (single) point layers. \n'%1' is not a point layer and cannot be displayed by the point displacement renderer" ).arg( layerName ), this );
layout->addWidget( label );
}