~ubuntu-branches/ubuntu/oneiric/koffice/oneiric-updates

« back to all changes in this revision

Viewing changes to kchart/kdchart/src/KDChartAbstractCoordinatePlane.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alessandro Ghersi
  • Date: 2010-10-27 17:52:57 UTC
  • mfrom: (0.12.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20101027175257-s04zqqk5bs8ckm9o
Tags: 1:2.2.83-0ubuntu1
* Merge with Debian git remaining changes:
 - Add build-deps on librcps-dev, opengtl-dev, libqtgtl-dev, freetds-dev,
   create-resources, libspnav-dev
 - Remove needless build-dep on libwv2-dev
 - koffice-libs recommends create-resources
 - krita recommends pstoedit
 - Keep our patches
* New upstream release 2.3 beta 3
  - Remove debian/patches fixed by upstream
  - Update install files

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/****************************************************************************
2
 
 ** Copyright (C) 2007 Klaralvdalens Datakonsult AB.  All rights reserved.
3
 
 **
4
 
 ** This file is part of the KD Chart library.
5
 
 **
6
 
 ** This file may be used under the terms of the GNU General Public
7
 
 ** License versions 2.0 or 3.0 as published by the Free Software
8
 
 ** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3
9
 
 ** included in the packaging of this file.  Alternatively you may (at
10
 
 ** your option) use any later version of the GNU General Public
11
 
 ** License if such license has been publicly approved by
12
 
 ** Klarälvdalens Datakonsult AB (or its successors, if any).
13
 
 ** 
14
 
 ** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
15
 
 ** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
16
 
 ** A PARTICULAR PURPOSE. Klarälvdalens Datakonsult AB reserves all rights
17
 
 ** not expressly granted herein.
18
 
 ** 
19
 
 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
20
 
 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21
 
 **
22
 
 **********************************************************************/
23
 
 
24
 
#include "KDChartAbstractCoordinatePlane.h"
25
 
#include "KDChartAbstractCoordinatePlane_p.h"
26
 
 
27
 
#include <QGridLayout>
28
 
#include <QRubberBand>
29
 
#include <QMouseEvent>
30
 
 
31
 
#include "KDChartChart.h"
32
 
#include "KDChartGridAttributes.h"
33
 
 
34
 
#include <KDABLibFakes>
35
 
 
36
 
 
37
 
using namespace KDChart;
38
 
 
39
 
#define d d_func()
40
 
 
41
 
AbstractCoordinatePlane::Private::Private()
42
 
    : AbstractArea::Private()
43
 
    , parent( 0 )
44
 
    , grid( 0 )
45
 
    , referenceCoordinatePlane( 0 )
46
 
    , enableRubberBandZooming( false )
47
 
    , rubberBand( 0 )
48
 
{
49
 
    // this bloc left empty intentionally
50
 
}
51
 
 
52
 
 
53
 
AbstractCoordinatePlane::AbstractCoordinatePlane ( KDChart::Chart* parent )
54
 
    : AbstractArea ( new Private() )
55
 
{
56
 
    d->parent = parent;
57
 
    d->init();
58
 
}
59
 
 
60
 
AbstractCoordinatePlane::~AbstractCoordinatePlane()
61
 
{
62
 
    emit destroyedCoordinatePlane( this );
63
 
}
64
 
 
65
 
void AbstractCoordinatePlane::init()
66
 
{
67
 
    d->initialize();  // virtual method to init the correct grid: cartesian, polar, ...
68
 
    connect( this, SIGNAL(internal_geometryChanged( QRect, QRect )),
69
 
             this, SIGNAL(geometryChanged(          QRect, QRect )),
70
 
             Qt::QueuedConnection );
71
 
}
72
 
 
73
 
void AbstractCoordinatePlane::addDiagram ( AbstractDiagram* diagram )
74
 
{
75
 
    // diagrams are invisible and paint through their paint() method
76
 
    diagram->hide();
77
 
 
78
 
    d->diagrams.append( diagram );
79
 
    diagram->setParent( d->parent );
80
 
    diagram->setCoordinatePlane( this );
81
 
    layoutDiagrams();
82
 
    layoutPlanes(); // there might be new axes, etc
83
 
    connect( diagram, SIGNAL( modelsChanged() ), this, SLOT( layoutPlanes() ) );
84
 
    update();
85
 
}
86
 
 
87
 
/*virtual*/
88
 
void AbstractCoordinatePlane::replaceDiagram ( AbstractDiagram* diagram, AbstractDiagram* oldDiagram_ )
89
 
{
90
 
    if( diagram && oldDiagram_ != diagram ){
91
 
        AbstractDiagram* oldDiagram = oldDiagram_;
92
 
        if( d->diagrams.count() ){
93
 
            if( ! oldDiagram ){
94
 
                oldDiagram = d->diagrams.first();
95
 
                if( oldDiagram == diagram )
96
 
                    return;
97
 
            }
98
 
            takeDiagram( oldDiagram );
99
 
        }
100
 
        delete oldDiagram;
101
 
        addDiagram( diagram );
102
 
        layoutDiagrams();
103
 
        layoutPlanes(); // there might be new axes, etc
104
 
        update();
105
 
    }
106
 
}
107
 
 
108
 
/*virtual*/
109
 
void AbstractCoordinatePlane::takeDiagram ( AbstractDiagram* diagram )
110
 
{
111
 
    const int idx = d->diagrams.indexOf( diagram );
112
 
    if( idx != -1 ){
113
 
        d->diagrams.removeAt( idx );
114
 
        diagram->setParent( 0 );
115
 
        diagram->setCoordinatePlane( 0 );
116
 
        disconnect( diagram, SIGNAL( modelsChanged() ), this, SLOT( layoutPlanes() ) );
117
 
        layoutDiagrams();
118
 
        update();
119
 
    }
120
 
}
121
 
 
122
 
 
123
 
AbstractDiagram* AbstractCoordinatePlane::diagram()
124
 
{
125
 
    if ( d->diagrams.isEmpty() )
126
 
    {
127
 
        return 0;
128
 
    } else {
129
 
        return d->diagrams.first();
130
 
    }
131
 
}
132
 
 
133
 
AbstractDiagramList AbstractCoordinatePlane::diagrams()
134
 
{
135
 
    return d->diagrams;
136
 
}
137
 
 
138
 
ConstAbstractDiagramList AbstractCoordinatePlane::diagrams() const
139
 
{
140
 
    ConstAbstractDiagramList list;
141
 
#ifndef QT_NO_STL
142
 
    qCopy( d->diagrams.begin(), d->diagrams.end(), std::back_inserter( list ) );
143
 
#else
144
 
    Q_FOREACH( AbstractDiagram * a, d->diagrams )
145
 
        list.push_back( a );
146
 
#endif
147
 
    return list;
148
 
}
149
 
 
150
 
QSize KDChart::AbstractCoordinatePlane::minimumSizeHint() const
151
 
{
152
 
    return QSize( 200, 200 );
153
 
}
154
 
 
155
 
 
156
 
QSizePolicy KDChart::AbstractCoordinatePlane::sizePolicy() const
157
 
{
158
 
    return QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding );
159
 
}
160
 
 
161
 
