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"