File indexing completed on 2024-05-12 04:20:06

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