void KDChart::AbstractCoordinatePlane::setGlobalGridAttributes( const GridAttributes& a )
162
 
{
163
 
    d->gridAttributes = a;
164
 
    update();
165
 
}
166
 
 
167
 
GridAttributes KDChart::AbstractCoordinatePlane::globalGridAttributes() const
168
 
{
169
 
    return d->gridAttributes;
170
 
}
171
 
 
172
 
KDChart::DataDimensionsList KDChart::AbstractCoordinatePlane::gridDimensionsList()
173
 
{
174
 
    //KDChart::DataDimensionsList l( d->grid->updateData( this ) );
175
 
    //qDebug() << "AbstractCoordinatePlane::gridDimensionsList() Y-range:" << l.last().end - l.last().start << "   step width:" << l.last().stepWidth;
176
 
    //qDebug() << "AbstractCoordinatePlane::gridDimensionsList() X-range:" << l.first().end - l.first().start << "   step width:" << l.first().stepWidth;
177
 
    return d->grid->updateData( this );
178
 
}
179
 
 
180
 
void KDChart::AbstractCoordinatePlane::setGridNeedsRecalculate()
181
 
{
182
 
    d->grid->setNeedRecalculate();
183
 
}
184
 
 
185
 
void KDChart::AbstractCoordinatePlane::setReferenceCoordinatePlane( AbstractCoordinatePlane * plane )
186
 
