QGIS API Documentation  2.8.2-Wien
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups 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  if ( !shouldDrawItem() )
68  {
69  return;
70  }
71 
72  drawBackground( painter );
73 
74  //x-offset is half of first label width because labels are drawn centered
75  QString firstLabel = firstLabelString();
76  double firstLabelWidth = QgsComposerUtils::textWidthMM( mFont, firstLabel );
77 
78  mStyle->draw( painter, firstLabelWidth / 2 );
79 
80  //draw frame and selection boxes if necessary
81  drawFrame( painter );
82  if ( isSelected() )
83  {
84  drawSelectionBoxes( painter );
85  }
86 }
87 
89 {
90  if ( !mStyle )
91  {
92  mNumSegments = nSegments;
93  return;
94  }
95  double width = mStyle->calculateBoxSize().width();
96  mNumSegments = nSegments;
97  double widthAfter = mStyle->calculateBoxSize().width();
98  correctXPositionAlignment( width, widthAfter );
99  emit itemChanged();
100 }
101 
103 {
104  if ( !mStyle )
105  {
107  return;
108  }
109  double width = mStyle->calculateBoxSize().width();
112  double widthAfter = mStyle->calculateBoxSize().width();
113  correctXPositionAlignment( width, widthAfter );
114  emit itemChanged();
115 }
116 
118 {
119  if ( !mStyle )
120  {
121  mNumSegmentsLeft = nSegmentsLeft;
122  return;
123  }
124  double width = mStyle->calculateBoxSize().width();
125  mNumSegmentsLeft = nSegmentsLeft;
126  double widthAfter = mStyle->calculateBoxSize().width();
127  correctXPositionAlignment( width, widthAfter );
128  emit itemChanged();
129 }
130 
132 {
133  if ( !mStyle )
134  {
135  mBoxContentSpace = space;
136  return;
137  }
138  double width = mStyle->calculateBoxSize().width();
139  mBoxContentSpace = space;
140  double widthAfter = mStyle->calculateBoxSize().width();
141  correctXPositionAlignment( width, widthAfter );
142  emit itemChanged();
143 }
144 
146 {
147  if ( mComposerMap )
148  {
149  disconnect( mComposerMap, SIGNAL( extentChanged() ), this, SLOT( updateSegmentSize() ) );
150  disconnect( mComposerMap, SIGNAL( destroyed( QObject* ) ), this, SLOT( invalidateCurrentMap() ) );
151  }
152  mComposerMap = map;
153 
154  if ( !map )
155  {
156  return;
157  }
158 
159  connect( mComposerMap, SIGNAL( extentChanged() ), this, SLOT( updateSegmentSize() ) );
160  connect( mComposerMap, SIGNAL( destroyed( QObject* ) ), this, SLOT( invalidateCurrentMap() ) );
161 
163  emit itemChanged();
164 }
165 
167 {
168  if ( !mComposerMap )
169  {
170  return;
171  }
172 
173  disconnect( mComposerMap, SIGNAL( extentChanged() ), this, SLOT( updateSegmentSize() ) );
174  disconnect( mComposerMap, SIGNAL( destroyed( QObject* ) ), this, SLOT( invalidateCurrentMap() ) );
175  mComposerMap = 0;
176 }
177 
179 {
180  if ( mComposerMap )
181  {
182  //get extent of composer map
183  QgsRectangle composerMapRect = *( mComposerMap->currentMapExtent() );
184 
185  //get mm dimension of composer map
186  QRectF composerItemRect = mComposerMap->rect();
187 
188  //calculate size depending on mNumUnitsPerSegment
189  mSegmentMillimeters = composerItemRect.width() / mapWidth() * mNumUnitsPerSegment;
190  }
191 }
192 
194 {
195  if ( !mComposerMap )
196  {
197  return 0.0;
198  }
199 
200  QgsRectangle composerMapRect = *( mComposerMap->currentMapExtent() );
201  if ( mUnits == MapUnits )
202  {
203  return composerMapRect.width();
204  }
205  else
206  {
207  QgsDistanceArea da;
210  da.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", "WGS84" ) );
211 
212  double measure = da.measureLine( QgsPoint( composerMapRect.xMinimum(), composerMapRect.yMinimum() ), QgsPoint( composerMapRect.xMaximum(), composerMapRect.yMinimum() ) );
214  {
216  }
218  {
220  }
221  return measure;
222  }
223 }
224 
226 {
227  mAlignment = a;
228  update();
229  emit itemChanged();
230 }
231 
233 {
234  mUnits = u;
236  emit itemChanged();
237 }
238 
239 void QgsComposerScaleBar::setLineJoinStyle( Qt::PenJoinStyle style )
240 {
241  if ( mLineJoinStyle == style )
242  {
243  //no change
244  return;
245  }
247  mPen.setJoinStyle( mLineJoinStyle );
248  update();
249  emit itemChanged();
250 }
251 
252 void QgsComposerScaleBar::setLineCapStyle( Qt::PenCapStyle style )
253 {
254  if ( mLineCapStyle == style )
255  {
256  //no change
257  return;
258  }
260  mPen.setCapStyle( mLineCapStyle );
261  update();
262  emit itemChanged();
263 }
264 
266 {
267  mNumSegments = 2;
268  mNumSegmentsLeft = 0;
269 
271 
272  //style
273  delete mStyle;
274  mStyle = new QgsSingleBoxScaleBarStyle( this );
275 
276  mHeight = 3;
277 
278  //default to no background
279  setBackgroundEnabled( false );
280 
281  mPen = QPen( Qt::black );
282  mPen.setJoinStyle( mLineJoinStyle );
283  mPen.setCapStyle( mLineCapStyle );
284  mPen.setWidthF( 1.0 );
285 
286  mBrush.setColor( Qt::black );
287  mBrush.setStyle( Qt::SolidPattern );
288 
289  mBrush2.setColor( Qt::white );
290  mBrush2.setStyle( Qt::SolidPattern );
291 
292  //get default composer font from settings
293  QSettings settings;
294  QString defaultFontString = settings.value( "/Composer/defaultFont" ).toString();
295  if ( !defaultFontString.isEmpty() )
296  {
297  mFont.setFamily( defaultFontString );
298  }
299  mFont.setPointSizeF( 12.0 );
300  mFontColor = QColor( 0, 0, 0 );
301 
302  mLabelBarSpace = 3.0;
303  mBoxContentSpace = 1.0;
304  emit itemChanged();
305 }
306 
308 {
309  if ( mComposerMap )
310  {
311  setUnits( u );
312  double upperMagnitudeMultiplier = 1.0;
313  double widthInSelectedUnits = mapWidth();
314  double initialUnitsPerSegment = widthInSelectedUnits / 10.0; //default scalebar width equals half the map width
315  setNumUnitsPerSegment( initialUnitsPerSegment );
316 
317  switch ( mUnits )
318  {
319  case MapUnits:
320  {
321  upperMagnitudeMultiplier = 1.0;
322  setUnitLabeling( tr( "units" ) );
323  break;
324  }
325  case Meters:
326  {
327  if ( initialUnitsPerSegment > 1000.0 )
328  {
329  upperMagnitudeMultiplier = 1000.0;
330  setUnitLabeling( tr( "km" ) );
331  }
332  else
333  {
334  upperMagnitudeMultiplier = 1.0;
335  setUnitLabeling( tr( "m" ) );
336  }
337  break;
338  }
339  case Feet:
340  {
341  if ( initialUnitsPerSegment > 5419.95 )
342  {
343  upperMagnitudeMultiplier = 5419.95;
344  setUnitLabeling( tr( "miles" ) );
345  }
346  else
347  {
348  upperMagnitudeMultiplier = 1.0;
349  setUnitLabeling( tr( "ft" ) );
350  }
351  break;
352  }
353  case NauticalMiles:
354  {
355  upperMagnitudeMultiplier = 1;
356  setUnitLabeling( tr( "Nm" ) );
357  break;
358  }
359  }
360 
361  double segmentWidth = initialUnitsPerSegment / upperMagnitudeMultiplier;
362  int segmentMagnitude = floor( log10( segmentWidth ) );
363  double unitsPerSegment = upperMagnitudeMultiplier * ( pow( 10.0, segmentMagnitude ) );
364  double multiplier = floor(( widthInSelectedUnits / ( unitsPerSegment * 10.0 ) ) / 2.5 ) * 2.5;
365 
366  if ( multiplier > 0 )
367  {
368  unitsPerSegment = unitsPerSegment * multiplier;
369  }
370  setNumUnitsPerSegment( unitsPerSegment );
371  setNumMapUnitsPerScaleBarUnit( upperMagnitudeMultiplier );
372 
373  setNumSegments( 4 );
374  setNumSegmentsLeft( 2 );
375  }
376 
378  adjustBoxSize();
379  emit itemChanged();
380 }
381 
383 {
384  if ( !mStyle )
385  {
386  return;
387  }
388 
389  QRectF box = mStyle->calculateBoxSize();
390  if ( rect().height() > box.height() )
391  {
392  //keep user specified item height if higher than minimum scale bar height
393  box.setHeight( rect().height() );
394  }
395 
396  //update rect for data defined size and position
397  QRectF newRect = evalItemRect( box, true );
398 
399  //scale bars have a minimum size, respect that regardless of data defined settings
400  if ( newRect.width() < box.width() )
401  {
402  newRect.setWidth( box.width() );
403  }
404  if ( newRect.height() < box.height() )
405  {
406  newRect.setHeight( box.height() );
407  }
408 
410 }
411 
412 void QgsComposerScaleBar::setSceneRect( const QRectF& rectangle )
413 {
414  QRectF box = mStyle->calculateBoxSize();
415  if ( rectangle.height() > box.height() )
416  {
417  //keep user specified item height if higher than minimum scale bar height
418  box.setHeight( rectangle.height() );
419  }
420  box.moveTopLeft( rectangle.topLeft() );
421 
422  //update rect for data defined size and position
423  QRectF newRect = evalItemRect( rectangle );
424 
425  //scale bars have a minimum size, respect that regardless of data defined settings
426  if ( newRect.width() < box.width() )
427  {
428  newRect.setWidth( box.width() );
429  }
430  if ( newRect.height() < box.height() )
431  {
432  newRect.setHeight( box.height() );
433  }
434 
436 }
437 
439 {
440  //Don't adjust box size for numeric scale bars:
441  if ( mStyle && mStyle->name() != "Numeric" )
442  {
443  adjustBoxSize();
444  }
446 }
447 
449 {
450  if ( !mStyle )
451  {
452  return;
453  }
454  double width = mStyle->calculateBoxSize().width();
456  double widthAfter = mStyle->calculateBoxSize().width();
457  correctXPositionAlignment( width, widthAfter );
458  update();
459  emit itemChanged();
460 }
461 
462 void QgsComposerScaleBar::segmentPositions( QList<QPair<double, double> >& posWidthList ) const
463 {
464  posWidthList.clear();
465  double mCurrentXCoord = mPen.widthF() + mBoxContentSpace;
466 
467  //left segments
468  double leftSegmentSize = mSegmentMillimeters / mNumSegmentsLeft;
469  for ( int i = 0; i < mNumSegmentsLeft; ++i )
470  {
471  posWidthList.push_back( qMakePair( mCurrentXCoord, leftSegmentSize ) );
472  mCurrentXCoord += leftSegmentSize;
473  }
474 
475  //right segments
476  for ( int i = 0; i < mNumSegments; ++i )
477  {
478  posWidthList.push_back( qMakePair( mCurrentXCoord, mSegmentMillimeters ) );
479  mCurrentXCoord += mSegmentMillimeters;
480  }
481 }
482 
483 void QgsComposerScaleBar::setStyle( const QString& styleName )
484 {
485  delete mStyle;
486  mStyle = 0;
487 
488  //switch depending on style name
489  if ( styleName == "Single Box" )
490  {
491  mStyle = new QgsSingleBoxScaleBarStyle( this );
492  }
493  else if ( styleName == "Double Box" )
494  {
495  mStyle = new QgsDoubleBoxScaleBarStyle( this );
496  }
497  else if ( styleName == "Line Ticks Middle" || styleName == "Line Ticks Down" || styleName == "Line Ticks Up" )
498  {
499  QgsTicksScaleBarStyle* tickStyle = new QgsTicksScaleBarStyle( this );
500  if ( styleName == "Line Ticks Middle" )
501  {
503  }
504  else if ( styleName == "Line Ticks Down" )
505  {
507  }
508  else if ( styleName == "Line Ticks Up" )
509  {
511  }
512  mStyle = tickStyle;
513  }
514  else if ( styleName == "Numeric" )
515  {
516  mStyle = new QgsNumericScaleBarStyle( this );
517  }
518  emit itemChanged();
519 }
520 
522 {
523  if ( mStyle )
524  {
525  return mStyle->name();
526  }
527  else
528  {
529  return "";
530  }
531 }
532 
534 {
535  if ( mNumSegmentsLeft > 0 )
536  {
537  return QString::number( mNumUnitsPerSegment / mNumMapUnitsPerScaleBarUnit );
538  }
539  else
540  {
541  return "0";
542  }
543 }
544 
546 {
547  return mFont;
548 }
549 
550 void QgsComposerScaleBar::setFont( const QFont& font )
551 {
552  mFont = font;
553  update();
554  emit itemChanged();
555 }
556 
557 bool QgsComposerScaleBar::writeXML( QDomElement& elem, QDomDocument & doc ) const
558 {
559  if ( elem.isNull() )
560  {
561  return false;
562  }
563 
564  QDomElement composerScaleBarElem = doc.createElement( "ComposerScaleBar" );
565  composerScaleBarElem.setAttribute( "height", QString::number( mHeight ) );
566  composerScaleBarElem.setAttribute( "labelBarSpace", QString::number( mLabelBarSpace ) );
567  composerScaleBarElem.setAttribute( "boxContentSpace", QString::number( mBoxContentSpace ) );
568  composerScaleBarElem.setAttribute( "numSegments", mNumSegments );
569  composerScaleBarElem.setAttribute( "numSegmentsLeft", mNumSegmentsLeft );
570  composerScaleBarElem.setAttribute( "numUnitsPerSegment", QString::number( mNumUnitsPerSegment ) );
571  composerScaleBarElem.setAttribute( "segmentMillimeters", QString::number( mSegmentMillimeters ) );
572  composerScaleBarElem.setAttribute( "numMapUnitsPerScaleBarUnit", QString::number( mNumMapUnitsPerScaleBarUnit ) );
573  composerScaleBarElem.setAttribute( "font", mFont.toString() );
574  composerScaleBarElem.setAttribute( "outlineWidth", QString::number( mPen.widthF() ) );
575  composerScaleBarElem.setAttribute( "unitLabel", mUnitLabeling );
576  composerScaleBarElem.setAttribute( "units", mUnits );
577  composerScaleBarElem.setAttribute( "lineJoinStyle", QgsSymbolLayerV2Utils::encodePenJoinStyle( mLineJoinStyle ) );
578  composerScaleBarElem.setAttribute( "lineCapStyle", QgsSymbolLayerV2Utils::encodePenCapStyle( mLineCapStyle ) );
579 
580  //style
581  if ( mStyle )
582  {
583  composerScaleBarElem.setAttribute( "style", mStyle->name() );
584  }
585 
586  //map id
587  if ( mComposerMap )
588  {
589  composerScaleBarElem.setAttribute( "mapId", mComposerMap->id() );
590  }
591 
592  //colors
593 
594  //fill color
595  QDomElement fillColorElem = doc.createElement( "fillColor" );
596  QColor fillColor = mBrush.color();
597  fillColorElem.setAttribute( "red", QString::number( fillColor.red() ) );
598  fillColorElem.setAttribute( "green", QString::number( fillColor.green() ) );
599  fillColorElem.setAttribute( "blue", QString::number( fillColor.blue() ) );
600  fillColorElem.setAttribute( "alpha", QString::number( fillColor.alpha() ) );
601  composerScaleBarElem.appendChild( fillColorElem );
602 
603  //fill color 2
604  QDomElement fillColor2Elem = doc.createElement( "fillColor2" );
605  QColor fillColor2 = mBrush2.color();
606  fillColor2Elem.setAttribute( "red", QString::number( fillColor2.red() ) );
607  fillColor2Elem.setAttribute( "green", QString::number( fillColor2.green() ) );
608  fillColor2Elem.setAttribute( "blue", QString::number( fillColor2.blue() ) );
609  fillColor2Elem.setAttribute( "alpha", QString::number( fillColor2.alpha() ) );
610  composerScaleBarElem.appendChild( fillColor2Elem );
611 
612  //pen color
613  QDomElement strokeColorElem = doc.createElement( "strokeColor" );
614  QColor strokeColor = mPen.color();
615  strokeColorElem.setAttribute( "red", QString::number( strokeColor.red() ) );
616  strokeColorElem.setAttribute( "green", QString::number( strokeColor.green() ) );
617  strokeColorElem.setAttribute( "blue", QString::number( strokeColor.blue() ) );
618  strokeColorElem.setAttribute( "alpha", QString::number( strokeColor.alpha() ) );
619  composerScaleBarElem.appendChild( strokeColorElem );
620 
621  //font color
622  QDomElement fontColorElem = doc.createElement( "textColor" );
623  fontColorElem.setAttribute( "red", QString::number( mFontColor.red() ) );
624  fontColorElem.setAttribute( "green", QString::number( mFontColor.green() ) );
625  fontColorElem.setAttribute( "blue", QString::number( mFontColor.blue() ) );
626  fontColorElem.setAttribute( "alpha", QString::number( mFontColor.alpha() ) );
627  composerScaleBarElem.appendChild( fontColorElem );
628 
629  //alignment
630  composerScaleBarElem.setAttribute( "alignment", QString::number(( int ) mAlignment ) );
631 
632  elem.appendChild( composerScaleBarElem );
633  return _writeXML( composerScaleBarElem, doc );
634 }
635 
636 bool QgsComposerScaleBar::readXML( const QDomElement& itemElem, const QDomDocument& doc )
637 {
638  if ( itemElem.isNull() )
639  {
640  return false;
641  }
642 
643  mHeight = itemElem.attribute( "height", "5.0" ).toDouble();
644  mLabelBarSpace = itemElem.attribute( "labelBarSpace", "3.0" ).toDouble();
645  mBoxContentSpace = itemElem.attribute( "boxContentSpace", "1.0" ).toDouble();
646  mNumSegments = itemElem.attribute( "numSegments", "2" ).toInt();
647  mNumSegmentsLeft = itemElem.attribute( "numSegmentsLeft", "0" ).toInt();
648  mNumUnitsPerSegment = itemElem.attribute( "numUnitsPerSegment", "1.0" ).toDouble();
649  mSegmentMillimeters = itemElem.attribute( "segmentMillimeters", "0.0" ).toDouble();
650  mNumMapUnitsPerScaleBarUnit = itemElem.attribute( "numMapUnitsPerScaleBarUnit", "1.0" ).toDouble();
651  mPen.setWidthF( itemElem.attribute( "outlineWidth", "1.0" ).toDouble() );
652  mUnitLabeling = itemElem.attribute( "unitLabel" );
653  mLineJoinStyle = QgsSymbolLayerV2Utils::decodePenJoinStyle( itemElem.attribute( "lineJoinStyle", "miter" ) );
654  mPen.setJoinStyle( mLineJoinStyle );
655  mLineCapStyle = QgsSymbolLayerV2Utils::decodePenCapStyle( itemElem.attribute( "lineCapStyle", "square" ) );
656  mPen.setCapStyle( mLineCapStyle );
657  QString fontString = itemElem.attribute( "font", "" );
658  if ( !fontString.isEmpty() )
659  {
660  mFont.fromString( fontString );
661  }
662 
663  //colors
664  //fill color
665  QDomNodeList fillColorList = itemElem.elementsByTagName( "fillColor" );
666  if ( fillColorList.size() > 0 )
667  {
668  QDomElement fillColorElem = fillColorList.at( 0 ).toElement();
669  bool redOk, greenOk, blueOk, alphaOk;
670  int fillRed, fillGreen, fillBlue, fillAlpha;
671 
672  fillRed = fillColorElem.attribute( "red" ).toDouble( &redOk );
673  fillGreen = fillColorElem.attribute( "green" ).toDouble( &greenOk );
674  fillBlue = fillColorElem.attribute( "blue" ).toDouble( &blueOk );
675  fillAlpha = fillColorElem.attribute( "alpha" ).toDouble( &alphaOk );
676 
677  if ( redOk && greenOk && blueOk && alphaOk )
678  {
679  mBrush.setColor( QColor( fillRed, fillGreen, fillBlue, fillAlpha ) );
680  }
681  }
682  else
683  {
684  mBrush.setColor( QColor( itemElem.attribute( "brushColor", "#000000" ) ) );
685  }
686 
687  //fill color 2
688  QDomNodeList fillColor2List = itemElem.elementsByTagName( "fillColor2" );
689  if ( fillColor2List.size() > 0 )
690  {
691  QDomElement fillColor2Elem = fillColor2List.at( 0 ).toElement();
692  bool redOk, greenOk, blueOk, alphaOk;
693  int fillRed, fillGreen, fillBlue, fillAlpha;
694 
695  fillRed = fillColor2Elem.attribute( "red" ).toDouble( &redOk );
696  fillGreen = fillColor2Elem.attribute( "green" ).toDouble( &greenOk );
697  fillBlue = fillColor2Elem.attribute( "blue" ).toDouble( &blueOk );
698  fillAlpha = fillColor2Elem.attribute( "alpha" ).toDouble( &alphaOk );
699 
700  if ( redOk && greenOk && blueOk && alphaOk )
701  {
702  mBrush2.setColor( QColor( fillRed, fillGreen, fillBlue, fillAlpha ) );
703  }
704  }
705  else
706  {
707  mBrush2.setColor( QColor( itemElem.attribute( "brush2Color", "#ffffff" ) ) );
708  }
709 
710  //stroke color
711  QDomNodeList strokeColorList = itemElem.elementsByTagName( "strokeColor" );
712  if ( strokeColorList.size() > 0 )
713  {
714  QDomElement strokeColorElem = strokeColorList.at( 0 ).toElement();
715  bool redOk, greenOk, blueOk, alphaOk;
716  int strokeRed, strokeGreen, strokeBlue, strokeAlpha;
717 
718  strokeRed = strokeColorElem.attribute( "red" ).toDouble( &redOk );
719  strokeGreen = strokeColorElem.attribute( "green" ).toDouble( &greenOk );
720  strokeBlue = strokeColorElem.attribute( "blue" ).toDouble( &blueOk );
721  strokeAlpha = strokeColorElem.attribute( "alpha" ).toDouble( &alphaOk );
722 
723  if ( redOk && greenOk && blueOk && alphaOk )
724  {
725  mPen.setColor( QColor( strokeRed, strokeGreen, strokeBlue, strokeAlpha ) );
726  }
727  }
728  else
729  {
730  mPen.setColor( QColor( itemElem.attribute( "penColor", "#000000" ) ) );
731  }
732 
733  //font color
734  QDomNodeList textColorList = itemElem.elementsByTagName( "textColor" );
735  if ( textColorList.size() > 0 )
736  {
737  QDomElement textColorElem = textColorList.at( 0 ).toElement();
738  bool redOk, greenOk, blueOk, alphaOk;
739  int textRed, textGreen, textBlue, textAlpha;
740 
741  textRed = textColorElem.attribute( "red" ).toDouble( &redOk );
742  textGreen = textColorElem.attribute( "green" ).toDouble( &greenOk );
743  textBlue = textColorElem.attribute( "blue" ).toDouble( &blueOk );
744  textAlpha = textColorElem.attribute( "alpha" ).toDouble( &alphaOk );
745 
746  if ( redOk && greenOk && blueOk && alphaOk )
747  {
748  mFontColor = QColor( textRed, textGreen, textBlue, textAlpha );
749  }
750  }
751  else
752  {
753  mFontColor.setNamedColor( itemElem.attribute( "fontColor", "#000000" ) );
754  }
755 
756  //style
757  delete mStyle;
758  mStyle = 0;
759  QString styleString = itemElem.attribute( "style", "" );
760  setStyle( tr( styleString.toLocal8Bit().data() ) );
761 
762  mUnits = ( ScaleBarUnits )itemElem.attribute( "units" ).toInt();
763  mAlignment = ( Alignment )( itemElem.attribute( "alignment", "0" ).toInt() );
764 
765  //map
766  int mapId = itemElem.attribute( "mapId", "-1" ).toInt();
767  if ( mapId >= 0 )
768  {
771  if ( mComposerMap )
772  {
773  connect( mComposerMap, SIGNAL( extentChanged() ), this, SLOT( updateSegmentSize() ) );
774  connect( mComposerMap, SIGNAL( destroyed( QObject* ) ), this, SLOT( invalidateCurrentMap() ) );
775  }
776  }
777 
779 
780  //restore general composer item properties
781  QDomNodeList composerItemList = itemElem.elementsByTagName( "ComposerItem" );
782  if ( composerItemList.size() > 0 )
783  {
784  QDomElement composerItemElem = composerItemList.at( 0 ).toElement();
785  _readXML( composerItemElem, doc );
786  }
787 
788  return true;
789 }
790 
791 void QgsComposerScaleBar::correctXPositionAlignment( double width, double widthAfter )
792 {
793  //Don't adjust position for numeric scale bars:
794  if ( mStyle->name() == "Numeric" )
795  {
796  return;
797  }
798 
799  if ( mAlignment == Middle )
800  {
801  move( -( widthAfter - width ) / 2.0, 0 );
802  }
803  else if ( mAlignment == Right )
804  {
805  move( -( widthAfter - width ), 0 );
806  }
807 }
808