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

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 "mainwindow.h"
0010 
0011 #include <KChartChart>
0012 #include <KChartDatasetProxyModel>
0013 #include <KChartAbstractCoordinatePlane>
0014 #include <KChartBarDiagram>
0015 #include <KChartTextAttributes>
0016 #include <KChartRelativePosition>
0017 #include <KChartPosition>
0018 
0019 
0020 #include <QDebug>
0021 #include <QPainter>
0022 
0023 using namespace KChart;
0024 
0025 MainWindow::MainWindow( QWidget* parent ) :
0026     QWidget( parent )
0027 {
0028     setupUi( this );
0029 
0030     QHBoxLayout* chartLayout = new QHBoxLayout( chartFrame );
0031     m_chart = new Chart();
0032     chartLayout->addWidget( m_chart );
0033 
0034     m_model.loadFromCSV( ":/data" );
0035 
0036     // Set up the diagram
0037     m_bars = new BarDiagram();
0038     m_bars->setModel( &m_model );
0039 
0040     QPen pen(  m_bars->pen() );
0041     pen.setColor( Qt::darkGray );
0042     pen.setWidth( 1 );
0043     m_bars->setPen( pen );
0044     m_chart->coordinatePlane()->replaceDiagram( m_bars );
0045     m_chart->setGlobalLeadingTop( 20 );
0046 
0047     scopeCommonRB->setFocus( Qt::OtherFocusReason );
0048     scopeCommonRB->setChecked( true );
0049     paintValuesCB->setChecked( true );
0050 }
0051 
0052 
0053 void MainWindow::on_scopeOneBarRB_toggled(  bool checked )
0054 {
0055     if ( checked ) {
0056         scopeBarDatasetSB->setDisabled( false );
0057         scopeBarItemSB->setDisabled(    false );
0058         scopeDatasetSB->setDisabled(    true );
0059         populateWidgets();
0060     }
0061 }
0062 void MainWindow::on_scopeBarDatasetSB_valueChanged( int i )
0063 {
0064     Q_UNUSED(i)
0065     populateWidgets();
0066 }
0067 void MainWindow::on_scopeBarItemSB_valueChanged(    int i )
0068 {
0069     Q_UNUSED(i)
0070     populateWidgets();
0071 }
0072 void MainWindow::on_scopeDatasetRB_toggled( bool checked )
0073 {
0074     if ( checked ) {
0075         scopeBarDatasetSB->setDisabled( true );
0076         scopeBarItemSB->setDisabled(    true );
0077         scopeDatasetSB->setDisabled(    false );
0078         populateWidgets();
0079     }
0080 }
0081 void MainWindow::on_scopeDatasetSB_valueChanged( int i )
0082 {
0083     Q_UNUSED(i)
0084     populateWidgets();
0085 }
0086 void MainWindow::on_scopeCommonRB_toggled( bool checked )
0087 {
0088     if ( checked ) {
0089         scopeBarDatasetSB->setDisabled( true );
0090         scopeBarItemSB->setDisabled(    true );
0091         scopeDatasetSB->setDisabled(    true );
0092         populateWidgets();
0093     }
0094 }
0095 
0096 void MainWindow::on_paintValuesCB_toggled( bool checked )
0097 {
0098     DataValueAttributes da( attributes() );
0099     da.setVisible( checked );
0100     setAttributes( da );
0101 
0102     m_chart->update();
0103 }
0104 
0105 void MainWindow::on_fontCombo_currentIndexChanged( const QString & text )
0106 {
0107     DataValueAttributes da( attributes() );
0108     TextAttributes ta( da.textAttributes() );
0109     QFont font( text );
0110     ta.setFont( font );
0111     da.setTextAttributes( ta );
0112     setAttributes( da );
0113 
0114     m_chart->update();
0115 }
0116 
0117 void MainWindow::on_relativeSizeSB_valueChanged( int i )
0118 {
0119     DataValueAttributes da( attributes() );
0120     TextAttributes ta( da.textAttributes() );
0121     Measure fs( ta.fontSize() );
0122     fs.setValue( i );
0123     ta.setFontSize( i );
0124     da.setTextAttributes( ta );
0125     setAttributes( da );
0126 
0127     m_chart->update();
0128 }
0129 
0130 void MainWindow::on_minimumSizeSB_valueChanged(  int i )
0131 {
0132     DataValueAttributes da( attributes() );
0133     TextAttributes ta( da.textAttributes() );
0134     Measure fs( ta.fontSize() );
0135     fs.setValue( i );
0136     ta.setMinimalFontSize( i );
0137     da.setTextAttributes( ta );
0138     setAttributes( da );
0139 
0140     m_chart->update();
0141 }
0142 
0143 void MainWindow::on_rotationSB_valueChanged( int i )
0144 {
0145     DataValueAttributes da( attributes() );
0146     TextAttributes ta( da.textAttributes() );
0147     ta.setRotation( i );
0148     da.setTextAttributes( ta );
0149     setAttributes( da );
0150 
0151     m_chart->update();
0152 }
0153 
0154 void MainWindow::on_posPosCombo_currentIndexChanged(   const QString & text )
0155 {
0156     DataValueAttributes da( attributes() );
0157     RelativePosition relPos( da.positivePosition() );
0158     relPos.setReferencePosition( Position::fromName( qPrintable( text ) ) );
0159     da.setPositivePosition( relPos );
0160     setAttributes( da );
0161 
0162     m_chart->update();
0163 }
0164 
0165 void MainWindow::on_posAlignCombo_currentIndexChanged( const QString & text )
0166 {
0167     DataValueAttributes da( attributes() );
0168     RelativePosition relPos( da.positivePosition() );
0169     relPos.setAlignment( alignmentFromScreeName( text ) );
0170     da.setPositivePosition( relPos );
0171     setAttributes( da );
0172 
0173     m_chart->update();
0174 }
0175 
0176 void MainWindow::on_posPadHoriSB_valueChanged( int i )
0177 {
0178     DataValueAttributes da( attributes() );
0179     RelativePosition relPos( da.positivePosition() );
0180     Measure pad( relPos.horizontalPadding() );
0181     pad.setValue( i );
0182     relPos.setHorizontalPadding( pad );
0183     da.setPositivePosition( relPos );
0184     setAttributes( da );
0185 
0186     m_chart->update();
0187 }
0188 
0189 void MainWindow::on_posPadVertSB_valueChanged( int i )
0190 {
0191     DataValueAttributes da( attributes() );
0192     RelativePosition relPos( da.positivePosition() );
0193     Measure pad( relPos.verticalPadding() );
0194     pad.setValue( i );
0195     relPos.setVerticalPadding( pad );
0196     da.setPositivePosition( relPos );
0197     setAttributes( da );
0198 
0199     m_chart->update();
0200 }
0201 
0202 void MainWindow::on_negPosCombo_currentIndexChanged(   const QString & text )
0203 {
0204     DataValueAttributes da( attributes() );
0205     RelativePosition relPos( da.negativePosition() );
0206     relPos.setReferencePosition( Position::fromName( qPrintable( text ) ) );
0207     da.setNegativePosition( relPos );
0208     setAttributes( da );
0209 
0210     m_chart->update();
0211 }
0212 
0213 void MainWindow::on_negAlignCombo_currentIndexChanged( const QString & text )
0214 {
0215     DataValueAttributes da( attributes() );
0216     RelativePosition relPos( da.negativePosition() );
0217     relPos.setAlignment( alignmentFromScreeName( text ) );
0218     da.setNegativePosition( relPos );
0219     setAttributes( da );
0220 
0221     m_chart->update();
0222 }
0223 
0224 void MainWindow::on_negPadHoriSB_valueChanged( int i )
0225 {
0226     DataValueAttributes da( attributes() );
0227     RelativePosition relPos( da.negativePosition() );
0228     Measure pad( relPos.horizontalPadding() );
0229     pad.setValue( i );
0230     relPos.setHorizontalPadding( pad );
0231     da.setNegativePosition( relPos );
0232     setAttributes( da );
0233 
0234     m_chart->update();
0235 }
0236 
0237 void MainWindow::on_negPadVertSB_valueChanged( int i )
0238 {
0239     DataValueAttributes da( attributes() );
0240     RelativePosition relPos( da.negativePosition() );
0241     Measure pad( relPos.verticalPadding() );
0242     pad.setValue( i );
0243     relPos.setVerticalPadding( pad );
0244     da.setNegativePosition( relPos );
0245     setAttributes( da );
0246 
0247     m_chart->update();
0248 }
0249 
0250 void MainWindow::on_labelLE_textEdited(  const QString & text )
0251 {
0252     DataValueAttributes da( attributes() );
0253     da.setDataLabel( text.isEmpty() ? QString() : text );
0254     setAttributes( da );
0255 
0256     m_chart->update();
0257 }
0258 
0259 void MainWindow::on_prefixLE_textEdited( const QString & text )
0260 {
0261     DataValueAttributes da( attributes() );
0262     da.setPrefix( text.isEmpty() ? QString() : text );
0263     setAttributes( da );
0264 
0265     m_chart->update();
0266 }
0267 
0268 void MainWindow::on_suffixLE_textEdited( const QString & text )
0269 {
0270     DataValueAttributes da( attributes() );
0271     da.setSuffix( text.isEmpty() ? QString() : text );
0272     setAttributes( da );
0273 
0274     m_chart->update();
0275 }
0276 
0277 const QModelIndex MainWindow::currentIndex() const
0278 {
0279     const int dataset = scopeBarDatasetSB->value();
0280     const int item    = scopeBarItemSB->value();
0281     return m_bars->model()->index( item, dataset, QModelIndex() );
0282 }
0283 
0284 const KChart::DataValueAttributes MainWindow::attributes() const
0285 {
0286     if ( scopeOneBarRB->isChecked() ) {
0287         //qDebug() << "attributes() returns settings for one single bar";
0288         return m_bars->dataValueAttributes( currentIndex() );
0289     }
0290     if ( scopeDatasetRB->isChecked() ) {
0291         //qDebug() << "attributes() returns settings for a dataset";
0292         return m_bars->dataValueAttributes( scopeDatasetSB->value() );
0293     }
0294     //qDebug() << "attributes() returns common settings";
0295     return m_bars->dataValueAttributes();
0296 }
0297 
0298 void MainWindow::setAttributes( const KChart::DataValueAttributes& da )
0299 {
0300     if ( scopeOneBarRB->isChecked() )
0301         m_bars->setDataValueAttributes( currentIndex(), da );
0302     else if ( scopeDatasetRB->isChecked() )
0303         m_bars->setDataValueAttributes( scopeDatasetSB->value(), da );
0304     else
0305         m_bars->setDataValueAttributes( da );
0306 }
0307 
0308 // just a convenience method:
0309 // In the combo box we have the text "( Default Value )" instead of "Unknown Position"
0310 // because by setting a position to unknown we get KD Chart to use the
0311 // diagram-specific default positions.
0312 const char* MainWindow::positionToScreenName( const Position& pos ) const
0313 {
0314     static const char* defaultPositionName = "( Default Value )";
0315     if ( pos.isUnknown() )
0316         return defaultPositionName;
0317     return pos.name();
0318 }
0319 
0320 const Qt::Alignment MainWindow::alignmentFromScreeName( const QString& name ) const
0321 {
0322     if ( name == "Center" )      return Qt::AlignCenter;
0323     if ( name == "BottomLeft" )  return Qt::AlignLeft    | Qt::AlignBottom;
0324     if ( name == "Bottom" )      return Qt::AlignHCenter | Qt::AlignBottom;
0325     if ( name == "BottomRight" ) return Qt::AlignRight   | Qt::AlignBottom;
0326     if ( name == "Right" )       return Qt::AlignRight   | Qt::AlignVCenter;
0327     if ( name == "TopRight" )    return Qt::AlignRight   | Qt::AlignTop;
0328     if ( name == "Top" )         return Qt::AlignHCenter | Qt::AlignTop;
0329     if ( name == "TopLeft" )     return Qt::AlignLeft    | Qt::AlignTop;
0330     if ( name == "Left" )        return Qt::AlignLeft    | Qt::AlignVCenter;
0331     return Qt::AlignCenter;
0332 }
0333 
0334 const QString MainWindow::alignmentToScreenName( const Qt::Alignment& align ) const
0335 {
0336     if ( align == Qt::AlignCenter )                       return "Center";
0337     if ( align == (Qt::AlignLeft    | Qt::AlignBottom) )  return "BottomLeft";
0338     if ( align == (Qt::AlignHCenter | Qt::AlignBottom) )  return "Bottom";
0339     if ( align == (Qt::AlignRight   | Qt::AlignBottom) )  return "BottomRight";
0340     if ( align == (Qt::AlignRight   | Qt::AlignVCenter) ) return "Right";
0341     if ( align == (Qt::AlignRight   | Qt::AlignTop) )     return "TopRight";
0342     if ( align == (Qt::AlignHCenter | Qt::AlignTop) )     return "Top";
0343     if ( align == (Qt::AlignLeft    | Qt::AlignTop) )     return "TopLeft";
0344     if ( align == (Qt::AlignLeft    | Qt::AlignVCenter) ) return "Left";
0345     return "Center";
0346 }
0347 
0348 void MainWindow::populateWidgets()
0349 {
0350     const DataValueAttributes da( attributes() );
0351     const TextAttributes ta( da.textAttributes() );
0352     const RelativePosition posPos( da.positivePosition() );
0353     const RelativePosition negPos( da.negativePosition() );
0354 
0355     paintValuesCB->setChecked( da.isVisible() && ta.isVisible() );
0356     fontCombo->setCurrentFont( ta.font() );
0357     relativeSizeSB->setValue( static_cast<int>(ta.fontSize().value()) );
0358     minimumSizeSB->setValue(  static_cast<int>(ta.minimalFontSize().value()) );
0359     rotationSB->setValue( static_cast<int>(ta.rotation()) );
0360 
0361     posPosCombo->setCurrentIndex( posPosCombo->findText(
0362             positionToScreenName( posPos.referencePosition() ) ) );
0363     posAlignCombo->setCurrentIndex( posAlignCombo->findText(
0364             alignmentToScreenName( posPos.alignment() ) ) );
0365     posPadHoriSB->setValue( static_cast<int>(posPos.horizontalPadding().value()) );
0366     posPadVertSB->setValue( static_cast<int>(posPos.verticalPadding().value()) );
0367 
0368     negPosCombo->setCurrentIndex( negPosCombo->findText( positionToScreenName(
0369             negPos.referencePosition() ) ) );
0370     negAlignCombo->setCurrentIndex( negAlignCombo->findText(
0371             alignmentToScreenName( negPos.alignment() ) ) );
0372     negPadHoriSB->setValue( static_cast<int>(negPos.horizontalPadding().value()) );
0373     negPadVertSB->setValue( static_cast<int>(negPos.verticalPadding().value()) );
0374 
0375     labelLE->setText(  da.dataLabel() );
0376     prefixLE->setText( da.prefix() );
0377     suffixLE->setText( da.suffix() );
0378 }