File indexing completed on 2024-05-19 15:26:51
0001 /** 0002 * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. 0003 * 0004 * This file is part of the KD Chart library. 0005 * 0006 * This program is free software; you can redistribute it and/or 0007 * modify it under the terms of the GNU General Public License as 0008 * published by the Free Software Foundation; either version 2 of 0009 * the License, or (at your option) any later version. 0010 * 0011 * This program is distributed in the hope that it will be useful, 0012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0014 * GNU General Public License for more details. 0015 * 0016 * You should have received a copy of the GNU General Public License 0017 * along with this program. If not, see <https://www.gnu.org/licenses/>. 0018 */ 0019 0020 #include "datavaluesettings.h" 0021 #include "ui_datavaluesettings.h" 0022 0023 #include <KChartChart> 0024 #include <KChartAbstractCoordinatePlane> 0025 #include <KChartBarDiagram> 0026 #include <KChartTextAttributes> 0027 #include <KChartRelativePosition> 0028 #include <KChartPosition> 0029 #include <KChartDataValueAttributes> 0030 #include <KChartAbstractDiagram> 0031 0032 0033 #include <QDebug> 0034 #include <QPainter> 0035 0036 using namespace KChart; 0037 0038 class DataValueSettings::Private : public QObject 0039 { 0040 Q_OBJECT 0041 public: 0042 Private( KChart::Chart *chart, DataValueSettings *q ); 0043 DataValueSettings *qq; 0044 void init(); 0045 public Q_SLOTS: 0046 void on_scopeOneBarRB_toggled( bool checked ); 0047 void on_scopeBarDatasetSB_valueChanged( int i ); 0048 void on_scopeBarItemSB_valueChanged( int i ); 0049 void on_scopeDatasetRB_toggled( bool checked ); 0050 void on_scopeDatasetSB_valueChanged( int i ); 0051 void on_scopeCommonRB_toggled( bool checked ); 0052 0053 void on_paintValuesCB_toggled( bool checked ); 0054 0055 void on_fontCombo_currentIndexChanged( const QString & text ); 0056 void on_relativeSizeSB_valueChanged( int i ); 0057 void on_minimumSizeSB_valueChanged( int i ); 0058 void on_rotationSB_valueChanged( int i ); 0059 0060 void on_posPosCombo_currentIndexChanged( const QString & text ); 0061 void on_posAlignCombo_currentIndexChanged( const QString & text ); 0062 void on_posPadHoriSB_valueChanged( int i ); 0063 void on_posPadVertSB_valueChanged( int i ); 0064 void on_negPosCombo_currentIndexChanged( const QString & text ); 0065 void on_negAlignCombo_currentIndexChanged( const QString & text ); 0066 void on_negPadHoriSB_valueChanged( int i ); 0067 void on_negPadVertSB_valueChanged( int i ); 0068 0069 void on_labelLE_textEdited( const QString & text ); 0070 void on_prefixLE_textEdited( const QString & text ); 0071 void on_suffixLE_textEdited( const QString & text ); 0072 public: 0073 const QModelIndex currentIndex() const; 0074 const KChart::DataValueAttributes attributes() const; 0075 const char* positionToScreenName( const KChart::Position& pos ) const; 0076 const Qt::Alignment alignmentFromScreeName( const QString& name ) const; 0077 const QString alignmentToScreenName( const Qt::Alignment& align ) const; 0078 void populateWidgets(); 0079 void setAttributes( const KChart::DataValueAttributes& da ); 0080 void connectWidgets(); 0081 0082 KChart::Chart* m_chart; 0083 Ui::DataValueSettings *ui; 0084 }; 0085 0086 DataValueSettings::Private::Private( KChart::Chart *chart, DataValueSettings *q ) 0087 : qq ( q ) 0088 , m_chart( chart ) 0089 , ui( new Ui::DataValueSettings ) 0090 { 0091 0092 } 0093 0094 void DataValueSettings::Private::init() 0095 { 0096 ui->setupUi( qq ); 0097 ui->scopeCommonRB->setFocus( Qt::OtherFocusReason ); 0098 ui->scopeCommonRB->setChecked( true ); 0099 ui->paintValuesCB->setChecked( true ); 0100 populateWidgets(); 0101 connectWidgets(); 0102 } 0103 0104 void DataValueSettings::Private::connectWidgets() 0105 { 0106 connect( ui->scopeBarDatasetSB, SIGNAL(valueChanged(int)), this, SLOT(on_scopeBarDatasetSB_valueChanged(int)) ); 0107 connect( ui->scopeBarItemSB, SIGNAL(valueChanged(int)), this, SLOT(on_scopeBarItemSB_valueChanged(int)) ); 0108 connect( ui->scopeDatasetSB, SIGNAL(valueChanged(int)), this, SLOT(on_scopeDatasetSB_valueChanged(int)) ); 0109 connect( ui->scopeOneBarRB, SIGNAL(toggled(bool)), this, SLOT(on_scopeOneBarRB_toggled(bool)) ); 0110 connect( ui->scopeDatasetRB, SIGNAL(toggled(bool)), this, SLOT(on_scopeDatasetRB_toggled(bool)) ); 0111 connect( ui->scopeCommonRB, SIGNAL(toggled(bool)), this, SLOT(on_scopeCommonRB_toggled(bool)) ); 0112 connect( ui->paintValuesCB, SIGNAL(toggled(bool)), this, SLOT(on_paintValuesCB_toggled(bool)) ); 0113 connect( ui->fontCombo, SIGNAL(currentIndexChanged(QString)), this , SLOT(on_fontCombo_currentIndexChanged(QString)) ); 0114 connect( ui->relativeSizeSB, SIGNAL(valueChanged(int)), this, SLOT(on_relativeSizeSB_valueChanged(int)) ); 0115 connect( ui->minimumSizeSB, SIGNAL(valueChanged(int)), this, SLOT(on_minimumSizeSB_valueChanged(int)) ); 0116 connect( ui->rotationSB, SIGNAL(valueChanged(int)), this, SLOT(on_rotationSB_valueChanged(int)) ); 0117 connect( ui->posPosCombo, SIGNAL(currentIndexChanged(QString)), this, SLOT(on_posPosCombo_currentIndexChanged(QString)) ); 0118 connect( ui->posAlignCombo, SIGNAL(currentIndexChanged(QString)), this, SLOT(on_posAlignCombo_currentIndexChanged(QString)) ); 0119 connect( ui->posPadHoriSB, SIGNAL(valueChanged(int)), this, SLOT(on_posPadHoriSB_valueChanged(int)) ); 0120 connect( ui->posPadVertSB, SIGNAL(valueChanged(int)), this, SLOT(on_posPadVertSB_valueChanged(int)) ); 0121 connect( ui->negPosCombo, SIGNAL(currentIndexChanged(QString)), this, SLOT(on_negPosCombo_currentIndexChanged(QString)) ); 0122 connect( ui->negAlignCombo, SIGNAL(currentIndexChanged(QString)), this, SLOT(on_negAlignCombo_currentIndexChanged(QString)) ); 0123 connect( ui->negPadHoriSB, SIGNAL(valueChanged(int)), this, SLOT(on_negPadHoriSB_valueChanged(int)) ); 0124 connect( ui->negPadVertSB, SIGNAL(valueChanged(int)), this, SLOT(on_negPadVertSB_valueChanged(int)) ); 0125 connect( ui->labelLE, SIGNAL(textEdited(QString)), this, SLOT(on_labelLE_textEdited(QString)) ); 0126 connect( ui->prefixLE, SIGNAL(textEdited(QString)), this, SLOT(on_prefixLE_textEdited(QString)) ); 0127 connect( ui->suffixLE, SIGNAL(textEdited(QString)), this, SLOT(on_suffixLE_textEdited(QString)) ); 0128 } 0129 0130 DataValueSettings::DataValueSettings( KChart::Chart *chart, QWidget* parent ) 0131 : QWidget( parent ) 0132 , d( new Private( chart, this ) ) 0133 { 0134 d->init(); 0135 } 0136 0137 DataValueSettings::~DataValueSettings() 0138 { 0139 delete d; 0140 } 0141 0142 void DataValueSettings::refresh() 0143 { 0144 d->populateWidgets(); 0145 } 0146 0147 0148 void DataValueSettings::Private::on_scopeOneBarRB_toggled( bool checked ) 0149 { 0150 if ( checked ) { 0151 ui->scopeBarDatasetSB->setDisabled( false ); 0152 ui->scopeBarItemSB->setDisabled( false ); 0153 ui->scopeDatasetSB->setDisabled( true ); 0154 populateWidgets(); 0155 } 0156 } 0157 0158 void DataValueSettings::Private::on_scopeBarDatasetSB_valueChanged( int i ) 0159 { 0160 Q_UNUSED(i) 0161 populateWidgets(); 0162 } 0163 0164 void DataValueSettings::Private::on_scopeBarItemSB_valueChanged( int i ) 0165 { 0166 Q_UNUSED(i) 0167 populateWidgets(); 0168 } 0169 0170 void DataValueSettings::Private::on_scopeDatasetRB_toggled( bool checked ) 0171 { 0172 if ( checked ) { 0173 ui->scopeBarDatasetSB->setDisabled( true ); 0174 ui->scopeBarItemSB->setDisabled( true ); 0175 ui->scopeDatasetSB->setDisabled( false ); 0176 populateWidgets(); 0177 } 0178 } 0179 0180 void DataValueSettings::Private::on_scopeDatasetSB_valueChanged( int i ) 0181 { 0182 Q_UNUSED(i) 0183 populateWidgets(); 0184 } 0185 0186 void DataValueSettings::Private::on_scopeCommonRB_toggled( bool checked ) 0187 { 0188 if ( checked ) { 0189 ui->scopeBarDatasetSB->setDisabled( true ); 0190 ui->scopeBarItemSB->setDisabled( true ); 0191 ui->scopeDatasetSB->setDisabled( true ); 0192 populateWidgets(); 0193 } 0194 } 0195 0196 void DataValueSettings::Private::on_paintValuesCB_toggled( bool checked ) 0197 { 0198 DataValueAttributes da( attributes() ); 0199 da.setVisible( checked ); 0200 setAttributes( da ); 0201 0202 m_chart->update(); 0203 } 0204 0205 void DataValueSettings::Private::on_fontCombo_currentIndexChanged( const QString & text ) 0206 { 0207 DataValueAttributes da( attributes() ); 0208 TextAttributes ta( da.textAttributes() ); 0209 QFont font( text ); 0210 ta.setFont( font ); 0211 da.setTextAttributes( ta ); 0212 setAttributes( da ); 0213 0214 m_chart->update(); 0215 } 0216 0217 void DataValueSettings::Private::on_relativeSizeSB_valueChanged( int i ) 0218 { 0219 DataValueAttributes da( attributes() ); 0220 TextAttributes ta( da.textAttributes() ); 0221 Measure fs( ta.fontSize() ); 0222 fs.setValue( i ); 0223 ta.setFontSize( i ); 0224 da.setTextAttributes( ta ); 0225 setAttributes( da ); 0226 0227 m_chart->update(); 0228 } 0229 0230 void DataValueSettings::Private::on_minimumSizeSB_valueChanged( int i ) 0231 { 0232 DataValueAttributes da( attributes() ); 0233 TextAttributes ta( da.textAttributes() ); 0234 Measure fs( ta.fontSize() ); 0235 fs.setValue( i ); 0236 ta.setMinimalFontSize( i ); 0237 da.setTextAttributes( ta ); 0238 setAttributes( da ); 0239 0240 m_chart->update(); 0241 } 0242 0243 void DataValueSettings::Private::on_rotationSB_valueChanged( int i ) 0244 { 0245 DataValueAttributes da( attributes() ); 0246 TextAttributes ta( da.textAttributes() ); 0247 ta.setRotation( i ); 0248 da.setTextAttributes( ta ); 0249 setAttributes( da ); 0250 0251 m_chart->update(); 0252 } 0253 0254 void DataValueSettings::Private::on_posPosCombo_currentIndexChanged( const QString & text ) 0255 { 0256 DataValueAttributes da( attributes() ); 0257 RelativePosition relPos( da.positivePosition() ); 0258 relPos.setReferencePosition( Position::fromName( qPrintable( text ) ) ); 0259 da.setPositivePosition( relPos ); 0260 setAttributes( da ); 0261 0262 m_chart->update(); 0263 } 0264 0265 void DataValueSettings::Private::on_posAlignCombo_currentIndexChanged( const QString & text ) 0266 { 0267 DataValueAttributes da( attributes() ); 0268 RelativePosition relPos( da.positivePosition() ); 0269 relPos.setAlignment( alignmentFromScreeName( text ) ); 0270 da.setPositivePosition( relPos ); 0271 setAttributes( da ); 0272 0273 m_chart->update(); 0274 } 0275 0276 void DataValueSettings::Private::on_posPadHoriSB_valueChanged( int i ) 0277 { 0278 DataValueAttributes da( attributes() ); 0279 RelativePosition relPos( da.positivePosition() ); 0280 Measure pad( relPos.horizontalPadding() ); 0281 pad.setValue( i ); 0282 relPos.setHorizontalPadding( pad ); 0283 da.setPositivePosition( relPos ); 0284 setAttributes( da ); 0285 0286 m_chart->update(); 0287 } 0288 0289 void DataValueSettings::Private::on_posPadVertSB_valueChanged( int i ) 0290 { 0291 DataValueAttributes da( attributes() ); 0292 RelativePosition relPos( da.positivePosition() ); 0293 Measure pad( relPos.verticalPadding() ); 0294 pad.setValue( i ); 0295 relPos.setVerticalPadding( pad ); 0296 da.setPositivePosition( relPos ); 0297 setAttributes( da ); 0298 0299 m_chart->update(); 0300 } 0301 0302 void DataValueSettings::Private::on_negPosCombo_currentIndexChanged( const QString & text ) 0303 { 0304 DataValueAttributes da( attributes() ); 0305 RelativePosition relPos( da.negativePosition() ); 0306 relPos.setReferencePosition( Position::fromName( qPrintable( text ) ) ); 0307 da.setNegativePosition( relPos ); 0308 setAttributes( da ); 0309 0310 m_chart->update(); 0311 } 0312 0313 void DataValueSettings::Private::on_negAlignCombo_currentIndexChanged( const QString & text ) 0314 { 0315 DataValueAttributes da( attributes() ); 0316 RelativePosition relPos( da.negativePosition() ); 0317 relPos.setAlignment( alignmentFromScreeName( text ) ); 0318 da.setNegativePosition( relPos ); 0319 setAttributes( da ); 0320 0321 m_chart->update(); 0322 } 0323 0324 void DataValueSettings::Private::on_negPadHoriSB_valueChanged( int i ) 0325 { 0326 DataValueAttributes da( attributes() ); 0327 RelativePosition relPos( da.negativePosition() ); 0328 Measure pad( relPos.horizontalPadding() ); 0329 pad.setValue( i ); 0330 relPos.setHorizontalPadding( pad ); 0331 da.setNegativePosition( relPos ); 0332 setAttributes( da ); 0333 0334 m_chart->update(); 0335 } 0336 0337 void DataValueSettings::Private::on_negPadVertSB_valueChanged( int i ) 0338 { 0339 DataValueAttributes da( attributes() ); 0340 RelativePosition relPos( da.negativePosition() ); 0341 Measure pad( relPos.verticalPadding() ); 0342 pad.setValue( i ); 0343 relPos.setVerticalPadding( pad ); 0344 da.setNegativePosition( relPos ); 0345 setAttributes( da ); 0346 0347 m_chart->update(); 0348 } 0349 0350 void DataValueSettings::Private::on_labelLE_textEdited( const QString & text ) 0351 { 0352 DataValueAttributes da( attributes() ); 0353 da.setDataLabel( text.isEmpty() ? QString() : text ); 0354 setAttributes( da ); 0355 0356 m_chart->update(); 0357 } 0358 0359 void DataValueSettings::Private::on_prefixLE_textEdited( const QString & text ) 0360 { 0361 DataValueAttributes da( attributes() ); 0362 da.setPrefix( text.isEmpty() ? QString() : text ); 0363 setAttributes( da ); 0364 0365 m_chart->update(); 0366 } 0367 0368 void DataValueSettings::Private::on_suffixLE_textEdited( const QString & text ) 0369 { 0370 DataValueAttributes da( attributes() ); 0371 da.setSuffix( text.isEmpty() ? QString() : text ); 0372 setAttributes( da ); 0373 0374 m_chart->update(); 0375 } 0376 0377 const QModelIndex DataValueSettings::Private::currentIndex() const 0378 { 0379 const int dataset = ui->scopeBarDatasetSB->value(); 0380 const int item = ui->scopeBarItemSB->value(); 0381 Q_ASSERT( m_chart ); 0382 Q_ASSERT( m_chart->coordinatePlane() ); 0383 AbstractDiagram *diag = m_chart->coordinatePlane()->diagram(); 0384 return diag->model()->index( item, dataset, QModelIndex() ); 0385 } 0386 0387 const KChart::DataValueAttributes DataValueSettings::Private::attributes() const 0388 { 0389 Q_ASSERT( m_chart ); 0390 Q_ASSERT( m_chart->coordinatePlane() ); 0391 AbstractDiagram *diag = m_chart->coordinatePlane()->diagram(); 0392 DataValueAttributes attr = diag->dataValueAttributes(); 0393 if ( ui->scopeOneBarRB->isChecked() ) { 0394 attr = diag->dataValueAttributes( currentIndex() ); 0395 } 0396 else if ( ui->scopeDatasetRB->isChecked() ) { 0397 attr = diag->dataValueAttributes( ui->scopeDatasetSB->value() ); 0398 } 0399 attr.setShowRepetitiveDataLabels( true ); 0400 return attr; 0401 } 0402 0403 void DataValueSettings::Private::setAttributes( const KChart::DataValueAttributes& da ) 0404 { 0405 Q_ASSERT( m_chart ); 0406 Q_ASSERT( m_chart->coordinatePlane() ); 0407 AbstractDiagram *diag = m_chart->coordinatePlane()->diagram(); 0408 if ( ui->scopeOneBarRB->isChecked() ) 0409 diag->setDataValueAttributes( currentIndex(), da ); 0410 else if ( ui->scopeDatasetRB->isChecked() ) 0411 diag->setDataValueAttributes( ui->scopeDatasetSB->value(), da ); 0412 else 0413 diag->setDataValueAttributes( da ); 0414 } 0415 0416 // just a convenience method: 0417 // In the combo box we have the text "( Default Value )" instead of "Unknown Position" 0418 // because by setting a position to unknown we get KD Chart to use the 0419 // diagram-specific default positions. 0420 const char* DataValueSettings::Private::positionToScreenName( const Position& pos ) const 0421 { 0422 static const char* defaultPositionName = "( Default Value )"; 0423 if ( pos.isUnknown() ) 0424 return defaultPositionName; 0425 return pos.name(); 0426 } 0427 0428 const Qt::Alignment DataValueSettings::Private::alignmentFromScreeName( const QString& name ) const 0429 { 0430 if ( name == "Center" ) return Qt::AlignCenter; 0431 if ( name == "BottomLeft" ) return Qt::AlignLeft | Qt::AlignBottom; 0432 if ( name == "Bottom" ) return Qt::AlignHCenter | Qt::AlignBottom; 0433 if ( name == "BottomRight" ) return Qt::AlignRight | Qt::AlignBottom; 0434 if ( name == "Right" ) return Qt::AlignRight | Qt::AlignVCenter; 0435 if ( name == "TopRight" ) return Qt::AlignRight | Qt::AlignTop; 0436 if ( name == "Top" ) return Qt::AlignHCenter | Qt::AlignTop; 0437 if ( name == "TopLeft" ) return Qt::AlignLeft | Qt::AlignTop; 0438 if ( name == "Left" ) return Qt::AlignLeft | Qt::AlignVCenter; 0439 return Qt::AlignCenter; 0440 } 0441 0442 const QString DataValueSettings::Private::alignmentToScreenName( const Qt::Alignment& align ) const 0443 { 0444 if ( align == Qt::AlignCenter ) return "Center"; 0445 if ( align == (Qt::AlignLeft | Qt::AlignBottom) ) return "BottomLeft"; 0446 if ( align == (Qt::AlignHCenter | Qt::AlignBottom) ) return "Bottom"; 0447 if ( align == (Qt::AlignRight | Qt::AlignBottom) ) return "BottomRight"; 0448 if ( align == (Qt::AlignRight | Qt::AlignVCenter) ) return "Right"; 0449 if ( align == (Qt::AlignRight | Qt::AlignTop) ) return "TopRight"; 0450 if ( align == (Qt::AlignHCenter | Qt::AlignTop) ) return "Top"; 0451 if ( align == (Qt::AlignLeft | Qt::AlignTop) ) return "TopLeft"; 0452 if ( align == (Qt::AlignLeft | Qt::AlignVCenter) ) return "Left"; 0453 return "Center"; 0454 } 0455 0456 void DataValueSettings::Private::populateWidgets() 0457 { 0458 const DataValueAttributes da( attributes() ); 0459 const TextAttributes ta( da.textAttributes() ); 0460 const RelativePosition posPos( da.positivePosition() ); 0461 const RelativePosition negPos( da.negativePosition() ); 0462 0463 ui->paintValuesCB->setChecked( da.isVisible() && ta.isVisible() ); 0464 ui->fontCombo->setCurrentFont( ta.font() ); 0465 ui->relativeSizeSB->setValue( static_cast<int>(ta.fontSize().value()) ); 0466 ui->minimumSizeSB->setValue( static_cast<int>(ta.minimalFontSize().value()) ); 0467 ui->rotationSB->setValue( static_cast<int>(ta.rotation()) ); 0468 0469 ui->posPosCombo->setCurrentIndex( ui->posPosCombo->findText( 0470 positionToScreenName( posPos.referencePosition() ) ) ); 0471 ui->posAlignCombo->setCurrentIndex( ui->posAlignCombo->findText( 0472 alignmentToScreenName( posPos.alignment() ) ) ); 0473 ui->posPadHoriSB->setValue( static_cast<int>(posPos.horizontalPadding().value()) ); 0474 ui->posPadVertSB->setValue( static_cast<int>(posPos.verticalPadding().value()) ); 0475 0476 ui->negPosCombo->setCurrentIndex( ui->negPosCombo->findText( positionToScreenName( 0477 negPos.referencePosition() ) ) ); 0478 ui->negAlignCombo->setCurrentIndex( ui->negAlignCombo->findText( 0479 alignmentToScreenName( negPos.alignment() ) ) ); 0480 ui->negPadHoriSB->setValue( static_cast<int>(negPos.horizontalPadding().value()) ); 0481 ui->negPadVertSB->setValue( static_cast<int>(negPos.verticalPadding().value()) ); 0482 0483 ui->labelLE->setText( da.dataLabel() ); 0484 ui->prefixLE->setText( da.prefix() ); 0485 ui->suffixLE->setText( da.suffix() ); 0486 } 0487 0488 #include "datavaluesettings.moc"