~ubuntu-branches/ubuntu/utopic/qgis/utopic

« back to all changes in this revision

Viewing changes to src/app/gps/qwtpolar/qwt_polar_grid.cpp

  • Committer: Package Import Robot
  • Author(s): Francesco Paolo Lovergine
  • Date: 2012-04-24 15:12:20 UTC
  • mfrom: (3.1.9 sid)
  • Revision ID: package-import@ubuntu.com-20120424151220-r88g00af5fpn5fc3
Tags: 1.7.4+1.7.5~20120320-1
The "Sometimes they come back" release.

* Branching from Qgis tree and adapting to current Debian Policy and
  standards. The target tree is currently set to release-1.7.
  (closes: #661491, #606304, #615683, #616182, #600308)
* Policy bumped to 3.9.3.
* Moving to debhelper compatibility level 9.
* Source format is now 3.0 with quilt support.
* Merged with 2bf42287 upstream git snapshot.
* Migrated to dh_python2 instead of python-central.
  (closes: #617048)
* Snapshot in qgis.org release-1.7: c936d031
* Added an automagic creation of a lintian override for sqlite embedding.
  This is required for uploading currently.
* Added missing ${misc:Depends} to make lintian happy.
* Copyright notes updated and debian/copyright moved to format 1.0.
* More licenses notices now reported in debian/copyright. Thanks ftpmasters.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
 
2
 * QwtPolar Widget Library
 
3
 * Copyright (C) 2008   Uwe Rathmann
 
4
 *
 
5
 * This library is free software; you can redistribute it and/or
 
6
 * modify it under the terms of the Qwt License, Version 1.0
 
7
 *****************************************************************************/
 
8
 
 
9
#include <cfloat>
 
10
#include <cmath>
 
11
#include <qpainter.h>
 
12
#include <qpen.h>
 
13
#include "qwt_painter.h"
 
14
#include "qwt_text.h"
 
15
#include "qwt_clipper.h"
 
16
#include "qwt_scale_map.h"
 
17
#include "qwt_scale_engine.h"
 
18
#include "qwt_scale_div.h"
 
19
#include "qwt_scale_draw.h"
 
20
#include "qwt_round_scale_draw.h"
 
21
#include "qwt_polar_grid.h"
 
22
 
 
23
static inline bool isClose( double value1, double value2 )
 
24
{
 
25
  return qwtAbs( value1 - value2 ) < DBL_EPSILON;
 
26
}
 
27
 
 
28
class QwtPolarGrid::AxisData
 
29
{
 
30
  public:
 
31
    AxisData():
 
32
        isVisible( false ),
 
33
        scaleDraw( NULL )
 
34
    {
 
35
    }
 
36
    ~AxisData()
 
37
    {
 
38
      delete scaleDraw;
 
39
    }
 
40
 
 
41
    bool isVisible;
 
42
    mutable QwtAbstractScaleDraw *scaleDraw;
 
43
    QPen pen;
 
44
    QFont font;
 
45
};
 
46
 
 
47
class QwtPolarGrid::GridData
 
48
{
 
49
  public:
 
50
    GridData():
 
51
        isVisible( true ),
 
52
        isMinorVisible( false )
 
53
    {
 
54
    }
 
55
 
 
56
    bool isVisible;
 
57
    bool isMinorVisible;
 
58
    QwtScaleDiv scaleDiv;
 
59
 
 
60
    QPen majorPen;
 
61
    QPen minorPen;
 
62
};
 
63
 
 
64
class QwtPolarGrid::PrivateData
 
65
{
 
66
  public:
 
67
    GridData gridData[QwtPolar::ScaleCount];
 
68
    AxisData axisData[QwtPolar::AxesCount];
 
69
    int displayFlags;
 
70
    int attributes;
 
71
};
 
72
 
 
73
/*!
 
74
   \brief Constructor
 
75
 
 
76
   Enables major and disables minor grid lines.
 
77
   The azimuth and right radial axis are visible. all other axes
 
78
   are hidden. Autoscaling is enabled.
 
79
*/
 
80
QwtPolarGrid::QwtPolarGrid():
 
81
    QwtPolarItem( QwtText( "Grid" ) )
 
82
{
 
83
  d_data = new PrivateData;
 
84
 
 
85
  for ( int axisId = 0; axisId < QwtPolar::AxesCount; axisId++ )
 
86
  {
 
87
    AxisData &axis = d_data->axisData[axisId];
 
88
    switch ( axisId )
 
89
    {
 
90
      case QwtPolar::AxisAzimuth:
 
91
      {
 
92
        axis.scaleDraw = new QwtRoundScaleDraw;
 
93
        axis.scaleDraw->setTickLength( QwtScaleDiv::MinorTick, 2 );
 
94
        axis.scaleDraw->setTickLength( QwtScaleDiv::MediumTick, 2 );
 
95
        axis.scaleDraw->setTickLength( QwtScaleDiv::MajorTick, 4 );
 
96
        axis.isVisible = true;
 
97
        break;
 
98
      }
 
99
      case QwtPolar::AxisLeft:
 
100
      {
 
101
        QwtScaleDraw *scaleDraw = new QwtScaleDraw;
 
102
        scaleDraw->setAlignment( QwtScaleDraw::BottomScale );
 
103
 
 
104
        axis.scaleDraw = scaleDraw;
 
105
        axis.isVisible = false;
 
106
        break;
 
107
      }
 
108
      case QwtPolar::AxisRight:
 
109
      {
 
110
        QwtScaleDraw *scaleDraw = new QwtScaleDraw;
 
111
        scaleDraw->setAlignment( QwtScaleDraw::BottomScale );
 
112
 
 
113
        axis.scaleDraw = scaleDraw;
 
114
        axis.isVisible = true;
 
115
        break;
 
116
      }
 
117
      case QwtPolar::AxisTop:
 
118
      {
 
119
        QwtScaleDraw *scaleDraw = new QwtScaleDraw;
 
120
        scaleDraw->setAlignment( QwtScaleDraw::LeftScale );
 
121
 
 
122
        axis.scaleDraw = scaleDraw;
 
123
        axis.isVisible = false;
 
124
        break;
 
125
      }
 
126
      case QwtPolar::AxisBottom:
 
127
      {
 
128
        QwtScaleDraw *scaleDraw = new QwtScaleDraw;
 
129
        scaleDraw->setAlignment( QwtScaleDraw::LeftScale );
 
130
 
 
131
        axis.scaleDraw = scaleDraw;
 
132
        axis.isVisible = true;
 
133
        break;
 
134
      }
 
135
      default:;
 
136
    }
 
137
  }
 
138
 
 
139
  d_data->attributes = AutoScaling;
 
140
 
 
141
  d_data->displayFlags = 0;
 
142
  d_data->displayFlags |= SmartOriginLabel;
 
143
  d_data->displayFlags |= HideMaxRadiusLabel;
 
144
  d_data->displayFlags |= ClipAxisBackground;
 
145
  d_data->displayFlags |= SmartScaleDraw;
 
146
  d_data->displayFlags |= ClipGridLines;
 
147
 
 
148
  setZ( 10.0 );
 
149
#if QT_VERSION >= 0x040000
 
150
  setRenderHint( RenderAntialiased, true );
 
151
#endif
 
152
}
 
153
 
 
154
//! Destructor
 
155
QwtPolarGrid::~QwtPolarGrid()
 
156
{
 
157
  delete d_data;
 
158
}
 
159
 
 
160
//! \return QwtPlotItem::Rtti_PolarGrid
 
161
int QwtPolarGrid::rtti() const
 
162
{
 
163
  return QwtPolarItem::Rtti_PolarGrid;
 
164
}
 
165
 
 
166
/*!
 
167
   Change the display flags
 
168
 
 
169
   \param flag See DisplayFlag
 
170
   \param on true/false
 
171
*/
 
172
void QwtPolarGrid::setDisplayFlag( DisplayFlag flag, bool on )
 
173
{
 
174
  if ((( d_data->displayFlags & flag ) != 0 ) != on )
 
175
  {
 
176
    if ( on )
 
177
      d_data->displayFlags |= flag;
 
178
    else
 
179
      d_data->displayFlags &= ~flag;
 
180
 
 
181
    itemChanged();
 
182
  }
 
183
}
 
184
 
 
185
/*!
 
186
   \return true, if flag is enabled
 
187
   \param flag See DisplayFlag
 
188
*/
 
189
bool QwtPolarGrid::testDisplayFlag( DisplayFlag flag ) const
 
190
{
 
191
  return ( d_data->displayFlags & flag );
 
192
}
 
193
 
 
194
/*!
 
195
  \brief Specify an attribute for the grid
 
196
 
 
197
  \param attribute Grid attribute
 
198
  \param on On/Off
 
199
 
 
200
  /sa GridAttribute, testGridAttribute(), updateScaleDiv(),
 
201
      QwtPolarPlot::zoom(), QwtPolarPlot::scaleDiv()
 
202
*/
 
203
void QwtPolarGrid::setGridAttribute( GridAttribute attribute, bool on )
 
204
{
 
205
  if ( bool( d_data->attributes & attribute ) == on )
 
206
    return;
 
207
 
 
208
  if ( on )
 
209
    d_data->attributes |= attribute;
 
210
  else
 
211
    d_data->attributes &= ~attribute;
 
212
 
 
213
  itemChanged();
 
214
}
 
215
 
 
216
/*!
 
217
    \return true, if attribute is enabled
 
218
    \sa GridAttribute, setGridAttribute()
 
219
*/
 
220
bool QwtPolarGrid::testGridAttribute( GridAttribute attribute ) const
 
221
{
 
222
  return d_data->attributes & attribute;
 
223
}
 
224
 
 
225
/*!
 
226
  Assign a pen for painting an axis
 
227
 
 
228
  \param axisId Axis id (QwtPolar::Axis)
 
229
  \param pen Pen
 
230
 
 
231
  \sa axisPen()
 
232
*/
 
233
void QwtPolarGrid::setAxisPen( int axisId, const QPen &pen )
 
234
{
 
235
  if ( axisId < 0 || axisId >= QwtPolar::AxesCount )
 
236
    return;
 
237
 
 
238
  AxisData &axisData = d_data->axisData[axisId];
 
239
  if ( axisData.pen != pen )
 
240
  {
 
241
    axisData.pen = pen;
 
242
    itemChanged();
 
243
  }
 
244
}
 
245
 
 
246
/*!
 
247
   Show/Hide grid lines for a scale
 
248
 
 
249
   \param scaleId Scale id ( QwtPolar::Scale )
 
250
   \param show true/false
 
251
*/
 
252
void QwtPolarGrid::showGrid( int scaleId, bool show )
 
253
{
 
254
  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
255
    return;
 
256
 
 
257
  GridData &grid = d_data->gridData[scaleId];
 
258
  if ( grid.isVisible != show )
 
259
  {
 
260
    grid.isVisible = show;
 
261
    itemChanged();
 
262
  }
 
263
}
 
264
 
 
265
/*!
 
266
  \return true if grid lines are enabled
 
267
  \param scaleId Scale id ( QwtPolar::Scale )
 
268
  \sa QwtPolar::Scale, showGrid()
 
269
*/
 
270
bool QwtPolarGrid::isGridVisible( int scaleId ) const
 
271
{
 
272
  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
273
    return false;
 
274
 
 
275
  return d_data->gridData[scaleId].isVisible;
 
276
}
 
277
 
 
278
/*!
 
279
   Show/Hide minor grid lines for a scale
 
280
 
 
281
   To display minor grid lines. showGrid() needs to be enabled too.
 
282
 
 
283
   \param scaleId Scale id ( QwtPolar::Scale )
 
284
   \param show true/false
 
285
 
 
286
   \sa showGrid
 
287
*/
 
288
void QwtPolarGrid::showMinorGrid( int scaleId, bool show )
 
289
{
 
290
  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
291
    return;
 
292
 
 
293
  GridData &grid = d_data->gridData[scaleId];
 
294
  if ( grid.isMinorVisible != show )
 
295
  {
 
296
    grid.isMinorVisible = show;
 
297
    itemChanged();
 
298
  }
 
299
}
 
300
 
 
301
/*!
 
302
  \return true if minor grid lines are enabled
 
303
  \param scaleId Scale id ( QwtPolar::Scale )
 
304
  \sa showMinorGrid()
 
305
*/
 
306
bool QwtPolarGrid::isMinorGridVisible( int scaleId ) const
 
307
{
 
308
  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
309
    return false;
 
310
 
 
311
  return d_data->gridData[scaleId].isMinorVisible;
 
312
}
 
313
 
 
314
/*!
 
315
  Show/Hide an axis
 
316
 
 
317
  \param axisId Axis id (QwtPolar::Axis)
 
318
  \param show true/false
 
319
 
 
320
  \sa isAxisVisible()
 
321
*/
 
322
void QwtPolarGrid::showAxis( int axisId, bool show )
 
323
{
 
324
  if ( axisId < 0 || axisId >= QwtPolar::AxesCount )
 
325
    return;
 
326
 
 
327
  AxisData &axisData = d_data->axisData[axisId];
 
328
  if ( axisData.isVisible != show )
 
329
  {
 
330
    axisData.isVisible = show;
 
331
    itemChanged();
 
332
  }
 
333
}
 
334
 
 
335
/*!
 
336
  \return true if the axis is visible
 
337
  \param axisId Axis id (QwtPolar::Axis)
 
338
 
 
339
  \sa showAxis()
 
340
*/
 
341
bool QwtPolarGrid::isAxisVisible( int axisId ) const
 
342
{
 
343
  if ( axisId < 0 || axisId >= QwtPolar::AxesCount )
 
344
    return false;
 
345
 
 
346
  return d_data->axisData[axisId].isVisible;
 
347
}
 
348
 
 
349
/*!
 
350
   Assign a pen for all axes and grid lines
 
351
 
 
352
   \param pen Pen
 
353
   \sa setMajorGridPen(), setMinorGridPen(), setAxisPen()
 
354
*/
 
355
void QwtPolarGrid::setPen( const QPen &pen )
 
356
{
 
357
  bool isChanged = false;
 
358
 
 
359
  for ( int scaleId = 0; scaleId < QwtPolar::ScaleCount; scaleId++ )
 
360
  {
 
361
    GridData &grid = d_data->gridData[scaleId];
 
362
    if ( grid.majorPen != pen || grid.minorPen != pen )
 
363
    {
 
364
      grid.majorPen = pen;
 
365
      grid.minorPen = pen;
 
366
      isChanged = true;
 
367
    }
 
368
  }
 
369
  for ( int axisId = 0; axisId < QwtPolar::AxesCount; axisId++ )
 
370
  {
 
371
    AxisData &axis = d_data->axisData[axisId];
 
372
    if ( axis.pen != pen )
 
373
    {
 
374
      axis.pen = pen;
 
375
      isChanged = true;
 
376
    }
 
377
  }
 
378
  if ( isChanged )
 
379
    itemChanged();
 
380
}
 
381
 
 
382
/*!
 
383
   Assign a font for all scale tick labels
 
384
 
 
385
   \param font Font
 
386
   \sa setAxisFont()
 
387
*/
 
388
void QwtPolarGrid::setFont( const QFont &font )
 
389
{
 
390
  bool isChanged = false;
 
391
  for ( int axisId = 0; axisId < QwtPolar::AxesCount; axisId++ )
 
392
  {
 
393
    AxisData &axis = d_data->axisData[axisId];
 
394
    if ( axis.font != font )
 
395
    {
 
396
      axis.font = font;
 
397
      isChanged = true;
 
398
    }
 
399
  }
 
400
  if ( isChanged )
 
401
    itemChanged();
 
402
}
 
403
 
 
404
/*!
 
405
   Assign a pen for the major grid lines
 
406
 
 
407
   \param pen Pen
 
408
   \sa setPen(), setMinorGridPen(), majorGridPen
 
409
*/
 
410
void QwtPolarGrid::setMajorGridPen( const QPen &pen )
 
411
{
 
412
  bool isChanged = false;
 
413
 
 
414
  for ( int scaleId = 0; scaleId < QwtPolar::ScaleCount; scaleId++ )
 
415
  {
 
416
    GridData &grid = d_data->gridData[scaleId];
 
417
    if ( grid.majorPen != pen )
 
418
    {
 
419
      grid.majorPen = pen;
 
420
      isChanged = true;
 
421
    }
 
422
  }
 
423
  if ( isChanged )
 
424
    itemChanged();
 
425
}
 
426
 
 
427
/*!
 
428
   Assign a pen for the major grid lines of a specific scale
 
429
 
 
430
   \param scaleId Scale id ( QwtPolar::Scale )
 
431
   \param pen Pen
 
432
   \sa setPen(), setMinorGridPen(), majorGridPen
 
433
*/
 
434
void QwtPolarGrid::setMajorGridPen( int scaleId, const QPen &pen )
 
435
{
 
436
  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
437
    return;
 
438
 
 
439
  GridData &grid = d_data->gridData[scaleId];
 
440
  if ( grid.majorPen != pen )
 
441
  {
 
442
    grid.majorPen = pen;
 
443
    itemChanged();
 
444
  }
 
445
}
 
446
 
 
447
/*!
 
448
   \return Pen for painting the major grid lines of a specific scale
 
449
   \param scaleId Scale id ( QwtPolar::Scale )
 
450
   \sa setMajorGridPen(), minorGridPen()
 
451
*/
 
452
QPen QwtPolarGrid::majorGridPen( int scaleId ) const
 
453
{
 
454
  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
455
    return QPen();
 
456
 
 
457
  const GridData &grid = d_data->gridData[scaleId];
 
458
  return grid.majorPen;
 
459
}
 
460
 
 
461
/*!
 
462
   Assign a pen for the minor grid lines
 
463
 
 
464
   \param pen Pen
 
465
   \sa setPen(), setMajorGridPen(), minorGridPen()
 
466
*/
 
467
void QwtPolarGrid::setMinorGridPen( const QPen &pen )
 
468
{
 
469
  bool isChanged = false;
 
470
 
 
471
  for ( int scaleId = 0; scaleId < QwtPolar::ScaleCount; scaleId++ )
 
472
  {
 
473
    GridData &grid = d_data->gridData[scaleId];
 
474
    if ( grid.minorPen != pen )
 
475
    {
 
476
      grid.minorPen = pen;
 
477
      isChanged = true;
 
478
    }
 
479
  }
 
480
  if ( isChanged )
 
481
    itemChanged();
 
482
}
 
483
 
 
484
/*!
 
485
   Assign a pen for the minor grid lines of a specific scale
 
486
 
 
487
   \param scaleId Scale id ( QwtPolar::Scale )
 
488
   \param pen Pen
 
489
   \sa setPen(), setMajorGridPen(), minorGridPen
 
490
*/
 
491
void QwtPolarGrid::setMinorGridPen( int scaleId, const QPen &pen )
 
492
{
 
493
  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
494
    return;
 
495
 
 
496
  GridData &grid = d_data->gridData[scaleId];
 
497
  if ( grid.minorPen != pen )
 
498
  {
 
499
    grid.minorPen = pen;
 
500
    itemChanged();
 
501
  }
 
502
}
 
503
 
 
504
/*!
 
505
   \return Pen for painting the minor grid lines of a specific scale
 
506
   \param scaleId Scale id ( QwtPolar::Scale )
 
507
*/
 
508
QPen QwtPolarGrid::minorGridPen( int scaleId ) const
 
509
{
 
510
  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
511
    return QPen();
 
512
 
 
513
  const GridData &grid = d_data->gridData[scaleId];
 
514
  return grid.minorPen;
 
515
}
 
516
 
 
517
/*!
 
518
   \return Pen for painting a specific axis
 
519
 
 
520
   \param axisId Axis id (QwtPolar::Axis)
 
521
   \sa setAxisPen()
 
522
*/
 
523
QPen QwtPolarGrid::axisPen( int axisId ) const
 
524
{
 
525
  if ( axisId < 0 || axisId >= QwtPolar::AxesCount )
 
526
    return QPen();
 
527
 
 
528
  return d_data->axisData[axisId].pen;
 
529
}
 
530
 
 
531
/*!
 
532
  Assign a font for the tick labels of a specific axis
 
533
 
 
534
  \param axisId Axis id (QwtPolar::Axis)
 
535
  \param font new Font
 
536
*/
 
537
void QwtPolarGrid::setAxisFont( int axisId, const QFont &font )
 
538
{
 
539
  if ( axisId < 0 || axisId >= QwtPolar::AxesCount )
 
540
    return;
 
541
 
 
542
  AxisData &axisData = d_data->axisData[axisId];
 
543
  if ( axisData.font != font )
 
544
  {
 
545
    axisData.font = font;
 
546
    itemChanged();
 
547
  }
 
548
}
 
549
 
 
550
/*!
 
551
  \return Font for the tick labels of a specific axis
 
552
  \param axisId Axis id (QwtPolar::Axis)
 
553
*/
 
554
QFont QwtPolarGrid::axisFont( int axisId ) const
 
555
{
 
556
  if ( axisId < 0 || axisId >= QwtPolar::AxesCount )
 
557
    return QFont();
 
558
 
 
559
  return d_data->axisData[axisId].font;
 
560
}
 
561
 
 
562
/*!
 
563
  Draw the grid and axes
 
564
 
 
565
  \param painter Painter
 
566
  \param azimuthMap Maps azimuth values to values related to 0.0, M_2PI
 
567
  \param radialMap Maps radius values into painter coordinates.
 
568
  \param pole Position of the pole in painter coordinates
 
569
  \param radius Radius of the complete plot area in painter coordinates
 
570
  \param canvasRect Contents rect of the canvas in painter coordinates
 
571
*/
 
572
void QwtPolarGrid::draw( QPainter *painter,
 
573
                         const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap,
 
574
                         const QwtDoublePoint &pole, double radius,
 
575
                         const QwtDoubleRect &canvasRect ) const
 
576
{
 
577
  updateScaleDraws( azimuthMap, radialMap, pole, radius );
 
578
 
 
579
  painter->save();
 
580
 
 
581
  if ( testDisplayFlag( ClipAxisBackground ) )
 
582
  {
 
583
    QRegion clipRegion( canvasRect.toRect() );
 
584
    for ( int axisId = 0; axisId < QwtPolar::AxesCount; axisId++ )
 
585
    {
 
586
      const AxisData &axis = d_data->axisData[axisId];
 
587
      if ( axisId != QwtPolar::AxisAzimuth && axis.isVisible )
 
588
      {
 
589
        QwtScaleDraw *scaleDraw = ( QwtScaleDraw * )axis.scaleDraw;
 
590
        if ( scaleDraw->hasComponent( QwtScaleDraw::Labels ) )
 
591
        {
 
592
          const QwtValueList &ticks =
 
593
            scaleDraw->scaleDiv().ticks( QwtScaleDiv::MajorTick );
 
594
          for ( int i = 0; i < int( ticks.size() ); i++ )
 
595
          {
 
596
            QRect labelRect =
 
597
              scaleDraw->boundingLabelRect( axis.font, ticks[i] );
 
598
 
 
599
            const int margin = 2;
 
600
            labelRect.setRect(
 
601
              labelRect.x() - margin,
 
602
              labelRect.y() - margin,
 
603
              labelRect.width() + 2 * margin,
 
604
              labelRect.height() + 2 * margin
 
605
            );
 
606
 
 
607
            if ( labelRect.isValid() )
 
608
              clipRegion -= QRegion( labelRect );
 
609
          }
 
610
        }
 
611
      }
 
612
    }
 
613
    painter->setClipRegion( clipRegion );
 
614
  }
 
615
 
 
616
  //  draw radial grid
 
617
 
 
618
  const GridData &radialGrid = d_data->gridData[QwtPolar::Radius];
 
619
  if ( radialGrid.isVisible && radialGrid.isMinorVisible )
 
620
  {
 
621
    painter->setPen( radialGrid.minorPen );
 
622
 
 
623
    drawCircles( painter, canvasRect, pole, radialMap,
 
624
                 radialGrid.scaleDiv.ticks( QwtScaleDiv::MinorTick ) );
 
625
    drawCircles( painter, canvasRect, pole, radialMap,
 
626
                 radialGrid.scaleDiv.ticks( QwtScaleDiv::MediumTick ) );
 
627
  }
 
628
  if ( radialGrid.isVisible )
 
629
  {
 
630
    painter->setPen( radialGrid.majorPen );
 
631
 
 
632
    drawCircles( painter, canvasRect, pole, radialMap,
 
633
                 radialGrid.scaleDiv.ticks( QwtScaleDiv::MajorTick ) );
 
634
  }
 
635
 
 
636
  // draw azimuth grid
 
637
 
 
638
  const GridData &azimuthGrid =
 
639
    d_data->gridData[QwtPolar::Azimuth];
 
640
 
 
641
  if ( azimuthGrid.isVisible && azimuthGrid.isMinorVisible )
 
642
  {
 
643
    painter->setPen( azimuthGrid.minorPen );
 
644
 
 
645
    drawRays( painter, canvasRect, pole, radius, azimuthMap,
 
646
              azimuthGrid.scaleDiv.ticks( QwtScaleDiv::MinorTick ) );
 
647
    drawRays( painter, canvasRect, pole, radius, azimuthMap,
 
648
              azimuthGrid.scaleDiv.ticks( QwtScaleDiv::MediumTick ) );
 
649
  }
 
650
  if ( azimuthGrid.isVisible )
 
651
  {
 
652
    painter->setPen( azimuthGrid.majorPen );
 
653
 
 
654
    drawRays( painter, canvasRect, pole, radius, azimuthMap,
 
655
              azimuthGrid.scaleDiv.ticks( QwtScaleDiv::MajorTick ) );
 
656
  }
 
657
  painter->restore();
 
658
 
 
659
  for ( int axisId = 0; axisId < QwtPolar::AxesCount; axisId++ )
 
660
  {
 
661
    const AxisData &axis = d_data->axisData[axisId];
 
662
    if ( axis.isVisible )
 
663
    {
 
664
      painter->save();
 
665
      drawAxis( painter, axisId );
 
666
      painter->restore();
 
667
    }
 
668
  }
 
669
}
 
670
 
 
671
/*!
 
672
  Draw lines from the pole
 
673
 
 
674
  \param painter Painter
 
675
  \param canvasRect Contents rect of the canvas in painter coordinates
 
676
  \param pole Position of the pole in painter coordinates
 
677
  \param radius Length of the lines in painter coordinates
 
678
  \param azimuthMap Maps azimuth values to values related to 0.0, M_2PI
 
679
  \param values Azimuth values, indicating the direction of the lines
 
680
*/
 
681
void QwtPolarGrid::drawRays(
 
682
  QPainter *painter, const QwtDoubleRect &canvasRect,
 
683
  const QwtDoublePoint &pole, double radius,
 
684
  const QwtScaleMap &azimuthMap, const QwtValueList &values ) const
 
685
{
 
686
  for ( int i = 0; i < int( values.size() ); i++ )
 
687
  {
 
688
    double azimuth = azimuthMap.xTransform( values[i] );
 
689
    azimuth = ::fmod( azimuth, 2 * M_PI );
 
690
 
 
691
    bool skipLine = false;
 
692
    if ( testDisplayFlag( SmartScaleDraw ) )
 
693
    {
 
694
      const QwtAbstractScaleDraw::ScaleComponent bone =
 
695
        QwtAbstractScaleDraw::Backbone;
 
696
      if ( isClose( azimuth, 0.0 ) )
 
697
      {
 
698
        const AxisData &axis = d_data->axisData[QwtPolar::AxisRight];
 
699
        if ( axis.isVisible && axis.scaleDraw->hasComponent( bone ) )
 
700
          skipLine = true;
 
701
      }
 
702
      else if ( isClose( azimuth, M_PI / 2 ) )
 
703
      {
 
704
        const AxisData &axis = d_data->axisData[QwtPolar::AxisTop];
 
705
        if ( axis.isVisible && axis.scaleDraw->hasComponent( bone ) )
 
706
          skipLine = true;
 
707
      }
 
708
      else if ( isClose( azimuth, M_PI ) )
 
709
      {
 
710
        const AxisData &axis = d_data->axisData[QwtPolar::AxisLeft];
 
711
        if ( axis.isVisible && axis.scaleDraw->hasComponent( bone ) )
 
712
          skipLine = true;
 
713
      }
 
714
      else if ( isClose( azimuth, 3 * M_PI / 2.0 ) )
 
715
      {
 
716
        const AxisData &axis = d_data->axisData[QwtPolar::AxisBottom];
 
717
        if ( axis.isVisible && axis.scaleDraw->hasComponent( bone ) )
 
718
          skipLine = true;
 
719
      }
 
720
    }
 
721
    if ( !skipLine )
 
722
    {
 
723
      const QwtDoublePoint pos = qwtPolar2Pos( pole, radius, azimuth );
 
724
 
 
725
      /*
 
726
          Qt4 is horrible slow, when painting primitives,
 
727
          with coordinates far outside the visible area.
 
728
       */
 
729
 
 
730
      QwtPolygon pa( 2 );
 
731
      pa.setPoint( 0, pole.toPoint() );
 
732
      pa.setPoint( 1, pos.toPoint() );
 
733
 
 
734
      if ( testDisplayFlag( ClipGridLines ) )
 
735
        pa = QwtClipper::clipPolygon( canvasRect.toRect(), pa );
 
736
 
 
737
      QwtPainter::drawPolyline( painter, pa );
 
738
    }
 
739
  }
 
740
}
 
741
 
 
742
/*!
 
743
  Draw circles
 
744
 
 
745
  \param painter Painter
 
746
  \param canvasRect Contents rect of the canvas in painter coordinates
 
747
  \param pole Position of the pole in painter coordinates
 
748
  \param radialMap Maps radius values into painter coordinates.
 
749
  \param values Radial values, indicating the distances from the pole
 
750
*/
 
751
void QwtPolarGrid::drawCircles(
 
752
  QPainter *painter, const QwtDoubleRect &canvasRect,
 
753
  const QwtDoublePoint &pole, const QwtScaleMap &radialMap,
 
754
  const QwtValueList &values ) const
 
755
{
 
756
  for ( int i = 0; i < int( values.size() ); i++ )
 
757
  {
 
758
    const double val = values[i];
 
759
 
 
760
    const GridData &gridData =
 
761
      d_data->gridData[QwtPolar::Radius];
 
762
 
 
763
    bool skipLine = false;
 
764
    if ( testDisplayFlag( SmartScaleDraw ) )
 
765
    {
 
766
      const AxisData &axis = d_data->axisData[QwtPolar::AxisAzimuth];
 
767
      if ( axis.isVisible &&
 
768
           axis.scaleDraw->hasComponent( QwtAbstractScaleDraw::Backbone ) )
 
769
      {
 
770
#if QWT_VERSION < 0x050200
 
771
        if ( isClose( val, gridData.scaleDiv.hBound() ) )
 
772
#else
 
773
        if ( isClose( val, gridData.scaleDiv.upperBound() ) )
 
774
#endif
 
775
          skipLine = true;
 
776
      }
 
777
    }
 
778
 
 
779
#if QWT_VERSION < 0x050200
 
780
    if ( isClose( val, gridData.scaleDiv.lBound() ) )
 
781
#else
 
782
    if ( isClose( val, gridData.scaleDiv.lowerBound() ) )
 
783
#endif
 
784
      skipLine = true;
 
785
 
 
786
    if ( !skipLine )
 
787
    {
 
788
      const double radius = radialMap.transform( val );
 
789
 
 
790
      QwtDoubleRect outerRect( 0, 0, 2 * radius, 2 * radius );
 
791
      outerRect.moveCenter( pole );
 
792
 
 
793
#if QT_VERSION < 0x040000
 
794
      QwtPainter::drawEllipse( painter, outerRect.toRect() );
 
795
#else
 
796
      if ( testDisplayFlag( ClipGridLines ) )
 
797
      {
 
798
 
 
799
        /*
 
800
            Qt4 is horrible slow, when painting primitives,
 
801
            with coordinates far outside the visible area.
 
802
            We need to clip.
 
803
        */
 
804
 
 
805
        const QwtArray<QwtDoubleInterval> angles =
 
806
          QwtClipper::clipCircle( canvasRect, pole, radius );
 
807
        for ( int i = 0; i < angles.size(); i++ )
 
808
        {
 
809
          const QwtDoubleInterval intv = angles[i];
 
810
          if ( intv.minValue() == 0 && intv.maxValue() == 2 * M_PI )
 
811
            QwtPainter::drawEllipse( painter, outerRect.toRect() );
 
812
          else
 
813
          {
 
814
            const double from = intv.minValue() / M_PI * 180;
 
815
            const double to = intv.maxValue() / M_PI * 180;
 
816
            double span = to - from;
 
817
            if ( span < 0.0 )
 
818
              span += 360.0;
 
819
 
 
820
            const QwtMetricsMap &mm = QwtPainter::metricsMap();
 
821
            const QRect r = outerRect.toRect();
 
822
 
 
823
            painter->drawArc( mm.layoutToDevice( r, painter ),
 
824
                              qRound( from * 16 ), qRound( span * 16 ) );
 
825
          }
 
826
 
 
827
        }
 
828
      }
 
829
      else
 
830
      {
 
831
        QwtPainter::drawEllipse( painter, outerRect.toRect() );
 
832
      }
 
833
#endif
 
834
    }
 
835
  }
 
836
}
 
837
 
 
838
/*!
 
839
  Paint an axis
 
840
 
 
841
  \param painter Painter
 
842
  \param axisId Axis id (QwtPolar::Axis)
 
843
*/
 
844
void QwtPolarGrid::drawAxis( QPainter *painter, int axisId ) const
 
845
{
 
846
  if ( axisId < 0 || axisId >= QwtPolar::AxesCount )
 
847
    return;
 
848
 
 
849
  AxisData &axis = d_data->axisData[axisId];
 
850
 
 
851
  painter->setPen( axis.pen );
 
852
  painter->setFont( axis.font );
 
853
 
 
854
#if QT_VERSION < 0x040000
 
855
  QColorGroup cg;
 
856
  cg.setColor( QColorGroup::Foreground, axis.pen.color() );
 
857
  cg.setColor( QColorGroup::Text, axis.pen.color() );
 
858
 
 
859
  axis.scaleDraw->draw( painter, cg );
 
860
#else
 
861
  QPalette pal;
 
862
  pal.setColor( QPalette::Foreground, axis.pen.color() );
 
863
  pal.setColor( QPalette::Text, axis.pen.color() );
 
864
 
 
865
  axis.scaleDraw->draw( painter, pal );
 
866
#endif
 
867
}
 
868
 
 
869
/*!
 
870
   Update the axis scale draw geometries
 
871
 
 
872
   \param azimuthMap Maps azimuth values to values related to 0.0, M_2PI
 
873
   \param radialMap Maps radius values into painter coordinates.
 
874
   \param pole Position of the pole in painter coordinates
 
875
   \param radius Radius of the complete plot area in painter coordinates
 
876
 
 
877
   \sa updateScaleDiv()
 
878
*/
 
879
void QwtPolarGrid::updateScaleDraws(
 
880
  const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap,
 
881
  const QwtDoublePoint &pole, double radius ) const
 
882
{
 
883
  const QPoint p = pole.toPoint();
 
884
 
 
885
  const QwtDoubleInterval interval =
 
886
    d_data->gridData[QwtPolar::ScaleRadius].scaleDiv.interval();
 
887
 
 
888
  const int min = radialMap.transform( interval.minValue() );
 
889
  const int max = radialMap.transform( interval.maxValue() );
 
890
  const int l = max - min;
 
891
 
 
892
  for ( int axisId = 0; axisId < QwtPolar::AxesCount; axisId++ )
 
893
  {
 
894
    AxisData &axis = d_data->axisData[axisId];
 
895
 
 
896
    if ( axisId == QwtPolar::AxisAzimuth )
 
897
    {
 
898
      QwtRoundScaleDraw *scaleDraw = ( QwtRoundScaleDraw * )axis.scaleDraw;
 
899
 
 
900
      scaleDraw->setRadius( qRound( radius ) );
 
901
      scaleDraw->moveCenter( p );
 
902
 
 
903
      double from = ::fmod( 90.0 - azimuthMap.p1() * 180.0 / M_PI, 360.0 );
 
904
      if ( from < 0.0 )
 
905
        from += 360.0;
 
906
 
 
907
      scaleDraw->setAngleRange( from, from - 360.0 );
 
908
      scaleDraw->setTransformation( azimuthMap.transformation()->copy() );
 
909
    }
 
910
    else
 
911
    {
 
912
      QwtScaleDraw *scaleDraw = ( QwtScaleDraw * )axis.scaleDraw;
 
913
      switch ( axisId )
 
914
      {
 
915
        case QwtPolar::AxisLeft:
 
916
        {
 
917
          scaleDraw->move( p.x() - min, p.y() );
 
918
          scaleDraw->setLength( -l );
 
919
          break;
 
920
        }
 
921
        case QwtPolar::AxisRight:
 
922
        {
 
923
          scaleDraw->move( p.x() + min, p.y() );
 
924
          scaleDraw->setLength( l );
 
925
          break;
 
926
        }
 
927
        case QwtPolar::AxisTop:
 
928
        {
 
929
          scaleDraw->move( p.x(), p.y() - max );
 
930
          scaleDraw->setLength( l );
 
931
          break;
 
932
        }
 
933
        case QwtPolar::AxisBottom:
 
934
        {
 
935
          scaleDraw->move( p.x(), p.y() + max );
 
936
          scaleDraw->setLength( -l );
 
937
          break;
 
938
        }
 
939
      }
 
940
      scaleDraw->setTransformation( radialMap.transformation()->copy() );
 
941
    }
 
942
  }
 
943
}
 
944
 
 
945
/*!
 
946
   \brief Update the item to changes of the axes scale division
 
947
 
 
948
   If AutoScaling is enabled the radial scale is calculated
 
949
   from the interval, otherwise the scales are adopted to
 
950
   the plot scales.
 
951
 
 
952
   \param azimuthScaleDiv Scale division of the azimuth-scale
 
953
   \param radialScaleDiv Scale division of the radius-axis
 
954
   \param interval The interval of the radius-axis, that is
 
955
                   visible on the canvas
 
956
 
 
957
   \sa QwtPolarPlot::setGridAttributes()
 
958
*/
 
959
 
 
960
void QwtPolarGrid::updateScaleDiv( const QwtScaleDiv &azimuthScaleDiv,
 
961
                                   const QwtScaleDiv &radialScaleDiv, const QwtDoubleInterval &interval )
 
962
{
 
963
  GridData &radialGrid = d_data->gridData[QwtPolar::Radius];
 
964
 
 
965
  const QwtPolarPlot *plt = plot();
 
966
  if ( plt && testGridAttribute( AutoScaling ) )
 
967
  {
 
968
    const QwtScaleEngine *se = plt->scaleEngine( QwtPolar::Radius );
 
969
    radialGrid.scaleDiv = se->divideScale(
 
970
                            interval.minValue(), interval.maxValue(),
 
971
                            plt->scaleMaxMajor( QwtPolar::Radius ),
 
972
                            plt->scaleMaxMinor( QwtPolar::Radius ), 0 );
 
973
  }
 
974
  else
 
975
  {
 
976
    if ( radialGrid.scaleDiv != radialScaleDiv )
 
977
      radialGrid.scaleDiv = radialScaleDiv;
 
978
  }
 
979
 
 
980
  GridData &azimuthGrid = d_data->gridData[QwtPolar::Azimuth];
 
981
  if ( azimuthGrid.scaleDiv != azimuthScaleDiv )
 
982
  {
 
983
    azimuthGrid.scaleDiv = azimuthScaleDiv;
 
984
  }
 
985
 
 
986
  bool hasOrigin = false;
 
987
  for ( int axisId = 0; axisId < QwtPolar::AxesCount; axisId++ )
 
988
  {
 
989
    AxisData &axis = d_data->axisData[axisId];
 
990
    if ( axis.isVisible && axis.scaleDraw )
 
991
    {
 
992
      if ( axisId == QwtPolar::AxisAzimuth )
 
993
      {
 
994
        axis.scaleDraw->setScaleDiv( azimuthGrid.scaleDiv );
 
995
        if ( testDisplayFlag( SmartScaleDraw ) )
 
996
        {
 
997
          axis.scaleDraw->enableComponent(
 
998
            QwtAbstractScaleDraw::Ticks, !azimuthGrid.isVisible );
 
999
        }
 
1000
      }
 
1001
      else
 
1002
      {
 
1003
        QwtScaleDiv sd = radialGrid.scaleDiv;
 
1004
 
 
1005
        QwtValueList &ticks =
 
1006
          ( QwtValueList & )sd.ticks( QwtScaleDiv::MajorTick );
 
1007
 
 
1008
        if ( testDisplayFlag( SmartOriginLabel ) )
 
1009
        {
 
1010
          bool skipOrigin = hasOrigin;
 
1011
          if ( !skipOrigin )
 
1012
          {
 
1013
            if ( axisId == QwtPolar::AxisLeft
 
1014
                 || axisId == QwtPolar::AxisRight )
 
1015
            {
 
1016
              if ( d_data->axisData[QwtPolar::AxisBottom].isVisible )
 
1017
                skipOrigin = true;
 
1018
            }
 
1019
            else
 
1020
            {
 
1021
              if ( d_data->axisData[QwtPolar::AxisLeft].isVisible )
 
1022
                skipOrigin = true;
 
1023
            }
 
1024
          }
 
1025
#if QWT_VERSION < 0x050200
 
1026
          if ( ticks.size() > 0 && ticks.first() == sd.lBound() )
 
1027
#else
 
1028
          if ( ticks.size() > 0 && ticks.first() == sd.lowerBound() )
 
1029
#endif
 
1030
          {
 
1031
            if ( skipOrigin )
 
1032
            {
 
1033
#if QT_VERSION < 0x040000
 
1034
              ticks.pop_front();
 
1035
#else
 
1036
              ticks.removeFirst();
 
1037
#endif
 
1038
            }
 
1039
            else
 
1040
              hasOrigin = true;
 
1041
          }
 
1042
        }
 
1043
 
 
1044
        if ( testDisplayFlag( HideMaxRadiusLabel ) )
 
1045
        {
 
1046
#if QWT_VERSION < 0x050200
 
1047
          if ( ticks.size() > 0 && ticks.last() == sd.hBound() )
 
1048
#else
 
1049
          if ( ticks.size() > 0 && ticks.last() == sd.upperBound() )
 
1050
#endif
 
1051
#if QT_VERSION < 0x040000
 
1052
            ticks.pop_back();
 
1053
#else
 
1054
            ticks.removeLast();
 
1055
#endif
 
1056
        }
 
1057
 
 
1058
        axis.scaleDraw->setScaleDiv( sd );
 
1059
 
 
1060
        if ( testDisplayFlag( SmartScaleDraw ) )
 
1061
        {
 
1062
          axis.scaleDraw->enableComponent(
 
1063
            QwtAbstractScaleDraw::Ticks, !radialGrid.isVisible );
 
1064
        }
 
1065
 
 
1066
      }
 
1067
    }
 
1068
  }
 
1069
}
 
1070
 
 
1071
/*!
 
1072
   \return Number of pixels, that are necessary to paint the azimuth scale
 
1073
   \sa QwtRoundScaleDraw::extent()
 
1074
*/
 
1075
int QwtPolarGrid::marginHint() const
 
1076
{
 
1077
  const AxisData &axis = d_data->axisData[QwtPolar::AxisAzimuth];
 
1078
  if ( axis.isVisible )
 
1079
  {
 
1080
    const int extent = axis.scaleDraw->extent( axis.pen, axis.font );
 
1081
    return extent;
 
1082
  }
 
1083
 
 
1084
  return 0;
 
1085
}
 
1086
 
 
1087
/*!
 
1088
  Returns the scale draw of a specified axis
 
1089
 
 
1090
  \param axisId axis index ( QwtPolar::AxisLeft <= axisId <= QwtPolar::AxisBottom)
 
1091
  \return specified scaleDraw for axis, or NULL if axis is invalid.
 
1092
  \sa azimuthScaleDraw()
 
1093
*/
 
1094
const QwtScaleDraw *QwtPolarGrid::scaleDraw( int axisId ) const
 
1095
{
 
1096
  if ( axisId >= QwtPolar::AxisLeft || axisId <= QwtPolar::AxisBottom )
 
1097
    return ( QwtScaleDraw * )d_data->axisData[axisId].scaleDraw;
 
1098
 
 
1099
  return NULL;
 
1100
}
 
1101
 
 
1102
/*!
 
1103
  Returns the scale draw of a specified axis
 
1104
 
 
1105
  \param axisId axis index ( QwtPolar::AxisLeft <= axisId <= QwtPolar::AxisBottom)
 
1106
  \return specified scaleDraw for axis, or NULL if axis is invalid.
 
1107
  \sa setScaleDraw(), azimuthScaleDraw()
 
1108
*/
 
1109
QwtScaleDraw *QwtPolarGrid::scaleDraw( int axisId )
 
1110
{
 
1111
  if ( axisId >= QwtPolar::AxisLeft || axisId <= QwtPolar::AxisBottom )
 
1112
    return ( QwtScaleDraw * )d_data->axisData[axisId].scaleDraw;
 
1113
 
 
1114
  return NULL;
 
1115
}
 
1116
 
 
1117
/*!
 
1118
  \brief Set a scale draw
 
1119
 
 
1120
  \param axisId axis index ( QwtPolar::AxisLeft <= axisId <= QwtPolar::AxisBottom)
 
1121
  \param scaleDraw object responsible for drawing scales.
 
1122
 
 
1123
  \sa scaleDraw(), setAzimuthScaleDraw()
 
1124
*/
 
1125
void QwtPolarGrid::setScaleDraw( int axisId, QwtScaleDraw *scaleDraw )
 
1126
{
 
1127
  if ( axisId < QwtPolar::AxisLeft || axisId > QwtPolar::AxisBottom )
 
1128
    return;
 
1129
 
 
1130
  AxisData &axisData = d_data->axisData[axisId];
 
1131
  if ( axisData.scaleDraw != scaleDraw )
 
1132
  {
 
1133
    delete axisData.scaleDraw;
 
1134
    axisData.scaleDraw = scaleDraw;
 
1135
    itemChanged();
 
1136
  }
 
1137
}
 
1138
 
 
1139
/*!
 
1140
  Returns the scale draw of the azimuth axis
 
1141
  \sa setAzimuthScaleDraw(), scaleDraw()
 
1142
*/
 
1143
const QwtRoundScaleDraw *QwtPolarGrid::azimuthScaleDraw() const
 
1144
{
 
1145
  return ( QwtRoundScaleDraw * )d_data->axisData[QwtPolar::AxisAzimuth].scaleDraw;
 
1146
}
 
1147
 
 
1148
/*!
 
1149
  Returns the scale draw of the azimuth axis
 
1150
  \sa setAzimuthScaleDraw(), scaleDraw()
 
1151
*/
 
1152
QwtRoundScaleDraw *QwtPolarGrid::azimuthScaleDraw()
 
1153
{
 
1154
  return ( QwtRoundScaleDraw * )d_data->axisData[QwtPolar::AxisAzimuth].scaleDraw;
 
1155
}
 
1156
 
 
1157
/*!
 
1158
  \brief Set a scale draw for the azimuth scale
 
1159
 
 
1160
  \param scaleDraw object responsible for drawing scales.
 
1161
  \sa azimuthScaleDraw(), setScaleDraw()
 
1162
*/
 
1163
void QwtPolarGrid::setAzimuthScaleDraw( QwtRoundScaleDraw *scaleDraw )
 
1164
{
 
1165
  AxisData &axisData = d_data->axisData[QwtPolar::AxisAzimuth];
 
1166
  if ( axisData.scaleDraw != scaleDraw )
 
1167
  {
 
1168
    delete axisData.scaleDraw;
 
1169
    axisData.scaleDraw = scaleDraw;
 
1170
    itemChanged();
 
1171
  }
 
1172
}