1
/* This file is part of the KDE project
3
* Copyright (C) 2007, 2010 Inge Wallin <inge@lysator.liu.se>
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Library General Public
7
* License as published by the Free Software Foundation; either
8
* version 2 of the License, or (at your option) any later version.
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Library General Public License for more details.
15
* You should have received a copy of the GNU Library General Public License
16
* along with this library; see the file COPYING.LIB. If not, write to
17
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18
* Boston, MA 02110-1301, USA.
22
#include "ChartTool.h"
26
#include <QGridLayout>
27
#include <QToolButton>
40
#include <KoCanvasBase.h>
41
#include <KoSelection.h>
42
#include <KoShapeManager.h>
43
#include <KoPointerEvent.h>
44
#include <KoTextShapeData.h>
45
#include <KoViewConverter.h>
48
#include <KDChartChart>
49
#include <KDChartCartesianAxis>
50
#include <KDChartGridAttributes>
51
#include <KDChartAbstractCartesianDiagram>
52
#include <KDChartCartesianCoordinatePlane>
53
#include <KDChartPosition>
61
#include "ChartProxyModel.h"
62
#include "ChartConfigWidget.h"
63
#include "KDChartConvertions.h"
66
using namespace KChart;
69
class ChartTool::Private
76
QModelIndex datasetSelection;
77
QPen datasetSelectionPen;
78
QBrush datasetSelectionBrush;
81
ChartTool::Private::Private()
86
ChartTool::Private::~Private()
90
ChartTool::ChartTool( KoCanvasBase *canvas )
91
: KoToolBase( canvas ),
94
// Create QActions here.
96
QActionGroup *group = new QActionGroup(this);
97
m_foo = new QAction(KIcon("this-action"), i18n("Do something"), this);
98
m_foo->setCheckable(true);
99
group->addAction(m_foo);
100
connect( m_foo, SIGNAL(toggled(bool)), this, SLOT(catchFoo(bool)) );
102
m_bar = new QAction(KIcon("that-action"), i18n("Do something else"), this);
103
m_bar->setCheckable(true);
104
group->addAction(m_bar);
105
connect( m_foo, SIGNAL(toggled(bool)), this, SLOT(catchBar(bool)) );
108
connect( canvas->shapeManager()->selection(), SIGNAL( selectionChanged() ),
109
this, SLOT( shapeSelectionChanged() ) );
112
ChartTool::~ChartTool()
117
void ChartTool::shapeSelectionChanged()
119
KoShape *selectedShape = 0;
121
// Get the chart shape that the tool is working on.
122
// Let d->shape point to it.
123
KoSelection *selection = canvas()->shapeManager()->selection();
124
foreach ( KoShape *shape, selection->selectedShapes() ) {
125
// Find out which type of shape that the user clicked on.
126
// We support several here, since the chart shape is comprised
127
// of several subshapes (plotarea, legend)
128
d->shape = dynamic_cast<ChartShape*>( shape );
130
PlotArea *plotArea = dynamic_cast<PlotArea*>( shape );
132
selectedShape = plotArea;
133
d->shape = plotArea->parent();
136
Legend *legend = dynamic_cast<Legend*>( shape );
138
selectedShape = legend;
139
d->shape = dynamic_cast<ChartShape*>( shape->parent() );
142
// The selected shape is the chart
144
selectedShape = shape;
146
// Insert the values from the selected shape (note: not only
147
// chart shape, but also plotarea or legend) into the tool
149
if ( selectedShape ) {
150
foreach ( QWidget *w, optionWidgets() ) {
151
KoShapeConfigWidgetBase *widget = dynamic_cast<KoShapeConfigWidgetBase*>(w);
154
widget->open( selectedShape );
157
// We support only one selected chart at the time, so once
158
// we found one, we don't need to search for any more
159
// among the selected shapes.
164
// If we couldn't determine a chart shape, then there is nothing to do.
165
if ( !d->shape ) { // none found
172
void ChartTool::paint( QPainter &painter, const KoViewConverter &converter)
175
Q_UNUSED( converter );
178
void ChartTool::mousePressEvent( KoPointerEvent *event )
185
if ( !d->shape || !d->shape->kdChart() || ! d->shape->kdChart()->coordinatePlane()
186
|| !d->shape->kdChart()->coordinatePlane()->diagram() )
188
QPointF point = event->point - d->shape->position();
189
QModelIndex selection = d->shape->kdChart()->coordinatePlane()->diagram()->indexAt( point.toPoint() );
190
// Note: the dataset will always stay column() due to the transformations being
191
// done internally by the ChartProxyModel
192
int dataset = selection.column();
194
if ( d->datasetSelection.isValid() ) {
195
d->shape->kdChart()->coordinatePlane()->diagram()->setPen( d->datasetSelection.column(), d->datasetSelectionPen );
196
//d->shape->kdChart()->coordinatePlane()->diagram()->setBrush( d->datasetSelection, d->datasetSelectionBrush );
198
if ( selection.isValid() ) {
199
d->datasetSelection = selection;
201
QPen pen( Qt::DotLine );
202
pen.setColor( Qt::darkGray );
205
d->datasetSelectionBrush = d->shape->kdChart()->coordinatePlane()->diagram()->brush( selection );
206
d->datasetSelectionPen = d->shape->kdChart()->coordinatePlane()->diagram()->pen( dataset );
208
d->shape->kdChart()->coordinatePlane()->diagram()->setPen( dataset, pen );
209
//d->shape->kdChart()->coordinatePlane()->diagram()->setBrush( selection, QBrush( Qt::lightGray ) );
211
((ChartConfigWidget*)optionWidget())->selectDataset( dataset );
217
void ChartTool::mouseMoveEvent( KoPointerEvent *event )
222
void ChartTool::mouseReleaseEvent( KoPointerEvent *event )
228
void ChartTool::activate(ToolActivation, const QSet<KoShape*> &)
230
useCursor(Qt::ArrowCursor);
233
void ChartTool::deactivate()
237
// Tell the config widget to delete all open dialogs.
239
// The reason why we want to do that explicitly here is because
240
// they are connected to the models, which may disappear when the
241
// chart shape is destructed.
242
foreach (QWidget *w, optionWidgets()) {
243
ChartConfigWidget *configWidget = dynamic_cast<ChartConfigWidget*>(w);
245
configWidget->deleteSubDialogs();
250
QWidget *ChartTool::createOptionWidget()
252
ChartConfigWidget *widget = new ChartConfigWidget();
253
widget->open( d->shape );
255
connect( widget, SIGNAL( dataSetXDataRegionChanged( DataSet*, const QString& ) ),
256
this, SLOT( setDataSetXDataRegion( DataSet*, const QString& ) ) );
257
connect( widget, SIGNAL( dataSetYDataRegionChanged( DataSet*, const QString& ) ),
258
this, SLOT( setDataSetYDataRegion( DataSet*, const QString& ) ) );
259
connect( widget, SIGNAL( dataSetCustomDataRegionChanged( DataSet*, const QString& ) ),
260
this, SLOT( setDataSetCustomDataRegion( DataSet*, const QString& ) ) );
261
connect( widget, SIGNAL( dataSetLabelDataRegionChanged( DataSet*, const QString& ) ),
262
this, SLOT( setDataSetLabelDataRegion( DataSet*, const QString& ) ) );
263
connect( widget, SIGNAL( dataSetCategoryDataRegionChanged( DataSet*, const QString& ) ),
264
this, SLOT( setDataSetCategoryDataRegion( DataSet*, const QString& ) ) );
265
connect( widget, SIGNAL( dataSetChartTypeChanged( DataSet*, ChartType ) ),
266
this, SLOT( setDataSetChartType( DataSet*, ChartType ) ) );
267
connect( widget, SIGNAL( dataSetChartSubTypeChanged( DataSet*, ChartSubtype ) ),
268
this, SLOT( setDataSetChartSubType( DataSet*, ChartSubtype ) ) );
269
connect( widget, SIGNAL( datasetColorChanged( DataSet*, const QColor& ) ),
270
this, SLOT( setDataSetColor( DataSet*, const QColor& ) ) );
271
connect( widget, SIGNAL( datasetShowValuesChanged( DataSet*, bool ) ),
272
this, SLOT( setDataSetShowValues( DataSet*, bool ) ) );
273
connect( widget, SIGNAL( datasetShowLabelsChanged( DataSet*, bool ) ),
274
this, SLOT( setDataSetShowLabels( DataSet*, bool ) ) );
275
connect( widget, SIGNAL( dataSetAxisChanged( DataSet*, Axis* ) ),
276
this, SLOT( setDataSetAxis( DataSet*, Axis* ) ) );
277
connect( widget, SIGNAL( gapBetweenBarsChanged( int ) ),
278
this, SLOT( setGapBetweenBars( int ) ) );
279
connect( widget, SIGNAL( gapBetweenSetsChanged( int ) ),
280
this, SLOT( setGapBetweenSets( int ) ) );
281
connect( widget, SIGNAL( pieExplodeFactorChanged( DataSet*, int ) ),
282
this, SLOT( setPieExplodeFactor( DataSet*, int ) ) );
284
connect( widget, SIGNAL( showLegendChanged( bool ) ),
285
this, SLOT( setShowLegend( bool ) ));
287
connect( widget, SIGNAL( chartTypeChanged( ChartType ) ),
288
this, SLOT( setChartType( ChartType ) ) );
289
connect( widget, SIGNAL( chartSubTypeChanged( ChartSubtype ) ),
290
this, SLOT( setChartSubType( ChartSubtype ) ) );
291
connect( widget, SIGNAL( threeDModeToggled( bool ) ),
292
this, SLOT( setThreeDMode( bool ) ) );
293
connect( widget, SIGNAL( showTitleChanged( bool ) ),
294
this, SLOT( setShowTitle( bool ) ) );
295
connect( widget, SIGNAL( showSubTitleChanged( bool ) ),
296
this, SLOT( setShowSubTitle( bool ) ) );
297
connect( widget, SIGNAL( showFooterChanged( bool ) ),
298
this, SLOT( setShowFooter( bool ) ) );
300
connect( widget, SIGNAL( axisAdded( AxisPosition, const QString& ) ),
301
this, SLOT( addAxis( AxisPosition, const QString& ) ) );
302
connect( widget, SIGNAL( axisRemoved( Axis* ) ),
303
this, SLOT( removeAxis( Axis* ) ) );
304
connect( widget, SIGNAL( axisTitleChanged( Axis*, const QString& ) ),
305
this, SLOT( setAxisTitle( Axis*, const QString& ) ) );
306
connect( widget, SIGNAL( axisShowTitleChanged( Axis*, bool ) ),
307
this, SLOT( setAxisShowTitle( Axis*, bool ) ) );
308
connect( widget, SIGNAL( axisShowGridLinesChanged( Axis*, bool ) ),
309
this, SLOT( setAxisShowGridLines( Axis*, bool ) ) );
310
connect( widget, SIGNAL( axisUseLogarithmicScalingChanged( Axis*, bool ) ),
311
this, SLOT( setAxisUseLogarithmicScaling( Axis*, bool ) ) );
312
connect( widget, SIGNAL( axisStepWidthChanged( Axis*, qreal ) ),
313
this, SLOT( setAxisStepWidth( Axis*, qreal ) ) );
314
connect( widget, SIGNAL( axisSubStepWidthChanged( Axis*, qreal ) ),
315
this, SLOT( setAxisSubStepWidth( Axis*, qreal ) ) );
316
connect( widget, SIGNAL( axisUseAutomaticStepWidthChanged( Axis*, bool ) ),
317
this, SLOT( setAxisUseAutomaticStepWidth( Axis*, bool ) ) );
318
connect( widget, SIGNAL( axisUseAutomaticSubStepWidthChanged( Axis*, bool ) ),
319
this, SLOT( setAxisUseAutomaticSubStepWidth( Axis*, bool ) ) );
321
connect( widget, SIGNAL( legendTitleChanged( const QString& ) ),
322
this, SLOT( setLegendTitle( const QString& ) ) );
323
connect( widget, SIGNAL( legendFontChanged( const QFont& ) ),
324
this, SLOT( setLegendFont( const QFont& ) ) );
325
connect( widget, SIGNAL( legendFontSizeChanged( int ) ),
326
this, SLOT( setLegendFontSize( int ) ) );
328
connect( widget, SIGNAL( legendOrientationChanged( Qt::Orientation ) ),
329
this, SLOT( setLegendOrientation( Qt::Orientation ) ) );
330
connect( widget, SIGNAL( legendAlignmentChanged( Qt::Alignment ) ),
331
this, SLOT( setLegendAlignment( Qt::Alignment ) ) );
333
connect( widget, SIGNAL( legendFixedPositionChanged( LegendPosition ) ),
334
this, SLOT( setLegendFixedPosition( LegendPosition ) ) );
336
connect( widget, SIGNAL( legendBackgroundColorChanged( const QColor& ) ) ,
337
this, SLOT( setLegendBackgroundColor( const QColor& ) ) );
338
connect( widget, SIGNAL( legendFrameColorChanged( const QColor& ) ) ,
339
this, SLOT( setLegendFrameColor( const QColor& ) ) );
340
connect( widget, SIGNAL( legendShowFrameChanged( bool ) ) ,
341
this, SLOT( setLegendShowFrame( bool ) ) );
347
void ChartTool::setChartType( ChartType type, ChartSubtype subtype )
349
Q_ASSERT( d->shape );
353
d->shape->setChartType( type );
354
d->shape->setChartSubType( subtype );
356
d->shape->legend()->update();
358
foreach (QWidget *w, optionWidgets())
363
void ChartTool::setChartSubType( ChartSubtype subtype )
365
Q_ASSERT( d->shape );
369
d->shape->setChartSubType( subtype );
374
void ChartTool::setDataSetXDataRegion( DataSet *dataSet, const QString ®ion )
379
dataSet->setXDataRegionString( region );
382
void ChartTool::setDataSetYDataRegion( DataSet *dataSet, const QString ®ion )
387
dataSet->setYDataRegionString( region );
390
void ChartTool::setDataSetCustomDataRegion( DataSet *dataSet, const QString ®ion )
395
dataSet->setCustomDataRegionString( region );
398
void ChartTool::setDataSetLabelDataRegion( DataSet *dataSet, const QString ®ion )
403
dataSet->setLabelDataRegionString( region );
406
void ChartTool::setDataSetCategoryDataRegion( DataSet *dataSet, const QString ®ion )
411
dataSet->setCategoryDataRegionString( region );
415
void ChartTool::setDataSetChartType( DataSet *dataSet, ChartType type )
420
dataSet->setChartType( type );
422
d->shape->legend()->update();
425
void ChartTool::setDataSetChartSubType( DataSet *dataSet, ChartSubtype subType )
429
dataSet->setChartSubType( subType );
434
void ChartTool::setDataSetColor( DataSet *dataSet, const QColor& color )
439
dataSet->setColor( color );
443
void ChartTool::setDataSetAxis( DataSet *dataSet, Axis *axis )
445
if ( !dataSet || !axis )
448
dataSet->attachedAxis()->detachDataSet( dataSet );
449
axis->attachDataSet( dataSet );
453
void ChartTool::setDataSetShowValues( DataSet *dataSet, bool b )
458
dataSet->setShowValues( b );
462
void ChartTool::setDataSetShowLabels( DataSet *dataSet, bool b )
467
dataSet->setShowLabels( b );
472
void ChartTool::setThreeDMode( bool threeD )
474
Q_ASSERT( d->shape );
478
d->shape->setThreeD( threeD );
482
void ChartTool::setShowTitle( bool show )
484
Q_ASSERT( d->shape );
488
d->shape->showTitle(show);
492
void ChartTool::setShowSubTitle( bool show )
494
Q_ASSERT( d->shape );
498
d->shape->showSubTitle(show);
502
void ChartTool::setShowFooter( bool show )
504
Q_ASSERT( d->shape );
508
d->shape->showFooter(show);
512
void ChartTool::setDataDirection( Qt::Orientation direction )
514
Q_ASSERT( d->shape );
518
d->shape->proxyModel()->setDataDirection( direction );
519
d->shape->relayout();
522
void ChartTool::setFirstRowIsLabel( bool b )
524
Q_ASSERT( d->shape );
526
d->shape->proxyModel()->setFirstRowIsLabel( b );
527
d->shape->relayout();
530
void ChartTool::setFirstColumnIsLabel( bool b )
532
Q_ASSERT( d->shape );
534
d->shape->proxyModel()->setFirstColumnIsLabel( b );
536
d->shape->relayout();
540
void ChartTool::setLegendTitle( const QString &title )
542
Q_ASSERT( d->shape );
543
Q_ASSERT( d->shape->legend() );
545
d->shape->legend()->setTitle( title );
546
d->shape->legend()->update();
549
void ChartTool::setLegendFont( const QFont &font )
551
Q_ASSERT( d->shape );
552
Q_ASSERT( d->shape->legend() );
554
// There only is a general font, for the legend items and the legend title
555
d->shape->legend()->setFont( font );
556
d->shape->legend()->update();
559
void ChartTool::setLegendFontSize( int size )
561
Q_ASSERT( d->shape );
562
Q_ASSERT( d->shape->legend() );
564
d->shape->legend()->setFontSize( size );
565
d->shape->legend()->update();
568
void ChartTool::setLegendOrientation( Qt::Orientation orientation )
570
Q_ASSERT( d->shape );
571
Q_ASSERT( d->shape->legend() );
573
d->shape->legend()->setExpansion( QtOrientationToLegendExpansion( orientation ) );
574
d->shape->legend()->update();
577
void ChartTool::setLegendAlignment( Qt::Alignment alignment )
579
Q_ASSERT( d->shape );
580
Q_ASSERT( d->shape->legend() );
582
d->shape->legend()->setAlignment( alignment );
583
d->shape->legend()->update();
586
void ChartTool::setLegendFixedPosition( LegendPosition position )
588
Q_ASSERT( d->shape );
589
Q_ASSERT( d->shape->legend() );
591
d->shape->legend()->setLegendPosition( position );
593
foreach (QWidget *w, optionWidgets()) {
594
( ( ChartConfigWidget* ) w )->updateFixedPosition( position );
597
d->shape->legend()->update();
600
void ChartTool::setLegendBackgroundColor( const QColor& color )
602
Q_ASSERT( d->shape );
603
Q_ASSERT( d->shape->legend() );
605
d->shape->legend()->setBackgroundColor( color );
606
d->shape->legend()->update();
609
void ChartTool::setLegendFrameColor( const QColor& color )
611
Q_ASSERT( d->shape );
612
Q_ASSERT( d->shape->legend() );
614
d->shape->legend()->setFrameColor( color );
615
d->shape->legend()->update();
618
void ChartTool::setLegendShowFrame( bool show )
620
Q_ASSERT( d->shape );
621
Q_ASSERT( d->shape->legend() );
623
d->shape->legend()->setShowFrame( show );
624
d->shape->legend()->update();
628
void ChartTool::addAxis( AxisPosition position, const QString& title )
630
Q_ASSERT( d->shape );
632
Axis *axis = new Axis( d->shape->plotArea() );
633
axis->setPosition( position );
634
axis->setTitleText( title );
636
d->shape->plotArea()->addAxis( axis );
637
d->shape->updateChildrenPositions();
641
void ChartTool::removeAxis( Axis *axis )
643
Q_ASSERT( d->shape );
645
d->shape->plotArea()->removeAxis( axis );
649
void ChartTool::setAxisTitle( Axis *axis, const QString& title )
651
axis->setTitleText( title );
655
void ChartTool::setAxisShowTitle( Axis *axis, bool show )
657
Q_ASSERT( d->shape );
659
axis->title()->setVisible( show );
663
void ChartTool::setAxisShowGridLines( Axis *axis, bool b )
665
axis->setShowMajorGrid( b );
666
axis->setShowMinorGrid( b );
670
void ChartTool::setAxisUseLogarithmicScaling( Axis *axis, bool b )
672
axis->setScalingLogarithmic( b );
676
void ChartTool::setAxisStepWidth( Axis *axis, qreal width )
678
axis->setMajorInterval( width );
682
void ChartTool::setAxisSubStepWidth( Axis *axis, qreal width )
684
axis->setMinorInterval( width );
688
void ChartTool::setAxisUseAutomaticStepWidth( Axis *axis, bool automatic )
690
axis->setUseAutomaticMajorInterval( automatic );
694
void ChartTool::setAxisUseAutomaticSubStepWidth( Axis *axis, bool automatic )
696
axis->setUseAutomaticMinorInterval( automatic );
701
void ChartTool::setGapBetweenBars( int percent )
703
Q_ASSERT( d->shape );
705
d->shape->plotArea()->setGapBetweenBars( percent );
709
void ChartTool::setGapBetweenSets( int percent )
711
Q_ASSERT( d->shape );
713
d->shape->plotArea()->setGapBetweenSets( percent );
717
void ChartTool::setPieExplodeFactor( DataSet *dataSet, int percent )
719
Q_ASSERT( d->shape );
721
d->shape->plotArea()->setPieExplodeFactor( dataSet, percent );
725
void ChartTool::setShowLegend( bool b )
727
Q_ASSERT( d->shape );
729
d->shape->legend()->setVisible( b );
730
d->shape->legend()->update();
733
#include "ChartTool.moc"