1 /** 2 * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. 3 * 4 * This file is part of the KD Chart library. 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation; either version 2 of 9 * the License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program. If not, see <https://www.gnu.org/licenses/>. 18 */ 19 20 #include "mainwindow.h" 21 22 #include <KChartChart> 23 #include <KChartDatasetProxyModel> 24 #include <KChartAbstractCoordinatePlane> 25 #include <KChartBarDiagram> 26 #include <KChartTextAttributes> 27 #include <KChartRelativePosition> 28 #include <KChartPosition> 29 30 31 #include <QDebug> 32 #include <QPainter> 33 34 using namespace KChart; 35 MainWindow(QWidget * parent)36MainWindow::MainWindow( QWidget* parent ) : 37 QWidget( parent ) 38 { 39 setupUi( this ); 40 41 QHBoxLayout* chartLayout = new QHBoxLayout( chartFrame ); 42 m_chart = new Chart(); 43 chartLayout->addWidget( m_chart ); 44 45 m_model.loadFromCSV( ":/data" ); 46 47 // Set up the diagram 48 m_bars = new BarDiagram(); 49 m_bars->setModel( &m_model ); 50 51 QPen pen( m_bars->pen() ); 52 pen.setColor( Qt::darkGray ); 53 pen.setWidth( 1 ); 54 m_bars->setPen( pen ); 55 m_chart->coordinatePlane()->replaceDiagram( m_bars ); 56 m_chart->setGlobalLeadingTop( 20 ); 57 58 scopeCommonRB->setFocus( Qt::OtherFocusReason ); 59 scopeCommonRB->setChecked( true ); 60 paintValuesCB->setChecked( true ); 61 } 62 63 on_scopeOneBarRB_toggled(bool checked)64void MainWindow::on_scopeOneBarRB_toggled( bool checked ) 65 { 66 if ( checked ) { 67 scopeBarDatasetSB->setDisabled( false ); 68 scopeBarItemSB->setDisabled( false ); 69 scopeDatasetSB->setDisabled( true ); 70 populateWidgets(); 71 } 72 } on_scopeBarDatasetSB_valueChanged(int i)73void MainWindow::on_scopeBarDatasetSB_valueChanged( int i ) 74 { 75 Q_UNUSED(i) 76 populateWidgets(); 77 } on_scopeBarItemSB_valueChanged(int i)78void MainWindow::on_scopeBarItemSB_valueChanged( int i ) 79 { 80 Q_UNUSED(i) 81 populateWidgets(); 82 } on_scopeDatasetRB_toggled(bool checked)83void MainWindow::on_scopeDatasetRB_toggled( bool checked ) 84 { 85 if ( checked ) { 86 scopeBarDatasetSB->setDisabled( true ); 87 scopeBarItemSB->setDisabled( true ); 88 scopeDatasetSB->setDisabled( false ); 89 populateWidgets(); 90 } 91 } on_scopeDatasetSB_valueChanged(int i)92void MainWindow::on_scopeDatasetSB_valueChanged( int i ) 93 { 94 Q_UNUSED(i) 95 populateWidgets(); 96 } on_scopeCommonRB_toggled(bool checked)97void MainWindow::on_scopeCommonRB_toggled( bool checked ) 98 { 99 if ( checked ) { 100 scopeBarDatasetSB->setDisabled( true ); 101 scopeBarItemSB->setDisabled( true ); 102 scopeDatasetSB->setDisabled( true ); 103 populateWidgets(); 104 } 105 } 106 on_paintValuesCB_toggled(bool checked)107void MainWindow::on_paintValuesCB_toggled( bool checked ) 108 { 109 DataValueAttributes da( attributes() ); 110 da.setVisible( checked ); 111 setAttributes( da ); 112 113 m_chart->update(); 114 } 115 on_fontCombo_currentIndexChanged(const QString & text)116void MainWindow::on_fontCombo_currentIndexChanged( const QString & text ) 117 { 118 DataValueAttributes da( attributes() ); 119 TextAttributes ta( da.textAttributes() ); 120 QFont font( text ); 121 ta.setFont( font ); 122 da.setTextAttributes( ta ); 123 setAttributes( da ); 124 125 m_chart->update(); 126 } 127 on_relativeSizeSB_valueChanged(int i)128void MainWindow::on_relativeSizeSB_valueChanged( int i ) 129 { 130 DataValueAttributes da( attributes() ); 131 TextAttributes ta( da.textAttributes() ); 132 Measure fs( ta.fontSize() ); 133 fs.setValue( i ); 134 ta.setFontSize( i ); 135 da.setTextAttributes( ta ); 136 setAttributes( da ); 137 138 m_chart->update(); 139 } 140 on_minimumSizeSB_valueChanged(int i)141void MainWindow::on_minimumSizeSB_valueChanged( int i ) 142 { 143 DataValueAttributes da( attributes() ); 144 TextAttributes ta( da.textAttributes() ); 145 Measure fs( ta.fontSize() ); 146 fs.setValue( i ); 147 ta.setMinimalFontSize( i ); 148 da.setTextAttributes( ta ); 149 setAttributes( da ); 150 151 m_chart->update(); 152 } 153 on_rotationSB_valueChanged(int i)154void MainWindow::on_rotationSB_valueChanged( int i ) 155 { 156 DataValueAttributes da( attributes() ); 157 TextAttributes ta( da.textAttributes() ); 158 ta.setRotation( i ); 159 da.setTextAttributes( ta ); 160 setAttributes( da ); 161 162 m_chart->update(); 163 } 164 on_posPosCombo_currentIndexChanged(const QString & text)165void MainWindow::on_posPosCombo_currentIndexChanged( const QString & text ) 166 { 167 DataValueAttributes da( attributes() ); 168 RelativePosition relPos( da.positivePosition() ); 169 relPos.setReferencePosition( Position::fromName( qPrintable( text ) ) ); 170 da.setPositivePosition( relPos ); 171 setAttributes( da ); 172 173 m_chart->update(); 174 } 175 on_posAlignCombo_currentIndexChanged(const QString & text)176void MainWindow::on_posAlignCombo_currentIndexChanged( const QString & text ) 177 { 178 DataValueAttributes da( attributes() ); 179 RelativePosition relPos( da.positivePosition() ); 180 relPos.setAlignment( alignmentFromScreeName( text ) ); 181 da.setPositivePosition( relPos ); 182 setAttributes( da ); 183 184 m_chart->update(); 185 } 186 on_posPadHoriSB_valueChanged(int i)187void MainWindow::on_posPadHoriSB_valueChanged( int i ) 188 { 189 DataValueAttributes da( attributes() ); 190 RelativePosition relPos( da.positivePosition() ); 191 Measure pad( relPos.horizontalPadding() ); 192 pad.setValue( i ); 193 relPos.setHorizontalPadding( pad ); 194 da.setPositivePosition( relPos ); 195 setAttributes( da ); 196 197 m_chart->update(); 198 } 199 on_posPadVertSB_valueChanged(int i)200void MainWindow::on_posPadVertSB_valueChanged( int i ) 201 { 202 DataValueAttributes da( attributes() ); 203 RelativePosition relPos( da.positivePosition() ); 204 Measure pad( relPos.verticalPadding() ); 205 pad.setValue( i ); 206 relPos.setVerticalPadding( pad ); 207 da.setPositivePosition( relPos ); 208 setAttributes( da ); 209 210 m_chart->update(); 211 } 212 on_negPosCombo_currentIndexChanged(const QString & text)213void MainWindow::on_negPosCombo_currentIndexChanged( const QString & text ) 214 { 215 DataValueAttributes da( attributes() ); 216 RelativePosition relPos( da.negativePosition() ); 217 relPos.setReferencePosition( Position::fromName( qPrintable( text ) ) ); 218 da.setNegativePosition( relPos ); 219 setAttributes( da ); 220 221 m_chart->update(); 222 } 223 on_negAlignCombo_currentIndexChanged(const QString & text)224void MainWindow::on_negAlignCombo_currentIndexChanged( const QString & text ) 225 { 226 DataValueAttributes da( attributes() ); 227 RelativePosition relPos( da.negativePosition() ); 228 relPos.setAlignment( alignmentFromScreeName( text ) ); 229 da.setNegativePosition( relPos ); 230 setAttributes( da ); 231 232 m_chart->update(); 233 } 234 on_negPadHoriSB_valueChanged(int i)235void MainWindow::on_negPadHoriSB_valueChanged( int i ) 236 { 237 DataValueAttributes da( attributes() ); 238 RelativePosition relPos( da.negativePosition() ); 239 Measure pad( relPos.horizontalPadding() ); 240 pad.setValue( i ); 241 relPos.setHorizontalPadding( pad ); 242 da.setNegativePosition( relPos ); 243 setAttributes( da ); 244 245 m_chart->update(); 246 } 247 on_negPadVertSB_valueChanged(int i)248void MainWindow::on_negPadVertSB_valueChanged( int i ) 249 { 250 DataValueAttributes da( attributes() ); 251 RelativePosition relPos( da.negativePosition() ); 252 Measure pad( relPos.verticalPadding() ); 253 pad.setValue( i ); 254 relPos.setVerticalPadding( pad ); 255 da.setNegativePosition( relPos ); 256 setAttributes( da ); 257 258 m_chart->update(); 259 } 260 on_labelLE_textEdited(const QString & text)261void MainWindow::on_labelLE_textEdited( const QString & text ) 262 { 263 DataValueAttributes da( attributes() ); 264 da.setDataLabel( text.isEmpty() ? QString() : text ); 265 setAttributes( da ); 266 267 m_chart->update(); 268 } 269 on_prefixLE_textEdited(const QString & text)270void MainWindow::on_prefixLE_textEdited( const QString & text ) 271 { 272 DataValueAttributes da( attributes() ); 273 da.setPrefix( text.isEmpty() ? QString() : text ); 274 setAttributes( da ); 275 276 m_chart->update(); 277 } 278 on_suffixLE_textEdited(const QString & text)279void MainWindow::on_suffixLE_textEdited( const QString & text ) 280 { 281 DataValueAttributes da( attributes() ); 282 da.setSuffix( text.isEmpty() ? QString() : text ); 283 setAttributes( da ); 284 285 m_chart->update(); 286 } 287 currentIndex() const288const QModelIndex MainWindow::currentIndex() const 289 { 290 const int dataset = scopeBarDatasetSB->value(); 291 const int item = scopeBarItemSB->value(); 292 return m_bars->model()->index( item, dataset, QModelIndex() ); 293 } 294 attributes() const295const KChart::DataValueAttributes MainWindow::attributes() const 296 { 297 if ( scopeOneBarRB->isChecked() ) { 298 //qDebug() << "attributes() returns settings for one single bar"; 299 return m_bars->dataValueAttributes( currentIndex() ); 300 } 301 if ( scopeDatasetRB->isChecked() ) { 302 //qDebug() << "attributes() returns settings for a dataset"; 303 return m_bars->dataValueAttributes( scopeDatasetSB->value() ); 304 } 305 //qDebug() << "attributes() returns common settings"; 306 return m_bars->dataValueAttributes(); 307 } 308 setAttributes(const KChart::DataValueAttributes & da)309void MainWindow::setAttributes( const KChart::DataValueAttributes& da ) 310 { 311 if ( scopeOneBarRB->isChecked() ) 312 m_bars->setDataValueAttributes( currentIndex(), da ); 313 else if ( scopeDatasetRB->isChecked() ) 314 m_bars->setDataValueAttributes( scopeDatasetSB->value(), da ); 315 else 316 m_bars->setDataValueAttributes( da ); 317 } 318 319 // just a convenience method: 320 // In the combo box we have the text "( Default Value )" instead of "Unknown Position" 321 // because by setting a position to unknown we get KD Chart to use the 322 // diagram-specific default positions. positionToScreenName(const Position & pos) const323const char* MainWindow::positionToScreenName( const Position& pos ) const 324 { 325 static const char* defaultPositionName = "( Default Value )"; 326 if ( pos.isUnknown() ) 327 return defaultPositionName; 328 return pos.name(); 329 } 330 alignmentFromScreeName(const QString & name) const331const Qt::Alignment MainWindow::alignmentFromScreeName( const QString& name ) const 332 { 333 if ( name == "Center" ) return Qt::AlignCenter; 334 if ( name == "BottomLeft" ) return Qt::AlignLeft | Qt::AlignBottom; 335 if ( name == "Bottom" ) return Qt::AlignHCenter | Qt::AlignBottom; 336 if ( name == "BottomRight" ) return Qt::AlignRight | Qt::AlignBottom; 337 if ( name == "Right" ) return Qt::AlignRight | Qt::AlignVCenter; 338 if ( name == "TopRight" ) return Qt::AlignRight | Qt::AlignTop; 339 if ( name == "Top" ) return Qt::AlignHCenter | Qt::AlignTop; 340 if ( name == "TopLeft" ) return Qt::AlignLeft | Qt::AlignTop; 341 if ( name == "Left" ) return Qt::AlignLeft | Qt::AlignVCenter; 342 return Qt::AlignCenter; 343 } 344 alignmentToScreenName(const Qt::Alignment & align) const345const QString MainWindow::alignmentToScreenName( const Qt::Alignment& align ) const 346 { 347 if ( align == Qt::AlignCenter ) return "Center"; 348 if ( align == (Qt::AlignLeft | Qt::AlignBottom) ) return "BottomLeft"; 349 if ( align == (Qt::AlignHCenter | Qt::AlignBottom) ) return "Bottom"; 350 if ( align == (Qt::AlignRight | Qt::AlignBottom) ) return "BottomRight"; 351 if ( align == (Qt::AlignRight | Qt::AlignVCenter) ) return "Right"; 352 if ( align == (Qt::AlignRight | Qt::AlignTop) ) return "TopRight"; 353 if ( align == (Qt::AlignHCenter | Qt::AlignTop) ) return "Top"; 354 if ( align == (Qt::AlignLeft | Qt::AlignTop) ) return "TopLeft"; 355 if ( align == (Qt::AlignLeft | Qt::AlignVCenter) ) return "Left"; 356 return "Center"; 357 } 358 populateWidgets()359void MainWindow::populateWidgets() 360 { 361 const DataValueAttributes da( attributes() ); 362 const TextAttributes ta( da.textAttributes() ); 363 const RelativePosition posPos( da.positivePosition() ); 364 const RelativePosition negPos( da.negativePosition() ); 365 366 paintValuesCB->setChecked( da.isVisible() && ta.isVisible() ); 367 fontCombo->setCurrentFont( ta.font() ); 368 relativeSizeSB->setValue( static_cast<int>(ta.fontSize().value()) ); 369 minimumSizeSB->setValue( static_cast<int>(ta.minimalFontSize().value()) ); 370 rotationSB->setValue( static_cast<int>(ta.rotation()) ); 371 372 posPosCombo->setCurrentIndex( posPosCombo->findText( 373 positionToScreenName( posPos.referencePosition() ) ) ); 374 posAlignCombo->setCurrentIndex( posAlignCombo->findText( 375 alignmentToScreenName( posPos.alignment() ) ) ); 376 posPadHoriSB->setValue( static_cast<int>(posPos.horizontalPadding().value()) ); 377 posPadVertSB->setValue( static_cast<int>(posPos.verticalPadding().value()) ); 378 379 negPosCombo->setCurrentIndex( negPosCombo->findText( positionToScreenName( 380 negPos.referencePosition() ) ) ); 381 negAlignCombo->setCurrentIndex( negAlignCombo->findText( 382 alignmentToScreenName( negPos.alignment() ) ) ); 383 negPadHoriSB->setValue( static_cast<int>(negPos.horizontalPadding().value()) ); 384 negPadVertSB->setValue( static_cast<int>(negPos.verticalPadding().value()) ); 385 386 labelLE->setText( da.dataLabel() ); 387 prefixLE->setText( da.prefix() ); 388 suffixLE->setText( da.suffix() ); 389 } 390