QGIS API Documentation  2.5.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
qgscomposerscalebar.cpp
Go to the documentation of this file.
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 "qgscomposition.h"
20 #include "qgscomposerutils.h"
21 #include "qgsdistancearea.h"
22 #include "qgsscalebarstyle.h"
24 #include "qgsmaprenderer.h"
27 #include "qgsticksscalebarstyle.h"
28 #include "qgsrectangle.h"
29 #include "qgsproject.h"
30 #include "qgssymbollayerv2utils.h"
31 #include <QDomDocument>
32 #include <QDomElement>
33 #include <QFontMetricsF>
34 #include <QPainter>
35 #include <QSettings>
36 #include <cmath>
37 
39  : QgsComposerItem( composition )
40  , mComposerMap( 0 )
41  , mNumUnitsPerSegment( 0 )
42  , mFontColor( QColor( 0, 0, 0 ) )
43  , mStyle( 0 )
44  , mSegmentMillimeters( 0.0 )
45  , mAlignment( Left )
46  , mUnits( MapUnits )
47  , mLineJoinStyle( Qt::MiterJoin )
48  , mLineCapStyle( Qt::SquareCap )
49 {
52 }
53 
55 {
56  delete mStyle;
57 }
58 
59 void QgsComposerScaleBar::paint( QPainter* painter, const QStyleOptionGraphicsItem* itemStyle, QWidget* pWidget )
60 {
61  Q_UNUSED( itemStyle );
62  Q_UNUSED( pWidget );
63  if ( !mStyle || !painter )
64  {
65  return;
66  }
67 
68  drawBackground( painter );
69 
70  //x-offset is half of first label width because labels are drawn centered
71  QString firstLabel = firstLabelString();
72  double firstLabelWidth = QgsComposerUtils::textWidthMM( mFont, firstLabel );
73 
74  mStyle->draw( painter, firstLabelWidth / 2 );
75 
76  //draw frame and selection boxes if necessary
77  drawFrame( painter );
78  if ( isSelected() )
79  {
80  drawSelectionBoxes( painter );
81  }
82 }
83 
85 {
86  if ( !mStyle )
87  {
88  mNumSegments = nSegments;
89  return;
90  }
91  double width = mStyle->calculateBoxSize().width();
92  mNumSegments = nSegments;
93  double widthAfter = mStyle->calculateBoxSize().width();
94  correctXPositionAlignment( width, widthAfter );
95  emit itemChanged();
96 }
97 
99 {
100  if ( !mStyle )
101  {
103  return;
104  }
105  double width = mStyle->calculateBoxSize().width();
108  double widthAfter = mStyle->calculateBoxSize().width();
109  correctXPositionAlignment( width, widthAfter );
110  emit itemChanged();
111 }
112 
114 {
115  if ( !mStyle )
116  {
117  mNumSegmentsLeft = nSegmentsLeft;
118  return;
119  }
120  double width = mStyle->calculateBoxSize().width();
121  mNumSegmentsLeft = nSegmentsLeft;
122  double widthAfter = mStyle->calculateBoxSize().width();
123  correctXPositionAlignment( width, widthAfter );
124  emit itemChanged();
125 }
126 
128 {
129  if ( !mStyle )
130  {
131  mBoxContentSpace = space;
132  return;
133  }
134  double width = mStyle->calculateBoxSize().width();
135  mBoxContentSpace = space;
136  double widthAfter = mStyle->calculateBoxSize().width();
137  correctXPositionAlignment( width, widthAfter );
138  emit itemChanged();
139 }
140 
142 {
143  if ( mComposerMap )
144  {
145  disconnect( mComposerMap, SIGNAL( extentChanged() ), this, SLOT( updateSegmentSize() ) );
146  disconnect( mComposerMap, SIGNAL( destroyed( QObject* ) ), this, SLOT( invalidateCurrentMap() ) );
147  }
148  mComposerMap = map;
149 
150  if ( !map )
151  {
152  return;
153  }
154 
155  connect( mComposerMap, SIGNAL( extentChanged() ), this, SLOT( updateSegmentSize() ) );
156  connect( mComposerMap, SIGNAL( destroyed( QObject* ) ), this, SLOT( invalidateCurrentMap() ) );
157 
159  emit itemChanged();
160 }
161 
163 {
164  if ( !mComposerMap )
165  {
166  return;
167  }
168 
169  disconnect( mComposerMap, SIGNAL( extentChanged() ), this, SLOT( updateSegmentSize() ) );
170  disconnect( mComposerMap, SIGNAL( destroyed( QObject* ) ), this, SLOT( invalidateCurrentMap() ) );
171  mComposerMap = 0;
172 }
173 
175 {
176  if ( mComposerMap )
177  {
178  //get extent of composer map
179  QgsRectangle composerMapRect = *( mComposerMap->currentMapExtent() );
180 
181  //get mm dimension of composer map
182  QRectF composerItemRect = mComposerMap->rect();
183 
184  //calculate size depending on mNumUnitsPerSegment
185  mSegmentMillimeters = composerItemRect.width() / mapWidth() * mNumUnitsPerSegment;
186  }
187 }
188 
190 {
191  if ( !mComposerMap )
192  {
193  return 0.0;
194  }
195 
196  QgsRectangle composerMapRect = *( mComposerMap->currentMapExtent() );
197  if ( mUnits == MapUnits )
198  {
199  return composerMapRect.width();
200  }
201  else
202  {
203  QgsDistanceArea da;
206  da.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", "WGS84" ) );
207 
208  double measure = da.measureLine( QgsPoint( composerMapRect.xMinimum(), composerMapRect.yMinimum() ), QgsPoint( composerMapRect.xMaximum(), composerMapRect.yMinimum() ) );
210  {
212  }
214  {
216  }
217  return measure;
218  }
219 }
220 
222 {
223  mAlignment = a;
224  update();
225  emit itemChanged();
226 }
227 
229 {
230  mUnits = u;
232  emit itemChanged();
233 }
234 
235 void QgsComposerScaleBar::setLineJoinStyle( Qt::PenJoinStyle style )
236 {
237  if ( mLineJoinStyle == style )
238  {
239  //no change
240  return;
241  }
243  mPen.setJoinStyle( mLineJoinStyle );
244  update();
245  emit itemChanged();
246 }
247 
248 void QgsComposerScaleBar::setLineCapStyle( Qt::PenCapStyle style )
249 {
250  if ( mLineCapStyle == style )
251  {
252  //no change
253  return;
254  }
256  mPen.setCapStyle( mLineCapStyle );
257  update();
258  emit itemChanged();
259 }
260 
262 {
263  mNumSegments = 2;
264  mNumSegmentsLeft = 0;
265 
267 
268  //style
269  delete mStyle;
270  mStyle = new QgsSingleBoxScaleBarStyle( this );
271 
272  mHeight = 3;
273 
274  //default to no background
275  setBackgroundEnabled( false );
276 
277  mPen = QPen( Qt::black );
278  mPen.setJoinStyle( mLineJoinStyle );
279  mPen.setCapStyle( mLineCapStyle );
280  mPen.setWidthF( 1.0 );
281 
282  mBrush.setColor( Qt::black );
283  mBrush.setStyle( Qt::SolidPattern );
284 
285  mBrush2.setColor( Qt::white );
286  mBrush2.setStyle( Qt::SolidPattern );
287 
288  //get default composer font from settings
289  QSettings settings;
290  QString defaultFontString = settings.value( "/Composer/defaultFont" ).toString();
291  if ( !defaultFontString.isEmpty() )
292  {
293  mFont.setFamily( defaultFontString );
294  }
295  mFont.setPointSizeF( 12.0 );
296  mFontColor = QColor( 0, 0, 0 );
297 
298  mLabelBarSpace = 3.0;
299  mBoxContentSpace = 1.0;
300  emit itemChanged();
301 }
302 
304 {
305  if ( mComposerMap )
306  {
307  setUnits( u );
308  double upperMagnitudeMultiplier = 1.0;
309  double widthInSelectedUnits = mapWidth();
310  double initialUnitsPerSegment = widthInSelectedUnits / 10.0; //default scalebar width equals half the map width
311  setNumUnitsPerSegment( initialUnitsPerSegment );
312 
313  switch ( mUnits )
314  {
315  case MapUnits:
316  {
317  upperMagnitudeMultiplier = 1.0;
318  setUnitLabeling( tr( "units" ) );
319  break;
320  }
321  case Meters:
322  {
323  if ( initialUnitsPerSegment > 1000.0 )
324  {
325  upperMagnitudeMultiplier = 1000.0;
326  setUnitLabeling( tr( "km" ) );
327  }
328  else
329  {
330  upperMagnitudeMultiplier = 1.0;
331  setUnitLabeling( tr( "m" ) );
332  }
333  break;
334  }
335  case Feet:
336  {
337  if ( initialUnitsPerSegment > 5419.95 )
338  {
339  upperMagnitudeMultiplier = 5419.95;
340  setUnitLabeling( tr( "miles" ) );
341  }
342  else
343  {
344  upperMagnitudeMultiplier = 1.0;
345  setUnitLabeling( tr( "ft" ) );
346  }
347  break;
348  }
349  case NauticalMiles:
350  {
351  upperMagnitudeMultiplier = 1;
352  setUnitLabeling( tr( "Nm" ) );
353  break;
354  }
355  }
356 
357  double segmentWidth = initialUnitsPerSegment / upperMagnitudeMultiplier;
358  int segmentMagnitude = floor( log10( segmentWidth ) );
359  double unitsPerSegment = upperMagnitudeMultiplier * ( pow( 10.0, segmentMagnitude ) );
360  double multiplier = floor(( widthInSelectedUnits / ( unitsPerSegment * 10.0 ) ) / 2.5 ) * 2.5;
361 
362  if ( multiplier > 0 )
363  {
364  unitsPerSegment = unitsPerSegment * multiplier;
365  }
366  setNumUnitsPerSegment( unitsPerSegment );
367  setNumMapUnitsPerScaleBarUnit( upperMagnitudeMultiplier );
368 
369  setNumSegments( 4 );
370  setNumSegmentsLeft( 2 );
371  }
372 
374  adjustBoxSize();
375  emit itemChanged();
376 }
377 
379 {
380  if ( !mStyle )
381  {
382  return;
383  }
384 
385  QRectF box = mStyle->calculateBoxSize();
386 
387  //update rect for data defined size and position
388  QRectF newRect = evalItemRect( box );
389 
390  //scale bars have a minimum size, respect that regardless of data defined settings
391  if ( newRect.width() < box.width() )
392  {
393  newRect.setWidth( box.width() );
394  }
395  if ( newRect.height() < box.height() )
396  {
397  newRect.setHeight( box.height() );
398  }
399 
400  setSceneRect( newRect );
401 }
402 
404 {
405  //Don't adjust box size for numeric scale bars:
406  if ( mStyle->name() != "Numeric" )
407  {
408  adjustBoxSize();
409  }
410  QgsComposerItem::update();
411 }
412 
414 {
415  if ( !mStyle )
416  {
417  return;
418  }
419  double width = mStyle->calculateBoxSize().width();
421  double widthAfter = mStyle->calculateBoxSize().width();
422  correctXPositionAlignment( width, widthAfter );
423  update();
424  emit itemChanged();
425 }
426 
427 void QgsComposerScaleBar::segmentPositions( QList<QPair<double, double> >& posWidthList ) const
428 {
429  posWidthList.clear();
430  double mCurrentXCoord = mPen.widthF() + mBoxContentSpace;
431 
432  //left segments
433  for ( int i = 0; i < mNumSegmentsLeft; ++i )
434  {
435  posWidthList.push_back( qMakePair( mCurrentXCoord, mSegmentMillimeters / mNumSegmentsLeft ) );
436  mCurrentXCoord += mSegmentMillimeters / mNumSegmentsLeft;
437  }
438 
439  //right segments
440  for ( int i = 0; i < mNumSegments; ++i )
441  {
442  posWidthList.push_back( qMakePair( mCurrentXCoord, mSegmentMillimeters ) );
443  mCurrentXCoord += mSegmentMillimeters;
444  }
445 }
446 
447 void QgsComposerScaleBar::setStyle( const QString& styleName )
448 {
449  delete mStyle;
450  mStyle = 0;
451 
452  //switch depending on style name
453  if ( styleName == "Single Box" )
454  {
455  mStyle = new QgsSingleBoxScaleBarStyle( this );
456  }
457  else if ( styleName == "Double Box" )
458  {
459  mStyle = new QgsDoubleBoxScaleBarStyle( this );
460  }
461  else if ( styleName == "Line Ticks Middle" || styleName == "Line Ticks Down" || styleName == "Line Ticks Up" )
462  {
463  QgsTicksScaleBarStyle* tickStyle = new QgsTicksScaleBarStyle( this );
464  if ( styleName == "Line Ticks Middle" )
465  {
467  }
468  else if ( styleName == "Line Ticks Down" )
469  {
471  }
472  else if ( styleName == "Line Ticks Up" )
473  {
475  }
476  mStyle = tickStyle;
477  }
478  else if ( styleName == "Numeric" )
479  {
480  mStyle = new QgsNumericScaleBarStyle( this );
481  }
482  emit itemChanged();
483 }
484 
486 {
487  if ( mStyle )
488  {
489  return mStyle->name();
490  }
491  else
492  {
493  return "";
494  }
495 }
496 
498 {
499  if ( mNumSegmentsLeft > 0 )
500  {
501  return QString::number( mNumUnitsPerSegment / mNumMapUnitsPerScaleBarUnit );
502  }
503  else
504  {
505  return "0";
506  }
507 }
508 
510 {
511  return mFont;
512 }
513 
514 void QgsComposerScaleBar::setFont( const QFont& font )
515 {
516  mFont = font;
517  update();
518  emit itemChanged();
519 }
520 
521 bool QgsComposerScaleBar::writeXML( QDomElement& elem, QDomDocument & doc ) const
522 {
523  if ( elem.isNull() )
524  {
525  return false;
526  }
527 
528  QDomElement composerScaleBarElem = doc.createElement( "ComposerScaleBar" );
529  composerScaleBarElem.setAttribute( "height", QString::number( mHeight ) );
530  composerScaleBarElem.setAttribute( "labelBarSpace", QString::number( mLabelBarSpace ) );
531  composerScaleBarElem.setAttribute( "boxContentSpace", QString::number( mBoxContentSpace ) );
532  composerScaleBarElem.setAttribute( "numSegments", mNumSegments );
533  composerScaleBarElem.setAttribute( "numSegmentsLeft", mNumSegmentsLeft );
534  composerScaleBarElem.setAttribute( "numUnitsPerSegment", QString::number( mNumUnitsPerSegment ) );
535  composerScaleBarElem.setAttribute( "segmentMillimeters", QString::number( mSegmentMillimeters ) );
536  composerScaleBarElem.setAttribute( "numMapUnitsPerScaleBarUnit", QString::number( mNumMapUnitsPerScaleBarUnit ) );
537  composerScaleBarElem.setAttribute( "font", mFont.toString() );
538  composerScaleBarElem.setAttribute( "outlineWidth", QString::number( mPen.widthF() ) );
539  composerScaleBarElem.setAttribute( "unitLabel", mUnitLabeling );
540  composerScaleBarElem.setAttribute( "units", mUnits );
541  composerScaleBarElem.setAttribute( "lineJoinStyle", QgsSymbolLayerV2Utils::encodePenJoinStyle( mLineJoinStyle ) );
542  composerScaleBarElem.setAttribute( "lineCapStyle", QgsSymbolLayerV2Utils::encodePenCapStyle( mLineCapStyle ) );
543 
544  //style
545  if ( mStyle )
546  {
547  composerScaleBarElem.setAttribute( "style", mStyle->name() );
548  }
549 
550  //map id
551  if ( mComposerMap )
552  {
553  composerScaleBarElem.setAttribute( "mapId", mComposerMap->id() );
554  }
555 
556  //colors
557 
558  //fill color
559  QDomElement fillColorElem = doc.createElement( "fillColor" );
560  QColor fillColor = mBrush.color();
561  fillColorElem.setAttribute( "red", QString::number( fillColor.red() ) );
562  fillColorElem.setAttribute( "green", QString::number( fillColor.green() ) );
563  fillColorElem.setAttribute( "blue", QString::number( fillColor.blue() ) );
564  fillColorElem.setAttribute( "alpha", QString::number( fillColor.alpha() ) );
565  composerScaleBarElem.appendChild( fillColorElem );
566 
567  //fill color 2
568  QDomElement fillColor2Elem = doc.createElement( "fillColor2" );
569  QColor fillColor2 = mBrush2.color();
570  fillColor2Elem.setAttribute( "red", QString::number( fillColor2.red() ) );
571  fillColor2Elem.setAttribute( "green", QString::number( fillColor2.green() ) );
572  fillColor2Elem.setAttribute( "blue", QString::number( fillColor2.blue() ) );
573  fillColor2Elem.setAttribute( "alpha", QString::number( fillColor2.alpha() ) );
574  composerScaleBarElem.appendChild( fillColor2Elem );
575 
576  //pen color
577  QDomElement strokeColorElem = doc.createElement( "strokeColor" );
578  QColor strokeColor = mPen.color();
579  strokeColorElem.setAttribute( "red", QString::number( strokeColor.red() ) );
580  strokeColorElem.setAttribute( "green", QString::number( strokeColor.green() ) );
581  strokeColorElem.setAttribute( "blue", QString::number( strokeColor.blue() ) );
582  strokeColorElem.setAttribute( "alpha", QString::number( strokeColor.alpha() ) );
583  composerScaleBarElem.appendChild( strokeColorElem );
584 
585  //font color
586  QDomElement fontColorElem = doc.createElement( "textColor" );
587  fontColorElem.setAttribute( "red", QString::number( mFontColor.red() ) );
588  fontColorElem.setAttribute( "green", QString::number( mFontColor.green() ) );
589  fontColorElem.setAttribute( "blue", QString::number( mFontColor.blue() ) );
590  fontColorElem.setAttribute( "alpha", QString::number( mFontColor.alpha() ) );
591  composerScaleBarElem.appendChild( fontColorElem );
592 
593  //alignment
594  composerScaleBarElem.setAttribute( "alignment", QString::number(( int ) mAlignment ) );
595 
596  elem.appendChild( composerScaleBarElem );
597  return _writeXML( composerScaleBarElem, doc );
598 }
599 
600 bool QgsComposerScaleBar::readXML( const QDomElement& itemElem, const QDomDocument& doc )
601 {
602  if ( itemElem.isNull() )
603  {
604  return false;
605  }
606 
607  mHeight = itemElem.attribute( "height", "5.0" ).toDouble();
608  mLabelBarSpace = itemElem.attribute( "labelBarSpace", "3.0" ).toDouble();
609  mBoxContentSpace = itemElem.attribute( "boxContentSpace", "1.0" ).toDouble();
610  mNumSegments = itemElem.attribute( "numSegments", "2" ).toInt();
611  mNumSegmentsLeft = itemElem.attribute( "numSegmentsLeft", "0" ).toInt();
612  mNumUnitsPerSegment = itemElem.attribute( "numUnitsPerSegment", "1.0" ).toDouble();
613  mSegmentMillimeters = itemElem.attribute( "segmentMillimeters", "0.0" ).toDouble();
614  mNumMapUnitsPerScaleBarUnit = itemElem.attribute( "numMapUnitsPerScaleBarUnit", "1.0" ).toDouble();
615  mPen.setWidthF( itemElem.attribute( "outlineWidth", "1.0" ).toDouble() );
616  mUnitLabeling = itemElem.attribute( "unitLabel" );
617  mLineJoinStyle = QgsSymbolLayerV2Utils::decodePenJoinStyle( itemElem.attribute( "lineJoinStyle", "miter" ) );
618  mPen.setJoinStyle( mLineJoinStyle );
619  mLineCapStyle = QgsSymbolLayerV2Utils::decodePenCapStyle( itemElem.attribute( "lineCapStyle", "square" ) );
620  mPen.setCapStyle( mLineCapStyle );
621  QString fontString = itemElem.attribute( "font", "" );
622  if ( !fontString.isEmpty() )
623  {
624  mFont.fromString( fontString );
625  }
626 
627  //colors
628  //fill color
629  QDomNodeList fillColorList = itemElem.elementsByTagName( "fillColor" );
630  if ( fillColorList.size() > 0 )
631  {
632  QDomElement fillColorElem = fillColorList.at( 0 ).toElement();
633  bool redOk, greenOk, blueOk, alphaOk;
634  int fillRed, fillGreen, fillBlue, fillAlpha;
635 
636  fillRed = fillColorElem.attribute( "red" ).toDouble( &redOk );
637  fillGreen = fillColorElem.attribute( "green" ).toDouble( &greenOk );
638  fillBlue = fillColorElem.attribute( "blue" ).toDouble( &blueOk );
639  fillAlpha = fillColorElem.attribute( "alpha" ).toDouble( &alphaOk );
640 
641  if ( redOk && greenOk && blueOk && alphaOk )
642  {
643  mBrush.setColor( QColor( fillRed, fillGreen, fillBlue, fillAlpha ) );
644  }
645  }
646  else
647  {
648  mBrush.setColor( QColor( itemElem.attribute( "brushColor", "#000000" ) ) );
649  }
650 
651  //fill color 2
652  QDomNodeList fillColor2List = itemElem.elementsByTagName( "fillColor2" );
653  if ( fillColor2List.size() > 0 )
654  {
655  QDomElement fillColor2Elem = fillColor2List.at( 0 ).toElement();
656  bool redOk, greenOk, blueOk, alphaOk;
657  int fillRed, fillGreen, fillBlue, fillAlpha;
658 
659  fillRed = fillColor2Elem.attribute( "red" ).toDouble( &redOk );
660  fillGreen = fillColor2Elem.attribute( "green" ).toDouble( &greenOk );
661  fillBlue = fillColor2Elem.attribute( "blue" ).toDouble( &blueOk );
662  fillAlpha = fillColor2Elem.attribute( "alpha" ).toDouble( &alphaOk );
663 
664  if ( redOk && greenOk && blueOk && alphaOk )
665  {
666  mBrush2.setColor( QColor( fillRed, fillGreen, fillBlue, fillAlpha ) );
667  }
668  }
669  else
670  {
671  mBrush2.setColor( QColor( itemElem.attribute( "brush2Color", "#ffffff" ) ) );
672  }
673 
674  //stroke color
675  QDomNodeList strokeColorList = itemElem.elementsByTagName( "strokeColor" );
676  if ( strokeColorList.size() > 0 )
677  {
678  QDomElement strokeColorElem = strokeColorList.at( 0 ).toElement();
679  bool redOk, greenOk, blueOk, alphaOk;
680  int strokeRed, strokeGreen, strokeBlue, strokeAlpha;
681 
682  strokeRed = strokeColorElem.attribute( "red" ).toDouble( &redOk );
683  strokeGreen = strokeColorElem.attribute( "green" ).toDouble( &greenOk );
684  strokeBlue = strokeColorElem.attribute( "blue" ).toDouble( &blueOk );
685  strokeAlpha = strokeColorElem.attribute( "alpha" ).toDouble( &alphaOk );
686 
687  if ( redOk && greenOk && blueOk && alphaOk )
688  {
689  mPen.setColor( QColor( strokeRed, strokeGreen, strokeBlue, strokeAlpha ) );
690  }
691  }
692  else
693  {
694  mPen.setColor( QColor( itemElem.attribute( "penColor", "#000000" ) ) );
695  }
696 
697  //font color
698  QDomNodeList textColorList = itemElem.elementsByTagName( "textColor" );
699  if ( textColorList.size() > 0 )
700  {
701  QDomElement textColorElem = textColorList.at( 0 ).toElement();
702  bool redOk, greenOk, blueOk, alphaOk;
703  int textRed, textGreen, textBlue, textAlpha;
704 
705  textRed = textColorElem.attribute( "red" ).toDouble( &redOk );
706  textGreen = textColorElem.attribute( "green" ).toDouble( &greenOk );
707  textBlue = textColorElem.attribute( "blue" ).toDouble( &blueOk );
708  textAlpha = textColorElem.attribute( "alpha" ).toDouble( &alphaOk );
709 
710  if ( redOk && greenOk && blueOk && alphaOk )
711  {
712  mFontColor = QColor( textRed, textGreen, textBlue, textAlpha );
713  }
714  }
715  else
716  {
717  mFontColor.setNamedColor( itemElem.attribute( "fontColor", "#000000" ) );
718  }
719 
720  //style
721  delete mStyle;
722  mStyle = 0;
723  QString styleString = itemElem.attribute( "style", "" );
724  setStyle( tr( styleString.toLocal8Bit().data() ) );
725 
726  mUnits = ( ScaleBarUnits )itemElem.attribute( "units" ).toInt();
727  mAlignment = ( Alignment )( itemElem.attribute( "alignment", "0" ).toInt() );
728 
729  //map
730  int mapId = itemElem.attribute( "mapId", "-1" ).toInt();
731  if ( mapId >= 0 )
732  {
735  if ( mComposerMap )
736  {
737  connect( mComposerMap, SIGNAL( extentChanged() ), this, SLOT( updateSegmentSize() ) );
738  connect( mComposerMap, SIGNAL( destroyed( QObject* ) ), this, SLOT( invalidateCurrentMap() ) );
739  }
740  }
741 
743 
744  //restore general composer item properties
745  QDomNodeList composerItemList = itemElem.elementsByTagName( "ComposerItem" );
746  if ( composerItemList.size() > 0 )
747  {
748  QDomElement composerItemElem = composerItemList.at( 0 ).toElement();
749  _readXML( composerItemElem, doc );
750  }
751 
752  return true;
753 }
754 
755 void QgsComposerScaleBar::correctXPositionAlignment( double width, double widthAfter )
756 {
757  //Don't adjust position for numeric scale bars:
758  if ( mStyle->name() == "Numeric" )
759  {
760  return;
761  }
762 
763  if ( mAlignment == Middle )
764  {
765  move( -( widthAfter - width ) / 2.0, 0 );
766  }
767  else if ( mAlignment == Right )
768  {
769  move( -( widthAfter - width ), 0 );
770  }
771 }
772 
Double box with alternating colors.
A rectangle specified with double values.
Definition: qgsrectangle.h:35
double mLabelBarSpace
Space between bar and Text labels.
double mHeight
Height of bars/lines.
double mNumUnitsPerSegment
Size of a segment (in map units)
bool writeXML(QDomElement &elem, QDomDocument &doc) const
stores state in Dom element
void setUnits(ScaleBarUnits u)
void setLineCapStyle(Qt::PenCapStyle style)
Sets cap style used when drawing the lines in the scalebar.
double mNumMapUnitsPerScaleBarUnit
Number of map units per scale bar units (e.g.
bool readXML(const QDomElement &itemElem, const QDomDocument &doc)
sets state from Dom document
void setFont(const QFont &font)
A scale bar style that draws text in the form of '1:XXXXX'.
void itemChanged()
Emitted when the item changes.
Qt::PenJoinStyle mLineJoinStyle
const QgsMapSettings & mapSettings() const
Return setting of QGIS map canvas.
void setSourceCrs(long srsid)
sets source spatial reference system (by QGIS CRS)
void setUnitLabeling(const QString &label)
void applyDefaultSize(ScaleBarUnits u=Meters)
Apply default size (scale bar 1/5 of map item width)
void setAlignment(Alignment a)
void applyDefaultSettings()
Apply default settings.
A item that forms part of a map composition.
void setNumSegments(int nSegments)
void segmentPositions(QList< QPair< double, double > > &posWidthList) const
Returns the x - positions of the segment borders (in item coordinates) and the width of the segment...
virtual QRectF calculateBoxSize() const
void setNumSegmentsLeft(int nSegmentsLeft)
bool hasCrsTransformEnabled() const
returns true if projections are enabled for this layer set
ScaleBarUnits units() const
virtual void drawFrame(QPainter *p)
Draw black frame around item.
QgsScaleBarStyle * mStyle
Scalebar style.
QBrush mBrush2
Secondary fill.
virtual QString name() const =0
bool setEllipsoid(const QString &ellipsoid)
sets ellipsoid by its acronym
void update()
Adjusts box size and calls QgsComposerItem::update()
A scale bar that draws segments using short ticks.
void setNumMapUnitsPerScaleBarUnit(double d)
void adjustBoxSize()
Sets box size suitable to content.
bool _readXML(const QDomElement &itemElem, const QDomDocument &doc)
Reads parameter that are not subclass specific in document.
double mSegmentMillimeters
Width of a segment (in mm)
void setLineJoinStyle(Qt::PenJoinStyle style)
Sets join style used when drawing the lines in the scalebar.
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
Definition: qgsrectangle.h:199
double xMaximum() const
Get the x maximum value (right side of rectangle)
Definition: qgsrectangle.h:184
static Qt::PenCapStyle decodePenCapStyle(QString str)
virtual void drawSelectionBoxes(QPainter *p)
Draws additional graphics on selected items.
Qt::PenCapStyle mLineCapStyle
void setStyle(const QString &styleName)
Sets style by name.
virtual void draw(QPainter *p, double xOffset=0) const =0
Draws the style.
const QgsCoordinateReferenceSystem & destinationCrs() const
returns CRS of destination coordinate reference system
static QString encodePenJoinStyle(Qt::PenJoinStyle style)
QgsComposerScaleBar(QgsComposition *composition)
int mNumSegmentsLeft
Number of segments on left side.
void setBackgroundEnabled(const bool drawBackground)
Set whether this item has a Background drawn around it or not.
QRectF evalItemRect(const QRectF &newRect)
Update an item rect to consider data defined position and size of item.
A class to represent a point geometry.
Definition: qgspoint.h:63
const QgsComposerMap * composerMap() const
Graphics scene for map printing.
ScaleBarUnits
Added in version 1.9.
Object representing map window.
QString style() const
Returns style name.
QgsRectangle * currentMapExtent()
Returns a pointer to the current map extent, which is either the original user specified extent or th...
void setComposerMap(const QgsComposerMap *map)
void refreshSegmentMillimeters()
Calculates with of a segment in mm and stores it in mSegmentMillimeters.
void invalidateCurrentMap()
Sets mCompositionMap to 0 if the map is deleted.
void setBoxContentSpace(double space)
int id() const
Get identification number.
General purpose distance and area calculator.
static double textWidthMM(const QFont &font, const QString &text)
Calculate font width in millimeters for a string, including workarounds for QT font rendering issues...
QgsComposition * mComposition
int mNumSegments
Number of segments on right side.
void paint(QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget)
Reimplementation of QCanvasItem::paint.
bool _writeXML(QDomElement &itemElem, QDomDocument &doc) const
Writes parameter that are not subclass specific in document.
Alignment
Added in version 1.8.
virtual void drawBackground(QPainter *p)
Draw background.
static QgsProject * instance()
access to canonical QgsProject instance
Definition: qgsproject.cpp:362
virtual void setSceneRect(const QRectF &rectangle)
Sets this items bound in scene coordinates such that 1 item size units corresponds to 1 scene size un...
double measureLine(const QList< QgsPoint > &points)
measures line
double mBoxContentSpace
Space between content and item box.
static double fromUnitToUnitFactor(QGis::UnitType fromUnit, QGis::UnitType toUnit)
Returns the conversion factor between the specified units.
Definition: qgis.cpp:123
QString mUnitLabeling
Labeling of map units.
static Qt::PenJoinStyle decodePenJoinStyle(QString str)
double mapWidth() const
Returns diagonal of composer map in selected units (map units / meters / feet / nautical miles) ...
const QgsComposerMap * mComposerMap
Reference to composer map object.
void setNumUnitsPerSegment(double units)
const QgsComposerMap * getComposerMapById(const int id) const
Returns the composer map with specified id.
double width() const
Width of the rectangle.
Definition: qgsrectangle.h:204
void move(double dx, double dy)
Moves item in canvas coordinates.
Scalebar style that draws a single box with alternating color for the segments.
void correctXPositionAlignment(double width, double widthAfter)
Moves scalebar position to the left / right depending on alignment and change in item width...
double xMinimum() const
Get the x minimum value (left side of rectangle)
Definition: qgsrectangle.h:189
void setEllipsoidalMode(bool flag)
sets whether coordinates must be projected to ellipsoid before measuring
void setTickPosition(TickPosition p)
QString firstLabelString() const
Returns string of first label (important for drawing, labeling, size calculation. ...
static QString encodePenCapStyle(Qt::PenCapStyle style)
#define tr(sourceText)