{
187
 
    d->referenceCoordinatePlane = plane;
188
 
}
189
 
 
190
 
AbstractCoordinatePlane * KDChart::AbstractCoordinatePlane::referenceCoordinatePlane( ) const
191
 
{
192
 
    return d->referenceCoordinatePlane;
193
 
}
194
 
 
195
 
void KDChart::AbstractCoordinatePlane::setParent( KDChart::Chart* parent )
196
 
{
197
 
    d->parent = parent;
198
 
}
199
 
 
200
 
const KDChart::Chart* KDChart::AbstractCoordinatePlane::parent() const
201
 
{
202
 
    return d->parent;
203
 
}
204
 
 
205
 
KDChart::Chart* KDChart::AbstractCoordinatePlane::parent()
206
 
{
207
 
    return d->parent;
208
 
}
209
 
 
210
 
/* pure virtual in QLayoutItem */
211
 
bool KDChart::AbstractCoordinatePlane::isEmpty() const
212
 
{
213
 
    return false; // never empty!
214
 
    // coordinate planes with no associated diagrams
215
 
    // are showing a default grid of ()1..10, 1..10) stepWidth 1
216
 
}
217
 
/* pure virtual in QLayoutItem */
218
 
Qt::Orientations KDChart::AbstractCoordinatePlane::expandingDirections() const
219
 
{
220
 
    return Qt::Vertical | Qt::Horizontal;
221
 
}
222
 
/* pure virtual in QLayoutItem */
223
 
QSize KDChart::AbstractCoordinatePlane::maximumSize() const
224
 
{
225
 
    // No maximum size set. Especially not parent()->size(), we are not layouting
226
 
    // to the parent widget's size when using Chart::paint()!
227
 
    return QSize(QLAYOUTSIZE_MAX, QLAYOUTSIZE_MAX);
228
 
}
229
 
/* pure virtual in QLayoutItem */
230
 
QSize KDChart::AbstractCoordinatePlane::minimumSize() const
231
 
{
232
 
    return QSize(60, 60); // this default can be overwritten by derived classes
233
 
}
234
 
/* pure virtual in QLayoutItem */
235
 
QSize KDChart::AbstractCoordinatePlane::sizeHint() const
236
 
{
237
 
    // we return our maxiumu (which is the full size of the Chart)
238
 
    // even if we know the plane will be smaller
239
 
    return maximumSize();
240
 
}
241
 
/* pure virtual in QLayoutItem */
242
 
void KDChart::AbstractCoordinatePlane::setGeometry( const QRect& r )
243
 
{
244
 
//    qDebug() << "KDChart::AbstractCoordinatePlane::setGeometry(" << r << ") called";
245
 
    if( d->geometry != r ){
246
 
        //qDebug() << "entering KDChart::AbstractCoordinatePlane::setGeometry(" << r << ")";
247
 
        // inform the outside word by Signal geometryChanged()
248
 
        // via a queued connection to internal_geometryChanged()
249
 
        emit internal_geometryChanged( d->geometry, r );
250
 
 
251
 
        d->geometry = r;
252
 
        // Note: We do *not* call update() here
253
 
        //       because it would invoke KDChart::update() recursively.
254
 
        //qDebug() << "leaving  KDChart::AbstractCoordinatePlane::setGeometry(" << r << ")";
255
 
    }
256
 
}
257
 
/* pure virtual in QLayoutItem */
258
 
QRect KDChart::AbstractCoordinatePlane::geometry() const
259
 
{
260
 
    return d->geometry;
261
 
}
262
 
 
263
 
void KDChart::AbstractCoordinatePlane::update()
264
 
{
265
 
    //qDebug("KDChart::AbstractCoordinatePlane::update() called");
266
 
    emit needUpdate();
267
 
}
268
 
 
269
 
