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 "datavaluesettings.h"
21 #include "ui_datavaluesettings.h"
22
23 #include <KChartChart>
24 #include <KChartAbstractCoordinatePlane>
25 #include <KChartBarDiagram>
26 #include <KChartTextAttributes>
27 #include <KChartRelativePosition>
28 #include <KChartPosition>
29 #include <KChartDataValueAttributes>
30 #include <KChartAbstractDiagram>
31
32
33 #include <QDebug>
34 #include <QPainter>
35
36 using namespace KChart;
37
38 class DataValueSettings::Private : public QObject
39 {
40 Q_OBJECT
41 public:
42 Private( KChart::Chart *chart, DataValueSettings *q );
43 DataValueSettings *qq;
44 void init();
45 public Q_SLOTS:
46 void on_scopeOneBarRB_toggled( bool checked );
47 void on_scopeBarDatasetSB_valueChanged( int i );
48 void on_scopeBarItemSB_valueChanged( int i );
49 void on_scopeDatasetRB_toggled( bool checked );
50 void on_scopeDatasetSB_valueChanged( int i );
51 void on_scopeCommonRB_toggled( bool checked );
52
53 void on_paintValuesCB_toggled( bool checked );
54
55 void on_fontCombo_currentIndexChanged( const QString & text );
56 void on_relativeSizeSB_valueChanged( int i );
57 void on_minimumSizeSB_valueChanged( int i );
58 void on_rotationSB_valueChanged( int i );
59
60 void on_posPosCombo_currentIndexChanged( const QString & text );
61 void on_posAlignCombo_currentIndexChanged( const QString & text );
62 void on_posPadHoriSB_valueChanged( int i );
63 void on_posPadVertSB_valueChanged( int i );
64 void on_negPosCombo_currentIndexChanged( const QString & text );
65 void on_negAlignCombo_currentIndexChanged( const QString & text );
66 void on_negPadHoriSB_valueChanged( int i );
67 void on_negPadVertSB_valueChanged( int i );
68
69 void on_labelLE_textEdited( const QString & text );
70 void on_prefixLE_textEdited( const QString & text );
71 void on_suffixLE_textEdited( const QString & text );
72 public:
73 const QModelIndex currentIndex() const;
74 const KChart::DataValueAttributes attributes() const;
75 const char* positionToScreenName( const KChart::Position& pos ) const;
76 const Qt::Alignment alignmentFromScreeName( const QString& name ) const;
77 const QString alignmentToScreenName( const Qt::Alignment& align ) const;
78 void populateWidgets();
79 void setAttributes( const KChart::DataValueAttributes& da );
80 void connectWidgets();
81
82 KChart::Chart* m_chart;
83 Ui::DataValueSettings *ui;
84 };
85
Private(KChart::Chart * chart,DataValueSettings * q)86 DataValueSettings::Private::Private( KChart::Chart *chart, DataValueSettings *q )
87 : qq ( q )
88 , m_chart( chart )
89 , ui( new Ui::DataValueSettings )
90 {
91
92 }
93
init()94 void DataValueSettings::Private::init()
95 {
96 ui->setupUi( qq );
97 ui->scopeCommonRB->setFocus( Qt::OtherFocusReason );
98 ui->scopeCommonRB->setChecked( true );
99 ui->paintValuesCB->setChecked( true );
100 populateWidgets();
101 connectWidgets();
102 }
103
connectWidgets()104 void DataValueSettings::Private::connectWidgets()
105 {
106 connect( ui->scopeBarDatasetSB, SIGNAL(valueChanged(int)), this, SLOT(on_scopeBarDatasetSB_valueChanged(int)) );
107 connect( ui->scopeBarItemSB, SIGNAL(valueChanged(int)), this, SLOT(on_scopeBarItemSB_valueChanged(int)) );
108 connect( ui->scopeDatasetSB, SIGNAL(valueChanged(int)), this, SLOT(on_scopeDatasetSB_valueChanged(int)) );
109 connect( ui->scopeOneBarRB, SIGNAL(toggled(bool)), this, SLOT(on_scopeOneBarRB_toggled(bool)) );
110 connect( ui->scopeDatasetRB, SIGNAL(toggled(bool)), this, SLOT(on_scopeDatasetRB_toggled(bool)) );
111 connect( ui->scopeCommonRB, SIGNAL(toggled(bool)), this, SLOT(on_scopeCommonRB_toggled(bool)) );
112 connect( ui->paintValuesCB, SIGNAL(toggled(bool)), this, SLOT(on_paintValuesCB_toggled(bool)) );
113 connect( ui->fontCombo, SIGNAL(currentIndexChanged(QString)), this , SLOT(on_fontCombo_currentIndexChanged(QString)) );
114 connect( ui->relativeSizeSB, SIGNAL(valueChanged(int)), this, SLOT(on_relativeSizeSB_valueChanged(int)) );
115 connect( ui->minimumSizeSB, SIGNAL(valueChanged(int)), this, SLOT(on_minimumSizeSB_valueChanged(int)) );
116 connect( ui->rotationSB, SIGNAL(valueChanged(int)), this, SLOT(on_rotationSB_valueChanged(int)) );
117 connect( ui->posPosCombo, SIGNAL(currentIndexChanged(QString)), this, SLOT(on_posPosCombo_currentIndexChanged(QString)) );
118 connect( ui->posAlignCombo, SIGNAL(currentIndexChanged(QString)), this, SLOT(on_posAlignCombo_currentIndexChanged(QString)) );
119 connect( ui->posPadHoriSB, SIGNAL(valueChanged(int)), this, SLOT(on_posPadHoriSB_valueChanged(int)) );
120 connect( ui->posPadVertSB, SIGNAL(valueChanged(int)), this, SLOT(on_posPadVertSB_valueChanged(int)) );
121 connect( ui->negPosCombo, SIGNAL(currentIndexChanged(QString)), this, SLOT(on_negPosCombo_currentIndexChanged(QString)) );
122 connect( ui->negAlignCombo, SIGNAL(currentIndexChanged(QString)), this, SLOT(on_negAlignCombo_currentIndexChanged(QString)) );
123 connect( ui->negPadHoriSB, SIGNAL(valueChanged(int)), this, SLOT(on_negPadHoriSB_valueChanged(int)) );
124 connect( ui->negPadVertSB, SIGNAL(valueChanged(int)), this, SLOT(on_negPadVertSB_valueChanged(int)) );
125 connect( ui->labelLE, SIGNAL(textEdited(QString)), this, SLOT(on_labelLE_textEdited(QString)) );
126 connect( ui->prefixLE, SIGNAL(textEdited(QString)), this, SLOT(on_prefixLE_textEdited(QString)) );
127 connect( ui->suffixLE, SIGNAL(textEdited(QString)), this, SLOT(on_suffixLE_textEdited(QString)) );
128 }
129
DataValueSettings(KChart::Chart * chart,QWidget * parent)130 DataValueSettings::DataValueSettings( KChart::Chart *chart, QWidget* parent )
131 : QWidget( parent )
132 , d( new Private( chart, this ) )
133 {
134 d->init();
135 }
136
~DataValueSettings()137 DataValueSettings::~DataValueSettings()
138 {
139 delete d;
140 }
141
refresh()142 void DataValueSettings::refresh()
143 {
144 d->populateWidgets();
145 }
146
147
on_scopeOneBarRB_toggled(bool checked)148 void DataValueSettings::Private::on_scopeOneBarRB_toggled( bool checked )
149 {
150 if ( checked ) {
151 ui->scopeBarDatasetSB->setDisabled( false );
152 ui->scopeBarItemSB->setDisabled( false );
153 ui->scopeDatasetSB->setDisabled( true );
154 populateWidgets();
155 }
156 }
157
on_scopeBarDatasetSB_valueChanged(int i)158 void DataValueSettings::Private::on_scopeBarDatasetSB_valueChanged( int i )
159 {
160 Q_UNUSED(i)
161 populateWidgets();
162 }
163
on_scopeBarItemSB_valueChanged(int i)164 void DataValueSettings::Private::on_scopeBarItemSB_valueChanged( int i )
165 {
166 Q_UNUSED(i)
167 populateWidgets();
168 }
169
on_scopeDatasetRB_toggled(bool checked)170 void DataValueSettings::Private::on_scopeDatasetRB_toggled( bool checked )
171 {
172 if ( checked ) {
173 ui->scopeBarDatasetSB->setDisabled( true );
174 ui->scopeBarItemSB->setDisabled( true );
175 ui->scopeDatasetSB->setDisabled( false );
176 populateWidgets();
177 }
178 }
179
on_scopeDatasetSB_valueChanged(int i)180 void DataValueSettings::Private::on_scopeDatasetSB_valueChanged( int i )
181 {
182 Q_UNUSED(i)
183 populateWidgets();
184 }
185
on_scopeCommonRB_toggled(bool checked)186 void DataValueSettings::Private::on_scopeCommonRB_toggled( bool checked )
187 {
188 if ( checked ) {
189 ui->scopeBarDatasetSB->setDisabled( true );
190 ui->scopeBarItemSB->setDisabled( true );
191 ui->scopeDatasetSB->setDisabled( true );
192 populateWidgets();
193 }
194 }
195
on_paintValuesCB_toggled(bool checked)196 void DataValueSettings::Private::on_paintValuesCB_toggled( bool checked )
197 {
198 DataValueAttributes da( attributes() );
199 da.setVisible( checked );
200 setAttributes( da );
201
202 m_chart->update();
203 }
204
on_fontCombo_currentIndexChanged(const QString & text)205 void DataValueSettings::Private::on_fontCombo_currentIndexChanged( const QString & text )
206 {
207 DataValueAttributes da( attributes() );
208 TextAttributes ta( da.textAttributes() );
209 QFont font( text );
210 ta.setFont( font );
211 da.setTextAttributes( ta );
212 setAttributes( da );
213
214 m_chart->update();
215 }
216
on_relativeSizeSB_valueChanged(int i)217 void DataValueSettings::Private::on_relativeSizeSB_valueChanged( int i )
218 {
219 DataValueAttributes da( attributes() );
220 TextAttributes ta( da.textAttributes() );
221 Measure fs( ta.fontSize() );
222 fs.setValue( i );
223 ta.setFontSize( i );
224 da.setTextAttributes( ta );
225 setAttributes( da );
226
227 m_chart->update();
228 }
229
on_minimumSizeSB_valueChanged(int i)230 void DataValueSettings::Private::on_minimumSizeSB_valueChanged( int i )
231 {
232 DataValueAttributes da( attributes() );
233 TextAttributes ta( da.textAttributes() );
234 Measure fs( ta.fontSize() );
235 fs.setValue( i );
236 ta.setMinimalFontSize( i );
237 da.setTextAttributes( ta );
238 setAttributes( da );
239
240 m_chart->update();
241 }
242
on_rotationSB_valueChanged(int i)243 void DataValueSettings::Private::on_rotationSB_valueChanged( int i )
244 {
245 DataValueAttributes da( attributes() );
246 TextAttributes ta( da.textAttributes() );
247 ta.setRotation( i );
248 da.setTextAttributes( ta );
249 setAttributes( da );
250
251 m_chart->update();
252 }
253
on_posPosCombo_currentIndexChanged(const QString & text)254 void DataValueSettings::Private::on_posPosCombo_currentIndexChanged( const QString & text )
255 {
256 DataValueAttributes da( attributes() );
257 RelativePosition relPos( da.positivePosition() );
258 relPos.setReferencePosition( Position::fromName( qPrintable( text ) ) );
259 da.setPositivePosition( relPos );
260 setAttributes( da );
261
262 m_chart->update();
263 }
264
on_posAlignCombo_currentIndexChanged(const QString & text)265 void DataValueSettings::Private::on_posAlignCombo_currentIndexChanged( const QString & text )
266 {
267 DataValueAttributes da( attributes() );
268 RelativePosition relPos( da.positivePosition() );
269 relPos.setAlignment( alignmentFromScreeName( text ) );
270 da.setPositivePosition( relPos );
271 setAttributes( da );
272
273 m_chart->update();
274 }
275
on_posPadHoriSB_valueChanged(int i)276 void DataValueSettings::Private::on_posPadHoriSB_valueChanged( int i )
277 {
278 DataValueAttributes da( attributes() );
279 RelativePosition relPos( da.positivePosition() );
280 Measure pad( relPos.horizontalPadding() );
281 pad.setValue( i );
282 relPos.setHorizontalPadding( pad );
283 da.setPositivePosition( relPos );
284 setAttributes( da );
285
286 m_chart->update();
287 }
288
on_posPadVertSB_valueChanged(int i)289 void DataValueSettings::Private::on_posPadVertSB_valueChanged( int i )
290 {
291 DataValueAttributes da( attributes() );
292 RelativePosition relPos( da.positivePosition() );
293 Measure pad( relPos.verticalPadding() );
294 pad.setValue( i );
295 relPos.setVerticalPadding( pad );
296 da.setPositivePosition( relPos );
297 setAttributes( da );
298
299 m_chart->update();
300 }
301
on_negPosCombo_currentIndexChanged(const QString & text)302 void DataValueSettings::Private::on_negPosCombo_currentIndexChanged( const QString & text )
303 {
304 DataValueAttributes da( attributes() );
305 RelativePosition relPos( da.negativePosition() );
306 relPos.setReferencePosition( Position::fromName( qPrintable( text ) ) );
307 da.setNegativePosition( relPos );
308 setAttributes( da );
309
310 m_chart->update();
311 }
312
on_negAlignCombo_currentIndexChanged(const QString & text)313 void DataValueSettings::Private::on_negAlignCombo_currentIndexChanged( const QString & text )
314 {
315 DataValueAttributes da( attributes() );
316 RelativePosition relPos( da.negativePosition() );
317 relPos.setAlignment( alignmentFromScreeName( text ) );
318 da.setNegativePosition( relPos );
319 setAttributes( da );
320
321 m_chart->update();
322 }
323
on_negPadHoriSB_valueChanged(int i)324 void DataValueSettings::Private::on_negPadHoriSB_valueChanged( int i )
325 {
326 DataValueAttributes da( attributes() );
327 RelativePosition relPos( da.negativePosition() );
328 Measure pad( relPos.horizontalPadding() );
329 pad.setValue( i );
330 relPos.setHorizontalPadding( pad );
331 da.setNegativePosition( relPos );
332 setAttributes( da );
333
334 m_chart->update();
335 }
336
on_negPadVertSB_valueChanged(int i)337 void DataValueSettings::Private::on_negPadVertSB_valueChanged( int i )
338 {
339 DataValueAttributes da( attributes() );
340 RelativePosition relPos( da.negativePosition() );
341 Measure pad( relPos.verticalPadding() );
342 pad.setValue( i );
343 relPos.setVerticalPadding( pad );
344 da.setNegativePosition( relPos );
345 setAttributes( da );
346
347 m_chart->update();
348 }
349
on_labelLE_textEdited(const QString & text)350 void DataValueSettings::Private::on_labelLE_textEdited( const QString & text )
351 {
352 DataValueAttributes da( attributes() );
353 da.setDataLabel( text.isEmpty() ? QString() : text );
354 setAttributes( da );
355
356 m_chart->update();
357 }
358
on_prefixLE_textEdited(const QString & text)359 void DataValueSettings::Private::on_prefixLE_textEdited( const QString & text )
360 {
361 DataValueAttributes da( attributes() );
362 da.setPrefix( text.isEmpty() ? QString() : text );
363 setAttributes( da );
364
365 m_chart->update();
366 }
367
on_suffixLE_textEdited(const QString & text)368 void DataValueSettings::Private::on_suffixLE_textEdited( const QString & text )
369 {
370 DataValueAttributes da( attributes() );
371 da.setSuffix( text.isEmpty() ? QString() : text );
372 setAttributes( da );
373
374 m_chart->update();
375 }
376
currentIndex() const377 const QModelIndex DataValueSettings::Private::currentIndex() const
378 {
379 const int dataset = ui->scopeBarDatasetSB->value();
380 const int item = ui->scopeBarItemSB->value();
381 Q_ASSERT( m_chart );
382 Q_ASSERT( m_chart->coordinatePlane() );
383 AbstractDiagram *diag = m_chart->coordinatePlane()->diagram();
384 return diag->model()->index( item, dataset, QModelIndex() );
385 }
386
attributes() const387 const KChart::DataValueAttributes DataValueSettings::Private::attributes() const
388 {
389 Q_ASSERT( m_chart );
390 Q_ASSERT( m_chart->coordinatePlane() );
391 AbstractDiagram *diag = m_chart->coordinatePlane()->diagram();
392 DataValueAttributes attr = diag->dataValueAttributes();
393 if ( ui->scopeOneBarRB->isChecked() ) {
394 attr = diag->dataValueAttributes( currentIndex() );
395 }
396 else if ( ui->scopeDatasetRB->isChecked() ) {
397 attr = diag->dataValueAttributes( ui->scopeDatasetSB->value() );
398 }
399 attr.setShowRepetitiveDataLabels( true );
400 return attr;
401 }
402
setAttributes(const KChart::DataValueAttributes & da)403 void DataValueSettings::Private::setAttributes( const KChart::DataValueAttributes& da )
404 {
405 Q_ASSERT( m_chart );
406 Q_ASSERT( m_chart->coordinatePlane() );
407 AbstractDiagram *diag = m_chart->coordinatePlane()->diagram();
408 if ( ui->scopeOneBarRB->isChecked() )
409 diag->setDataValueAttributes( currentIndex(), da );
410 else if ( ui->scopeDatasetRB->isChecked() )
411 diag->setDataValueAttributes( ui->scopeDatasetSB->value(), da );
412 else
413 diag->setDataValueAttributes( da );
414 }
415
416 // just a convenience method:
417 // In the combo box we have the text "( Default Value )" instead of "Unknown Position"
418 // because by setting a position to unknown we get KD Chart to use the
419 // diagram-specific default positions.
positionToScreenName(const Position & pos) const420 const char* DataValueSettings::Private::positionToScreenName( const Position& pos ) const
421 {
422 static const char* defaultPositionName = "( Default Value )";
423 if ( pos.isUnknown() )
424 return defaultPositionName;
425 return pos.name();
426 }
427
alignmentFromScreeName(const QString & name) const428 const Qt::Alignment DataValueSettings::Private::alignmentFromScreeName( const QString& name ) const
429 {
430 if ( name == "Center" ) return Qt::AlignCenter;
431 if ( name == "BottomLeft" ) return Qt::AlignLeft | Qt::AlignBottom;
432 if ( name == "Bottom" ) return Qt::AlignHCenter | Qt::AlignBottom;
433 if ( name == "BottomRight" ) return Qt::AlignRight | Qt::AlignBottom;
434 if ( name == "Right" ) return Qt::AlignRight | Qt::AlignVCenter;
435 if ( name == "TopRight" ) return Qt::AlignRight | Qt::AlignTop;
436 if ( name == "Top" ) return Qt::AlignHCenter | Qt::AlignTop;
437 if ( name == "TopLeft" ) return Qt::AlignLeft | Qt::AlignTop;
438 if ( name == "Left" ) return Qt::AlignLeft | Qt::AlignVCenter;
439 return Qt::AlignCenter;
440 }
441
alignmentToScreenName(const Qt::Alignment & align) const442 const QString DataValueSettings::Private::alignmentToScreenName( const Qt::Alignment& align ) const
443 {
444 if ( align == Qt::AlignCenter ) return "Center";
445 if ( align == (Qt::AlignLeft | Qt::AlignBottom) ) return "BottomLeft";
446 if ( align == (Qt::AlignHCenter | Qt::AlignBottom) ) return "Bottom";
447 if ( align == (Qt::AlignRight | Qt::AlignBottom) ) return "BottomRight";
448 if ( align == (Qt::AlignRight | Qt::AlignVCenter) ) return "Right";
449 if ( align == (Qt::AlignRight | Qt::AlignTop) ) return "TopRight";
450 if ( align == (Qt::AlignHCenter | Qt::AlignTop) ) return "Top";
451 if ( align == (Qt::AlignLeft | Qt::AlignTop) ) return "TopLeft";
452 if ( align == (Qt::AlignLeft | Qt::AlignVCenter) ) return "Left";
453 return "Center";
454 }
455
populateWidgets()456 void DataValueSettings::Private::populateWidgets()
457 {
458 const DataValueAttributes da( attributes() );
459 const TextAttributes ta( da.textAttributes() );
460 const RelativePosition posPos( da.positivePosition() );
461 const RelativePosition negPos( da.negativePosition() );
462
463 ui->paintValuesCB->setChecked( da.isVisible() && ta.isVisible() );
464 ui->fontCombo->setCurrentFont( ta.font() );
465 ui->relativeSizeSB->setValue( static_cast<int>(ta.fontSize().value()) );
466 ui->minimumSizeSB->setValue( static_cast<int>(ta.minimalFontSize().value()) );
467 ui->rotationSB->setValue( static_cast<int>(ta.rotation()) );
468
469 ui->posPosCombo->setCurrentIndex( ui->posPosCombo->findText(
470 positionToScreenName( posPos.referencePosition() ) ) );
471 ui->posAlignCombo->setCurrentIndex( ui->posAlignCombo->findText(
472 alignmentToScreenName( posPos.alignment() ) ) );
473 ui->posPadHoriSB->setValue( static_cast<int>(posPos.horizontalPadding().value()) );
474 ui->posPadVertSB->setValue( static_cast<int>(posPos.verticalPadding().value()) );
475
476 ui->negPosCombo->setCurrentIndex( ui->negPosCombo->findText( positionToScreenName(
477 negPos.referencePosition() ) ) );
478 ui->negAlignCombo->setCurrentIndex( ui->negAlignCombo->findText(
479 alignmentToScreenName( negPos.alignment() ) ) );
480 ui->negPadHoriSB->setValue( static_cast<int>(negPos.horizontalPadding().value()) );
481 ui->negPadVertSB->setValue( static_cast<int>(negPos.verticalPadding().value()) );
482
483 ui->labelLE->setText( da.dataLabel() );
484 ui->prefixLE->setText( da.prefix() );
485 ui->suffixLE->setText( da.suffix() );
486 }
487
488 #include "datavaluesettings.moc"
489