~ubuntu-branches/ubuntu/trusty/qgis/trusty

« back to all changes in this revision

Viewing changes to src/core/composer/qgscomposerscalebar.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Johan Van de Wauw
  • Date: 2010-07-11 20:23:24 UTC
  • mfrom: (3.1.4 squeeze)
  • Revision ID: james.westby@ubuntu.com-20100711202324-5ktghxa7hracohmr
Tags: 1.4.0+12730-3ubuntu1
* Merge from Debian unstable (LP: #540941).
* Fix compilation issues with QT 4.7
* Add build-depends on libqt4-webkit-dev 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
                           qgscomposerscalebar.cpp
 
3
                             -------------------
 
4
    begin                : March 2005
 
5
    copyright            : (C) 2005 by Radim Blazek
 
6
    email                : blazek@itc.it
 
7
 ***************************************************************************/
 
8
/***************************************************************************
 
9
 *                                                                         *
 
10
 *   This program is free software; you can redistribute it and/or modify  *
 
11
 *   it under the terms of the GNU General Public License as published by  *
 
12
 *   the Free Software Foundation; either version 2 of the License, or     *
 
13
 *   (at your option) any later version.                                   *
 
14
 *                                                                         *
 
15
 ***************************************************************************/
 
16
 
 
17
#include "qgscomposerscalebar.h"
 
18
#include "qgscomposermap.h"
 
19
#include "qgsscalebarstyle.h"
 
20
#include "qgsdoubleboxscalebarstyle.h"
 
21
#include "qgsnumericscalebarstyle.h"
 
22
#include "qgssingleboxscalebarstyle.h"
 
23
#include "qgsticksscalebarstyle.h"
 
24
#include "qgsrectangle.h"
 
25
#include <QDomDocument>
 
26
#include <QDomElement>
 
27
#include <QFontMetricsF>
 
28
#include <QPainter>
 
29
#include <cmath>
 
30
 
 
31
QgsComposerScaleBar::QgsComposerScaleBar( QgsComposition* composition ): QgsComposerItem( composition ), mComposerMap( 0 ), mStyle( 0 ), mSegmentMillimeters( 0.0 )
 
32
{
 
33
  applyDefaultSettings();
 
34
}
 
35
 
 
36
QgsComposerScaleBar::~QgsComposerScaleBar()
 
37
{
 
38
  delete mStyle;
 
39
}
 
40
 
 
41
void QgsComposerScaleBar::paint( QPainter* painter, const QStyleOptionGraphicsItem* itemStyle, QWidget* pWidget )
 
42
{
 
43
  if ( !mStyle || !painter )
 
44
  {
 
45
    return;
 
46
  }
 
47
 
 
48
  drawBackground( painter );
 
49
  painter->setPen( QPen( QColor( 0, 0, 0 ) ) ); //draw all text black
 
50
 
 
51
  //x-offset is half of first label width because labels are drawn centered
 
52
  QString firstLabel = firstLabelString();
 
53
  double firstLabelWidth = textWidthMillimeters( mFont, firstLabel );
 
54
 
 
55
  mStyle->draw( painter, firstLabelWidth / 2 );
 
56
 
 
57
  //draw frame and selection boxes if necessary
 
58
  drawFrame( painter );
 
59
  if ( isSelected() )
 
60
  {
 
61
    drawSelectionBoxes( painter );
 
62
  }
 
63
}
 
64
 
 
65
void QgsComposerScaleBar::setNumUnitsPerSegment( double units )
 
66
{
 
67
  mNumUnitsPerSegment = units;
 
68
  refreshSegmentMillimeters();
 
69
}
 
70
 
 
71
void QgsComposerScaleBar::setComposerMap( const QgsComposerMap* map )
 
72
{
 
73
  disconnect( mComposerMap, SIGNAL( extentChanged() ), this, SLOT( updateSegmentSize() ) );
 
74
  disconnect( mComposerMap, SIGNAL( destroyed( QObject* ) ), this, SLOT( invalidateCurrentMap() ) );
 
75
  mComposerMap = map;
 
76
 
 
77
  if ( !map )
 
78
  {
 
79
    return;
 
80
  }
 
81
 
 
82
  connect( mComposerMap, SIGNAL( extentChanged() ), this, SLOT( updateSegmentSize() ) );
 
83
  connect( mComposerMap, SIGNAL( destroyed( QObject* ) ), this, SLOT( invalidateCurrentMap() ) );
 
84
 
 
85
  refreshSegmentMillimeters();
 
86
}
 
87
 
 
88
void QgsComposerScaleBar::invalidateCurrentMap()
 
89
{
 
90
  disconnect( mComposerMap, SIGNAL( extentChanged() ), this, SLOT( updateSegmentSize() ) );
 
91
  disconnect( mComposerMap, SIGNAL( destroyed( QObject* ) ), this, SLOT( invalidateCurrentMap() ) );
 
92
  mComposerMap = 0;
 
93
}
 
94
 
 
95
void QgsComposerScaleBar::refreshSegmentMillimeters()
 
96
{
 
97
  if ( mComposerMap )
 
98
  {
 
99
    //get extent of composer map
 
100
    QgsRectangle composerMapRect = mComposerMap->extent();
 
101
 
 
102
    //get mm dimension of composer map
 
103
    QRectF composerItemRect = mComposerMap->rect();
 
104
 
 
105
    //calculate size depending on mNumUnitsPerSegment
 
106
    mSegmentMillimeters = composerItemRect.width() / composerMapRect.width() * mNumUnitsPerSegment;
 
107
  }
 
108
}
 
109
 
 
110
void QgsComposerScaleBar::applyDefaultSettings()
 
111
{
 
112
  mNumSegments = 2;
 
113
  mNumSegmentsLeft = 0;
 
114
 
 
115
  mNumMapUnitsPerScaleBarUnit = 1.0;
 
116
 
 
117
  //style
 
118
  delete mStyle;
 
119
  mStyle = new QgsSingleBoxScaleBarStyle( this );
 
120
 
 
121
  mHeight = 5;
 
122
 
 
123
  mPen = QPen( QColor( 0, 0, 0 ) );
 
124
  mPen.setWidthF( 1.0 );
 
125
 
 
126
  mBrush.setColor( QColor( 0, 0, 0 ) );
 
127
  mBrush.setStyle( Qt::SolidPattern );
 
128
 
 
129
  mFont.setPointSizeF( 12.0 );
 
130
 
 
131
  mLabelBarSpace = 3.0;
 
132
  mBoxContentSpace = 1.0;
 
133
 
 
134
  if ( mComposerMap )
 
135
  {
 
136
    //calculate mNumUnitsPerSegment
 
137
    QRectF composerItemRect = mComposerMap->rect();
 
138
    QgsRectangle composerMapRect = mComposerMap->extent();
 
139
 
 
140
    double proposedScaleBarLength = composerMapRect.width() / 4;
 
141
    int powerOf10 = int ( pow( 10.0, int ( log( proposedScaleBarLength ) / log( 10.0 ) ) ) ); // from scalebar plugin
 
142
    int nPow10 = proposedScaleBarLength / powerOf10;
 
143
    mNumSegments = 2;
 
144
    mNumUnitsPerSegment = ( nPow10 / 2 ) * powerOf10;
 
145
  }
 
146
 
 
147
  refreshSegmentMillimeters();
 
148
  adjustBoxSize();
 
149
}
 
150
 
 
151
void QgsComposerScaleBar::adjustBoxSize()
 
152
{
 
153
  if ( !mStyle )
 
154
  {
 
155
    return;
 
156
  }
 
157
 
 
158
  QRectF box = mStyle->calculateBoxSize();
 
159
  setSceneRect( box );
 
160
}
 
161
 
 
162
void QgsComposerScaleBar::update()
 
163
{
 
164
  adjustBoxSize();
 
165
  QgsComposerItem::update();
 
166
}
 
167
 
 
168
void QgsComposerScaleBar::updateSegmentSize()
 
169
{
 
170
  refreshSegmentMillimeters();
 
171
  update();
 
172
}
 
173
 
 
174
void QgsComposerScaleBar::segmentPositions( QList<QPair<double, double> >& posWidthList ) const
 
175
{
 
176
  posWidthList.clear();
 
177
  double mCurrentXCoord = mPen.widthF() + mBoxContentSpace;
 
178
 
 
179
  //left segments
 
180
  for ( int i = 0; i < mNumSegmentsLeft; ++i )
 
181
  {
 
182
    posWidthList.push_back( qMakePair( mCurrentXCoord, mSegmentMillimeters / mNumSegmentsLeft ) );
 
183
    mCurrentXCoord += mSegmentMillimeters / mNumSegmentsLeft;
 
184
  }
 
185
 
 
186
  //right segments
 
187
  for ( int i = 0; i < mNumSegments; ++i )
 
188
  {
 
189
    posWidthList.push_back( qMakePair( mCurrentXCoord, mSegmentMillimeters ) );
 
190
    mCurrentXCoord += mSegmentMillimeters;
 
191
  }
 
192
}
 
193
 
 
194
void QgsComposerScaleBar::setStyle( const QString& styleName )
 
195
{
 
196
  delete mStyle;
 
197
  mStyle = 0;
 
198
 
 
199
  //switch depending on style name
 
200
  if ( styleName == "Single Box" )
 
201
  {
 
202
    mStyle = new QgsSingleBoxScaleBarStyle( this );
 
203
  }
 
204
  else if ( styleName == "Double Box" )
 
205
  {
 
206
    mStyle = new QgsDoubleBoxScaleBarStyle( this );
 
207
  }
 
208
  else if ( styleName == "Line Ticks Middle"  || styleName == "Line Ticks Down" || styleName == "Line Ticks Up" )
 
209
  {
 
210
    QgsTicksScaleBarStyle* tickStyle = new QgsTicksScaleBarStyle( this );
 
211
    if ( styleName == "Line Ticks Middle" )
 
212
    {
 
213
      tickStyle->setTickPosition( QgsTicksScaleBarStyle::TicksMiddle );
 
214
    }
 
215
    else if ( styleName == "Line Ticks Down" )
 
216
    {
 
217
      tickStyle->setTickPosition( QgsTicksScaleBarStyle::TicksDown );
 
218
    }
 
219
    else if ( styleName == "Line Ticks Up" )
 
220
    {
 
221
      tickStyle->setTickPosition( QgsTicksScaleBarStyle::TicksUp );
 
222
    }
 
223
    mStyle = tickStyle;
 
224
  }
 
225
  else if ( styleName == "Numeric" )
 
226
  {
 
227
    mStyle = new QgsNumericScaleBarStyle( this );
 
228
  }
 
229
}
 
230
 
 
231
QString QgsComposerScaleBar::style() const
 
232
{
 
233
  if ( mStyle )
 
234
  {
 
235
    return mStyle->name();
 
236
  }
 
237
  else
 
238
  {
 
239
    return "";
 
240
  }
 
241
}
 
242
 
 
243
QString QgsComposerScaleBar::firstLabelString() const
 
244
{
 
245
  if ( mNumSegmentsLeft > 0 )
 
246
  {
 
247
    return QString::number( mNumUnitsPerSegment / mNumMapUnitsPerScaleBarUnit );
 
248
  }
 
249
  else
 
250
  {
 
251
    return "0";
 
252
  }
 
253
}
 
254
 
 
255
QFont QgsComposerScaleBar::font() const
 
256
{
 
257
  return mFont;
 
258
}
 
259
 
 
260
void QgsComposerScaleBar::setFont( const QFont& font )
 
261
{
 
262
  mFont = font;
 
263
  adjustBoxSize();
 
264
  update();
 
265
}
 
266
 
 
267
bool QgsComposerScaleBar::writeXML( QDomElement& elem, QDomDocument & doc ) const
 
268
{
 
269
  if ( elem.isNull() )
 
270
  {
 
271
    return false;
 
272
  }
 
273
 
 
274
  QDomElement composerScaleBarElem = doc.createElement( "ComposerScaleBar" );
 
275
  composerScaleBarElem.setAttribute( "height", mHeight );
 
276
  composerScaleBarElem.setAttribute( "labelBarSpace", mLabelBarSpace );
 
277
  composerScaleBarElem.setAttribute( "boxContentSpace", mBoxContentSpace );
 
278
  composerScaleBarElem.setAttribute( "numSegments", mNumSegments );
 
279
  composerScaleBarElem.setAttribute( "numSegmentsLeft", mNumSegmentsLeft );
 
280
  composerScaleBarElem.setAttribute( "numUnitsPerSegment", mNumUnitsPerSegment );
 
281
  composerScaleBarElem.setAttribute( "segmentMillimeters", mSegmentMillimeters );
 
282
  composerScaleBarElem.setAttribute( "numMapUnitsPerScaleBarUnit", mNumMapUnitsPerScaleBarUnit );
 
283
  composerScaleBarElem.setAttribute( "font", mFont.toString() );
 
284
  composerScaleBarElem.setAttribute( "outlineWidth", mPen.widthF() );
 
285
  composerScaleBarElem.setAttribute( "unitLabel", mUnitLabeling );
 
286
 
 
287
  //style
 
288
  if ( mStyle )
 
289
  {
 
290
    composerScaleBarElem.setAttribute( "style", mStyle->name() );
 
291
  }
 
292
 
 
293
  //map id
 
294
  if ( mComposerMap )
 
295
  {
 
296
    composerScaleBarElem.setAttribute( "mapId", mComposerMap->id() );
 
297
  }
 
298
 
 
299
  //fill color
 
300
  QColor brushColor = mBrush.color();
 
301
  QDomElement colorElem = doc.createElement( "BrushColor" );
 
302
  colorElem.setAttribute( "red", brushColor.red() );
 
303
  colorElem.setAttribute( "green", brushColor.green() );
 
304
  colorElem.setAttribute( "blue", brushColor.blue() );
 
305
  composerScaleBarElem.appendChild( colorElem );
 
306
 
 
307
  elem.appendChild( composerScaleBarElem );
 
308
  return _writeXML( composerScaleBarElem, doc );
 
309
}
 
310
 
 
311
bool QgsComposerScaleBar::readXML( const QDomElement& itemElem, const QDomDocument& doc )
 
312
{
 
313
  if ( itemElem.isNull() )
 
314
  {
 
315
    return false;
 
316
  }
 
317
 
 
318
  mHeight = itemElem.attribute( "height", "5.0" ).toDouble();
 
319
  mLabelBarSpace = itemElem.attribute( "labelBarSpace", "3.0" ).toDouble();
 
320
  mBoxContentSpace = itemElem.attribute( "boxContentSpace", "1.0" ).toDouble();
 
321
  mNumSegments = itemElem.attribute( "numSegments", "2" ).toInt();
 
322
  mNumSegmentsLeft = itemElem.attribute( "numSegmentsLeft", "0" ).toInt();
 
323
  mNumUnitsPerSegment = itemElem.attribute( "numUnitsPerSegment", "1.0" ).toDouble();
 
324
  mSegmentMillimeters = itemElem.attribute( "segmentMillimeters", "0.0" ).toDouble();
 
325
  mNumMapUnitsPerScaleBarUnit = itemElem.attribute( "numMapUnitsPerScaleBarUnit", "1.0" ).toDouble();
 
326
  mPen.setWidthF( itemElem.attribute( "outlineWidth", "1.0" ).toDouble() );
 
327
  mUnitLabeling = itemElem.attribute( "unitLabel" );
 
328
  QString fontString = itemElem.attribute( "font", "" );
 
329
  if ( !fontString.isEmpty() )
 
330
  {
 
331
    mFont.fromString( fontString );
 
332
  }
 
333
 
 
334
  //style
 
335
  delete mStyle;
 
336
  mStyle = 0;
 
337
  QString styleString = itemElem.attribute( "style", "" );
 
338
  setStyle( tr( styleString.toLocal8Bit().data() ) );
 
339
 
 
340
  //map
 
341
  int mapId = itemElem.attribute( "mapId", "-1" ).toInt();
 
342
  if ( mapId >= 0 )
 
343
  {
 
344
    const QgsComposerMap* composerMap = mComposition->getComposerMapById( mapId );
 
345
    mComposerMap = composerMap;
 
346
    if ( mComposerMap )
 
347
    {
 
348
      connect( mComposerMap, SIGNAL( extentChanged() ), this, SLOT( updateSegmentSize() ) );
 
349
      connect( mComposerMap, SIGNAL( destroyed( QObject* ) ), this, SLOT( invalidateCurrentMap() ) );
 
350
    }
 
351
  }
 
352
 
 
353
  refreshSegmentMillimeters();
 
354
 
 
355
  //restore general composer item properties
 
356
  QDomNodeList composerItemList = itemElem.elementsByTagName( "ComposerItem" );
 
357
  if ( composerItemList.size() > 0 )
 
358
  {
 
359
    QDomElement composerItemElem = composerItemList.at( 0 ).toElement();
 
360
    _readXML( composerItemElem, doc );
 
361
  }
 
362
 
 
363
  return true;
 
364
}
 
365
 
 
366