void KDChart::AbstractCoordinatePlane::relayout()
270
 
{
271
 
    //qDebug("KDChart::AbstractCoordinatePlane::relayout() called");
272
 
    emit needRelayout();
273
 
}
274
 
 
275
 
void KDChart::AbstractCoordinatePlane::layoutPlanes()
276
 
{
277
 
    //qDebug("KDChart::AbstractCoordinatePlane::relayout() called");
278
 
    emit needLayoutPlanes();
279
 
}
280
 
 
281
 
void KDChart::AbstractCoordinatePlane::setRubberBandZoomingEnabled( bool enable )
282
 
{
283
 
    d->enableRubberBandZooming = enable;
284
 
 
285
 
    if( !enable && d->rubberBand != 0 )
286
 
    {
287
 
        delete d->rubberBand;
288
 
        d->rubberBand = 0;
289
 
    }
290
 
}
291
 
 
292
 
bool KDChart::AbstractCoordinatePlane::isRubberBandZoomingEnabled() const
293
 
{
294
 
    return d->enableRubberBandZooming;
295
 
}
296
 
 
297
 
void KDChart::AbstractCoordinatePlane::mousePressEvent( QMouseEvent* event )
298
 
{
299
 
    if( event->button() == Qt::LeftButton )
300
 
    {
301
 
        if( d->enableRubberBandZooming && d->rubberBand == 0 )
302
 
            d->rubberBand = new QRubberBand( QRubberBand::Rectangle, qobject_cast< QWidget* >( parent() ) );
303
 
 
304
 
        if( d->rubberBand != 0 )
305
 
        {
306
 
            d->rubberBandOrigin = event->pos();
307
 
            d->rubberBand->setGeometry( QRect( event->pos(), QSize() ) );
308
 
            d->rubberBand->show();
309
 
 
310
 
            event->accept();
311
 
        }
312
 
    }
313
 
    else if( event->button() == Qt::RightButton )
314
 
    {
315
 
        if( d->enableRubberBandZooming && !d->rubberBandZoomConfigHistory.isEmpty() )
316
 
        {
317
 
            // restore the last config from the stack
318
 
            ZoomParameters config = d->rubberBandZoomConfigHistory.pop();
319
 
            setZoomFactorX( config.xFactor );
320
 
            setZoomFactorY( config.yFactor );
321
 
            setZoomCenter( config.center() );
322
 
 
323
 
            QWidget* const p = qobject_cast< QWidget* >( parent() );
324
 
            if( p != 0 )
325
 
                p->update();
326
 
 
327
 
            event->accept();
328
 
        }
329
 
    }
330
 
 
331
 
    KDAB_FOREACH( AbstractDiagram * a, d->diagrams )
332
 
    {
333
 
        a->mousePressEvent( event );
334
 
    }
335
 
}
336
 
 
337
 
void KDChart::AbstractCoordinatePlane::mouseDoubleClickEvent( QMouseEvent* event )
338
 
{
339
 
    if( event->button() == Qt::RightButton )
340
 
    {
341
 
        // othewise the second click gets lost
342
 
        // which is pretty annoying when zooming out fast
343
 
        mousePressEvent( event );
344
 
    }
345
 
    KDAB_FOREACH( AbstractDiagram * a, d->diagrams )
346
 
    {
347
 
        a->mouseDoubleClickEvent( event );
348
 
    }
349
 
}
350
 
 
351
 
void KDChart::AbstractCoordinatePlane::mouseReleaseEvent( QMouseEvent* event )
352
 
