File indexing completed on 2024-05-19 15:26:50

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