{
353
 
    if( d->rubberBand != 0 )
354
 
    {
355
 
        // save the old config on the stack
356
 
        d->rubberBandZoomConfigHistory.push( ZoomParameters( zoomFactorX(), zoomFactorY(), zoomCenter() ) );
357
 
 
358
 
        // this is the height/width of the rubber band in pixel space
359
 
        const double rubberWidth = static_cast< double >( d->rubberBand->width() );
360
 
        const double rubberHeight = static_cast< double >( d->rubberBand->height() );
361
 
 
362
 
        if( rubberWidth > 0.0 && rubberHeight > 0.0 )
363
 
        {
364
 
            // this is the center of the rubber band in pixel space
365
 
            const double rubberCenterX = static_cast< double >( d->rubberBand->geometry().center().x() - geometry().x() );
366
 
            const double rubberCenterY = static_cast< double >( d->rubberBand->geometry().center().y() - geometry().y() );
367
 
 
368
 
            // this is the height/width of the plane in pixel space
369
 
            const double myWidth = static_cast< double >( geometry().width() );
370
 
            const double myHeight = static_cast< double >( geometry().height() );
371
 
 
372
 
            // this describes the new center of zooming, relative to the plane pixel space
373
 
            const double newCenterX = rubberCenterX / myWidth / zoomFactorX() + zoomCenter().x() - 0.5 / zoomFactorX();
374
 
            const double newCenterY = rubberCenterY / myHeight / zoomFactorY() + zoomCenter().y() - 0.5 / zoomFactorY();
375
 
 
376
 
            // this will be the new zoom factor
377
 
            const double newZoomFactorX = zoomFactorX() * myWidth / rubberWidth;
378
 
            const double newZoomFactorY = zoomFactorY() * myHeight / rubberHeight;
379
 
 
380
 
            // and this the new center
381
 
            const QPointF newZoomCenter( newCenterX, newCenterY );
382
 
 
383
 
            setZoomFactorX( newZoomFactorX );
384
 
            setZoomFactorY( newZoomFactorY );
385
 
            setZoomCenter( newZoomCenter );
386
 
        }
387
 
 
388
 
        d->rubberBand->parentWidget()->update();
389
 
        delete d->rubberBand;
390
 
        d->rubberBand = 0;
391
 
 
392
 
        event->accept();
393
 
    }
394
 
 
395
 
    KDAB_FOREACH( AbstractDiagram * a, d->diagrams )
396
 
    {
397
 
        a->mouseReleaseEvent( event );
398
 
    }
399
 
}
400
 
 
401
 
void KDChart::AbstractCoordinatePlane::mouseMoveEvent( QMouseEvent* event )
402
 
{
403
 
    if( d->rubberBand != 0 )
404
 
    {
405
 
        const QRect normalized = QRect( d->rubberBandOrigin, event->pos() ).normalized();
406
 
        d->rubberBand->setGeometry( normalized &  geometry() );
407
 
 
408
 
        event->accept();
409
 
    }
410
 
 
411
 
    KDAB_FOREACH( AbstractDiagram * a, d->diagrams )
412
 
    {
413
 
        a->mouseMoveEvent( event );
414
 
    }
415
 
}
416
 
 
417
 
#if QT_VERSION < 0x040400 || defined(Q_COMPILER_MANGLES_RETURN_TYPE)
418
 
const
419
 
#endif
420
 
bool KDChart::AbstractCoordinatePlane::isVisiblePoint( const QPointF& point ) const
421
 
{
422
 
    return d->isVisiblePoint( this, point );
423
 
}
424
 
 
425
 
AbstractCoordinatePlane* KDChart::AbstractCoordinatePlane::sharedAxisMasterPlane( QPainter* p )
426
 
{
427
 
    Q_UNUSED( p );
428
 
    return this;
429
 
}
430
 
 
431
 
#if !defined(QT_NO_DEBUG_STREAM)
432
 
#include "KDChartEnums.h"
433
 
 
434
 
QDebug KDChart::operator<<( QDebug stream, const DataDimension& r )
435
 
{
436
 
    stream << "DataDimension("
437
 
           << " start=" << r.start
438
 
           << " end=" << r.end
439
 
           << " sequence=" << KDChartEnums::granularitySequenceToString( r.sequence )
440
 
           << " isCalculated=" << r.isCalculated
441
 
           << " calcMode=" << ( r.calcMode == AbstractCoordinatePlane::Logarithmic ? "Logarithmic" : "Linear" )
442
 
           << " stepWidth=" << r.stepWidth
443
 
           << " subStepWidth=" << r.subStepWidth
444
 
           << " )";
445
 
    return stream;
446
 
}
447
 
#endif
448
 
 
449
 
#undef d