scalebarwidget_v1.diff

Patch for scalebar widget generated against r14228 - Tim Sutton, 2010-09-15 03:46 AM

Download (69.6 KB)

View differences:

python/CMakeLists.txt (working copy)
47 47
# additional gui includes
48 48
INCLUDE_DIRECTORIES(
49 49
    ../src/gui
50
    ../src/gui/mapwidgets
50 51
    ../src/gui/symbology-ng
51 52
    ../src/plugins
52 53
    ${CMAKE_BINARY_DIR}/src/gui
src/app/qgsmaptoolscalebarannotation.cpp (working copy)
1 1
/***************************************************************************
2
                              qgsmaptooltextannotation.cpp
2
                              qgsmaptoolscalebarannotation.cpp
3 3
                              -------------------------------
4
  begin                : February 9, 2010
5
  copyright            : (C) 2010 by Marco Hugentobler
6
  email                : marco dot hugentobler at hugis dot net
4
  begin                : September 15, 2010
5
  copyright            : (C) 2010 by Tim Sutton
6
  email                : Tim Sutton
7 7
 ***************************************************************************/
8 8

  
9 9
/***************************************************************************
......
15 15
 *                                                                         *
16 16
 ***************************************************************************/
17 17

  
18
#include "qgsmaptooltextannotation.h"
19
#include "qgstextannotationitem.h"
18
#include "qgsmaptoolscalebarannotation.h"
19
#include "qgsscalebarannotationitem.h"
20 20
#include <QMouseEvent>
21 21

  
22
QgsMapToolTextAnnotation::QgsMapToolTextAnnotation( QgsMapCanvas* canvas ): QgsMapToolAnnotation( canvas )
22
QgsMapToolScaleBarAnnotation::QgsMapToolScaleBarAnnotation( QgsMapCanvas* canvas ): QgsMapToolAnnotation( canvas )
23 23
{
24 24

  
25 25
}
26 26

  
27
QgsMapToolTextAnnotation::~QgsMapToolTextAnnotation()
27
QgsMapToolScaleBarAnnotation::~QgsMapToolScaleBarAnnotation()
28 28
{
29 29

  
30 30
}
31 31

  
32
QgsAnnotationItem* QgsMapToolTextAnnotation::createItem( QMouseEvent* e )
32
QgsAnnotationItem* QgsMapToolScaleBarAnnotation::createItem( QMouseEvent* e )
33 33
{
34 34
  QgsPoint mapCoord = toMapCoordinates( e->pos() );
35
  QgsTextAnnotationItem* textItem = new QgsTextAnnotationItem( mCanvas );
36
  textItem->setMapPosition( toMapCoordinates( e->pos() ) );
37
  textItem->setFrameSize( QSizeF( 200, 100 ) );
38
  textItem->setSelected( true );
39
  return textItem;
35
  QgsScaleBarAnnotationItem* scaleBarItem = new QgsScaleBarAnnotationItem( mCanvas );
36
  scaleBarItem->setMapPosition( toMapCoordinates( e->pos() ) );
37
  scaleBarItem->setFrameSize( QSizeF( 200, 100 ) );
38
  scaleBarItem->setSelected( true );
39
  return scaleBarItem;
40 40
}
41 41

  
src/app/qgsmaptoolscalebarannotation.h (working copy)
1 1
/***************************************************************************
2
                              qgsmaptooltextannotation.h
2
                              qgsmaptoolscalebarannotation.h
3 3
                              -------------------------
4
  begin                : February 9, 2010
5
  copyright            : (C) 2010 by Marco Hugentobler
6
  email                : marco dot hugentobler at hugis dot net
4
  begin                : September 15, 2010
5
  copyright            : (C) 2010 by Tim Sutton
6
  email                : [email protected]
7 7
 ***************************************************************************/
8 8

  
9 9
/***************************************************************************
......
15 15
 *                                                                         *
16 16
 ***************************************************************************/
17 17

  
18
#ifndef QGSMAPTOOLTEXTANNOTATION_H
19
#define QGSMAPTOOLTEXTANNOTATION_H
18
#ifndef QGSMAPTOOLSCALEBARANNOTATION_H
19
#define QGSMAPTOOLSCALEBARANNOTATION_H
20 20

  
21 21
#include "qgsmaptoolannotation.h"
22 22

  
23
class QgsMapToolTextAnnotation: public QgsMapToolAnnotation
23
class QgsMapToolScaleBarAnnotation: public QgsMapToolAnnotation
24 24
{
25 25
  public:
26
    QgsMapToolTextAnnotation( QgsMapCanvas* canvas );
27
    ~QgsMapToolTextAnnotation();
26
    QgsMapToolScaleBarAnnotation( QgsMapCanvas* canvas );
27
    ~QgsMapToolScaleBarAnnotation();
28 28

  
29 29
  protected:
30 30
    QgsAnnotationItem* createItem( QMouseEvent* e );
31 31
};
32 32

  
33
#endif // QGSMAPTOOLTEXTANNOTATION_H
33
#endif // QGSMAPTOOLSCALEBARANNOTATION_H
src/app/qgisapp.h (working copy)
686 686
    //annotations
687 687
    void addFormAnnotation();
688 688
    void addTextAnnotation();
689
    void addScaleBarAnnotation();
689 690
    void modifyAnnotation();
690 691

  
691 692
    //! shows label settings dialog (for labeling-ng)
......
925 926
    QAction *mActionDraw;
926 927
    QAction *mActionViewSeparator5;
927 928
    QAction *mActionTextAnnotation;
929
    QAction *mActionScaleBarAnnotation;
928 930
    QAction *mActionFormAnnotation;
929 931
    QAction *mActionAnnotation;
930 932
    QAction *mActionLabeling;
......
1052 1054
        QgsMapTool* mAnnotation;
1053 1055
        QgsMapTool* mFormAnnotation;
1054 1056
        QgsMapTool* mTextAnnotation;
1057
        QgsMapTool* mScaleBarAnnotation;
1055 1058
    } mMapTools;
1056 1059

  
1057 1060
    QgsMapTool *mNonEditMapTool;
src/app/CMakeLists.txt (working copy)
57 57
  qgsmaptoolsimplify.cpp
58 58
  qgsmaptoolsplitfeatures.cpp
59 59
  qgsmaptooltextannotation.cpp
60
  qgsmaptoolscalebarannotation.cpp
60 61
  qgsmaptoolvertexedit.cpp
61 62
  qgsmeasuredialog.cpp
62 63
  qgsmeasuretool.cpp
......
334 335
  ${CMAKE_CURRENT_BINARY_DIR}/../ui
335 336
  ${QT_QTUITOOLS_INCLUDE_DIR}
336 337
  ../core
337
  ../core/gps ../core/gps/qextserialport
338
  ../core/composer ../core/raster ../core/renderer ../core/symbology ../core/symbology-ng
339
  ../gui ../gui/symbology-ng
338
  ../core/gps 
339
  ../core/gps/qextserialport
340
  ../core/composer 
341
  ../core/raster 
342
  ../core/renderer 
343
  ../core/symbology 
344
  ../core/symbology-ng
345
  ../gui 
346
  ../gui/symbology-ng
347
  ../gui/mapwidgets
340 348
  ../plugins
341 349
  ../python
342 350
  gps
src/app/qgisapp.cpp (working copy)
112 112
#include "qgsexception.h"
113 113
#include "qgsfeature.h"
114 114
#include "qgsformannotationitem.h"
115
#include "qgsscalebarannotationitem.h"
115 116
#include "qgslabelinggui.h"
116 117
#include "qgsnewvectorlayerdialog.h"
117 118
#include "qgshelpviewer.h"
......
209 210
#include "qgsmaptoolrotatepointsymbols.h"
210 211
#include "qgsmaptoolsplitfeatures.h"
211 212
#include "qgsmaptooltextannotation.h"
213
#include "qgsmaptoolscalebarannotation.h"
212 214
#include "qgsmaptoolvertexedit.h"
213 215
#include "qgsmaptoolzoom.h"
214 216
#include "qgsmaptoolsimplify.h"
......
553 555
  delete mMapTools.mMeasureDist;
554 556
  delete mMapTools.mMeasureArea;
555 557
  delete mMapTools.mMeasureAngle;
558
  delete mMapTools.mScaleBarAnnotation;
556 559
  delete mMapTools.mTextAnnotation;
557 560
  delete mMapTools.mFormAnnotation;
558 561
  delete mMapTools.mAnnotation;
......
987 990
  mActionDraw->setStatusTip( tr( "Refresh Map" ) );
988 991
  connect( mActionDraw, SIGNAL( triggered() ), this, SLOT( refreshMapCanvas() ) );
989 992

  
993
  mActionScaleBarAnnotation = new QAction( getThemeIcon( "mActionScaleBarAnnotation.png" ), tr( "ScaleBar Annotation" ), this );
994
  mActionScaleBarAnnotation->setCheckable( true );
995
  connect( mActionScaleBarAnnotation, SIGNAL( triggered() ), this, SLOT( addScaleBarAnnotation() ) );
996

  
990 997
  mActionTextAnnotation = new QAction( getThemeIcon( "mActionTextAnnotation.png" ), tr( "Text Annotation" ), this );
991 998
  mActionTextAnnotation->setCheckable( true );
992 999
  connect( mActionTextAnnotation, SIGNAL( triggered() ), this, SLOT( addTextAnnotation() ) );
......
1747 1754
  annotationToolButton->setCheckable( true );
1748 1755
  annotationToolButton->addAction( mActionTextAnnotation );
1749 1756
  annotationToolButton->addAction( mActionFormAnnotation );
1757
  annotationToolButton->addAction( mActionScaleBarAnnotation );
1750 1758
  annotationToolButton->addAction( mActionAnnotation );
1751 1759
  annotationToolButton->setDefaultAction( mActionTextAnnotation );
1752 1760
  connect( annotationToolButton, SIGNAL( triggered( QAction* ) ),
......
2009 2017
  mActionAnnotation->setIcon( getThemeIcon( "/mActionAnnotation.png" ) );
2010 2018
  mActionFormAnnotation->setIcon( getThemeIcon( "/mActionFormAnnotation.png" ) );
2011 2019
  mActionTextAnnotation->setIcon( getThemeIcon( "/mActionTextAnnotation.png" ) );
2020
  mActionScaleBarAnnotation->setIcon( getThemeIcon( "/mActionTextAnnotation.png" ) );
2012 2021

  
2013 2022
  //change themes of all composers
2014 2023
  QSet<QgsComposer*>::iterator composerIt = mPrintComposers.begin();
......
2112 2121
  mMapTools.mMeasureArea->setAction( mActionMeasureArea );
2113 2122
  mMapTools.mMeasureAngle = new QgsMapToolMeasureAngle( mMapCanvas );
2114 2123
  mMapTools.mMeasureAngle->setAction( mActionMeasureAngle );
2124
  mMapTools.mScaleBarAnnotation = new QgsMapToolScaleBarAnnotation( mMapCanvas );
2125
  mMapTools.mScaleBarAnnotation->setAction( mActionScaleBarAnnotation );
2115 2126
  mMapTools.mTextAnnotation = new QgsMapToolTextAnnotation( mMapCanvas );
2116 2127
  mMapTools.mTextAnnotation->setAction( mActionTextAnnotation );
2117 2128
  mMapTools.mFormAnnotation = new QgsMapToolFormAnnotation( mMapCanvas );
......
3898 3909
  mMapCanvas->setMapTool( mMapTools.mTextAnnotation );
3899 3910
}
3900 3911

  
3912

  
3913
void QgisApp::addScaleBarAnnotation()
3914
{
3915
  mMapCanvas->setMapTool( mMapTools.mScaleBarAnnotation );
3916
}
3917

  
3901 3918
void QgisApp::modifyAnnotation()
3902 3919
{
3903 3920
  mMapCanvas->setMapTool( mMapTools.mAnnotation );
......
4262 4279
    QgsFormAnnotationItem* newFormItem = new QgsFormAnnotationItem( mMapCanvas );
4263 4280
    newFormItem->readXML( doc, formItemList.at( i ).toElement() );
4264 4281
  }
4282

  
4283
  QDomNodeList scaleBarItemList = doc.elementsByTagName( "ScaleBarAnnotationItem" );
4284
  for ( int i = 0; i < scaleBarItemList.size(); ++i )
4285
  {
4286
    QgsScaleBarAnnotationItem* newScaleBarItem = new QgsScaleBarAnnotationItem( mMapCanvas );
4287
    newScaleBarItem->readXML( doc, formItemList.at( i ).toElement() );
4288
  }
4265 4289
  return true;
4266 4290
}
4267 4291

  
src/gui/qgstextannotationitem.cpp (working copy)
1
/***************************************************************************
2
                              qgstextannotationitem.cpp
3
                              ------------------------
4
  begin                : February 9, 2010
5
  copyright            : (C) 2010 by Marco Hugentobler
6
  email                : marco dot hugentobler at hugis dot net
7
 ***************************************************************************/
8

  
9
/***************************************************************************
10
 *                                                                         *
11
 *   This program is free software; you can redistribute it and/or modify  *
12
 *   it under the terms of the GNU General Public License as published by  *
13
 *   the Free Software Foundation; either version 2 of the License, or     *
14
 *   (at your option) any later version.                                   *
15
 *                                                                         *
16
 ***************************************************************************/
17

  
18
#include "qgstextannotationitem.h"
19
#include <QDomDocument>
20
#include <QPainter>
21

  
22
QgsTextAnnotationItem::QgsTextAnnotationItem( QgsMapCanvas* canvas ): QgsAnnotationItem( canvas ), mDocument( new QTextDocument( QObject::tr( "QGIS rocks!" ) ) )
23
{
24
  mDocument->setUseDesignMetrics( true );
25
}
26

  
27
QgsTextAnnotationItem::~QgsTextAnnotationItem()
28
{
29
  delete mDocument;
30
}
31

  
32
QTextDocument* QgsTextAnnotationItem::document() const
33
{
34
  if ( !mDocument )
35
  {
36
    return 0;
37
  }
38

  
39
  return mDocument->clone();
40
}
41

  
42
void QgsTextAnnotationItem::setDocument( const QTextDocument* doc )
43
{
44
  delete mDocument;
45
  mDocument = doc->clone();
46
}
47

  
48
void QgsTextAnnotationItem::paint( QPainter * painter )
49
{
50
  if ( !painter || !mDocument )
51
  {
52
    return;
53
  }
54

  
55
  drawFrame( painter );
56
  if ( mMapPositionFixed )
57
  {
58
    drawMarkerSymbol( painter );
59
  }
60
  double frameWidth = mFrameBorderWidth;
61
  mDocument->setTextWidth( mFrameSize.width() );
62

  
63
  painter->save();
64
  painter->translate( mOffsetFromReferencePoint.x() + frameWidth / 2.0,
65
                      mOffsetFromReferencePoint.y() + frameWidth / 2.0 );
66

  
67
  //draw text document
68
  mDocument->drawContents( painter, QRectF( 0, 0, mFrameSize.width() - frameWidth / 2.0, mFrameSize.height() - frameWidth / 2.0 ) );
69
  painter->restore();
70
  if ( isSelected() )
71
  {
72
    drawSelectionBoxes( painter );
73
  }
74
}
75

  
76
void QgsTextAnnotationItem::writeXML( QDomDocument& doc ) const
77
{
78
  QDomElement documentElem = doc.documentElement();
79
  if ( documentElem.isNull() )
80
  {
81
    return;
82
  }
83
  QDomElement annotationElem = doc.createElement( "TextAnnotationItem" );
84
  if ( mDocument )
85
  {
86
    annotationElem.setAttribute( "document", mDocument->toHtml() );
87
  }
88
  _writeXML( doc, annotationElem );
89
  documentElem.appendChild( annotationElem );
90
}
91

  
92
void QgsTextAnnotationItem::readXML( const QDomDocument& doc, const QDomElement& itemElem )
93
{
94
  delete mDocument;
95
  mDocument = new QTextDocument;
96
  mDocument->setHtml( itemElem.attribute( "document", QObject::tr( "<html>QGIS rocks!</html>" ) ) );
97
  QDomElement annotationElem = itemElem.firstChildElement( "AnnotationItem" );
98
  if ( !annotationElem.isNull() )
99
  {
100
    _readXML( doc, annotationElem );
101
  }
102
}
src/gui/mapwidgets/qgstextannotationitem.h (working copy)
21 21
#include "qgsannotationitem.h"
22 22
#include <QTextDocument>
23 23

  
24
/**An annotation item that displays formated text*/
24
/** \ingroup gui
25
 * An annotation item that displays formated text*/
25 26
class GUI_EXPORT QgsTextAnnotationItem: public QgsAnnotationItem
26 27
{
27 28
  public:
src/gui/mapwidgets/qgsscalebarannotationitem.cpp (revision 0)
1
/***************************************************************************
2
                              qgsscalebarannotationitem.h
3
                              ------------------------
4
  begin                : Sept 15, 2010
5
  copyright            : (C) 2010 by Tim Sutton
6
  email                : [email protected]
7
 ***************************************************************************/
8

  
9
/***************************************************************************
10
 *                                                                         *
11
 *   This program is free software; you can redistribute it and/or modify  *
12
 *   it under the terms of the GNU General Public License as published by  *
13
 *   the Free Software Foundation; either version 2 of the License, or     *
14
 *   (at your option) any later version.                                   *
15
 *                                                                         *
16
 ***************************************************************************/
17

  
18
#include "qgsscalebarannotationitem.h"
19
#include "qgslogger.h"
20
#include "qgsmapcanvas.h"
21
#include <QDomElement>
22
#include <QDir>
23
#include <QFile>
24
#include <QFileInfo>
25
#include <QGraphicsProxyWidget>
26
#include <QPainter>
27
#include <QSettings>
28
#include <QUiLoader>
29
#include <QWidget>
30
#include "qgsmaplayer.h"
31
#include "qgsmaptopixel.h"
32
#include "qgspoint.h"
33
#include "qgsproject.h"
34

  
35
#include <QPainter>
36
#include <QAction>
37
#include <QPen>
38
#include <QPolygon>
39
#include <QString>
40
#include <QFontMetrics>
41
#include <QFont>
42
#include <QColor>
43
#include <QMenu>
44
#include <QFile>
45
#include <QLocale>
46

  
47
//non qt includes
48
#include <cmath>
49

  
50
//the gui subclass
51
#include "qgslogger.h"
52

  
53
QgsScaleBarAnnotationItem::QgsScaleBarAnnotationItem( QgsMapCanvas* canvas ): QgsAnnotationItem( canvas )
54
{
55
  if ( mMapCanvas ) 
56
  {
57
    QObject::connect( mMapCanvas, SIGNAL( renderComplete( QPainter* ) ), this, SLOT( setFeatureScaleBarapPosition() ) );
58
  }
59
  setMapPositionFixed( false );
60
}
61

  
62
QgsScaleBarAnnotationItem::~QgsScaleBarAnnotationItem()
63
{
64
}
65

  
66
void QgsScaleBarAnnotationItem::paint( QPainter * painter )
67
{
68
  renderScaleBar( painter );
69
}
70

  
71
void QgsScaleBarAnnotationItem::paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget )
72
{
73
  if ( !painter )
74
  {
75
    return;
76
  }
77

  
78
  if ( isSelected() )
79
  {
80
    drawSelectionBoxes( painter );
81
  }
82

  
83
  renderScaleBar( painter );
84
}
85

  
86
// Actual drawing of Scale Bar
87
void QgsScaleBarAnnotationItem::renderScaleBar( QPainter * theQPainter )
88
{
89
  // Get font metric info
90
  int myFontSize = 10; //we use this later for buffering
91
  QFont myFont( "helvetica", myFontSize );
92
  theQPainter->setFont( myFont );
93
  QFontMetrics myFontMetrics( myFont );
94
  double myFontHeight = myFontMetrics.height();
95
  double myFontWidth = myFontMetrics.width( tr("degrees" ) );
96
  int myBufferSize = 1; //softcode this later
97

  
98
  //remove the length of the longest possible map unit word (degrees)
99
  int myCanvasWidth = mBoundingRect.width() - myFontWidth;
100

  
101
  //Get map units per pixel. This can be negative at times (to do with
102
  //projections) and that just confuses the rest of the code in this
103
  //function, so force to a positive number.
104
  double myMapUnitsPerPixelDouble = std::abs( mMapCanvas->mapUnitsPerPixel() );
105

  
106
  // Exit if the canvas width is 0 or layercount is 0 or QGIS will freeze
107
  int myLayerCount = mMapCanvas->layerCount();
108
  if ( !myLayerCount || !myCanvasWidth || !myMapUnitsPerPixelDouble ) return;
109

  
110
  //Large if statement which determines whether to render the scale bar
111
  // Hard coded sizes
112
  int myMajorTickSize = 8;
113
  int myTextOffsetX = 3;
114
  int myMargin = 20;
115

  
116
  //Calculate size of scale bar for preferred number of map units
117
  double myScaleBarWidth = myCanvasWidth; // pixels
118
  double myActualSize = myScaleBarWidth * myMapUnitsPerPixelDouble; // map units
119

  
120
  // Work out the exponent for the number - e.g, 1234 will give 3,
121
  // and .001234 will give -3
122
  double myPowerOf10 = floor( log10( myActualSize ) );
123

  
124
  // snap to integer < 10 times power of 10
125
  bool mSnapping = true; //hard coded for now
126
  if ( mSnapping )
127
  {
128
    double scaler = pow( 10.0, myPowerOf10 );
129
    myActualSize = round( myActualSize / scaler ) * scaler;
130
    myScaleBarWidth = myActualSize / myMapUnitsPerPixelDouble;
131
  }
132
  //Get type of map units and set scale bar unit label text
133
  QGis::UnitType myMapUnits = mMapCanvas->mapUnits();
134
  QString myScaleBarUnitLabel;
135
  switch ( myMapUnits )
136
  {
137
    case QGis::Meters:
138
      if ( myActualSize > 1000.0 )
139
      {
140
        myScaleBarUnitLabel = tr( " km" );
141
        myActualSize = myActualSize / 1000;
142
      }
143
      else if ( myActualSize < 0.01 )
144
      {
145
        myScaleBarUnitLabel = tr( " mm" );
146
        myActualSize = myActualSize * 1000;
147
      }
148
      else if ( myActualSize < 0.1 )
149
      {
150
        myScaleBarUnitLabel = tr( " cm" );
151
        myActualSize = myActualSize * 100;
152
      }
153
      else
154
        myScaleBarUnitLabel = tr( " m" );
155
      break;
156
    case QGis::Feet:
157
      if ( myActualSize > 5280.0 ) //5280 feet to the mile
158
      {
159
        myScaleBarUnitLabel = tr( " miles" );
160
        // Adjust scale bar width to get even numbers
161
        myActualSize = myActualSize / 5000;
162
        myScaleBarWidth = ( myScaleBarWidth * 5280 ) / 5000;
163
      }
164
      else if ( myActualSize == 5280.0 ) //5280 feet to the mile
165
      {
166
        myScaleBarUnitLabel = tr( " mile" );
167
        // Adjust scale bar width to get even numbers
168
        myActualSize = myActualSize / 5000;
169
        myScaleBarWidth = ( myScaleBarWidth * 5280 ) / 5000;
170
      }
171
      else if ( myActualSize < 1 )
172
      {
173
        myScaleBarUnitLabel = tr( " inches" );
174
        myActualSize = myActualSize * 10;
175
        myScaleBarWidth = ( myScaleBarWidth * 10 ) / 12;
176
      }
177
      else if ( myActualSize == 1.0 )
178
      {
179
        myScaleBarUnitLabel = tr( " foot" );
180
      }
181
      else
182
      {
183
        myScaleBarUnitLabel = tr( " feet" );
184
      }
185
      break;
186
    case QGis::Degrees:
187
      if ( myActualSize == 1.0 )
188
        myScaleBarUnitLabel = tr( " degree" );
189
      else
190
        myScaleBarUnitLabel = tr( " degrees" );
191
      break;
192
    case QGis::UnknownUnit:
193
      myScaleBarUnitLabel = tr( " unknown" );
194
    default:
195
      QgsDebugMsg( QString( "Error: not picked up map units - actual value = %1" ).arg( myMapUnits ) );
196
  };
197

  
198
  //Set font and calculate width of unit label
199
  myFontWidth = myFontMetrics.width( myScaleBarUnitLabel );
200

  
201

  
202

  
203
  //Set the maximum label
204
  QString myScaleBarMaxLabel = QLocale::system().toString( myActualSize );
205

  
206
  //Calculate total width of scale bar and label
207
  double myTotalScaleBarWidth = myScaleBarWidth + myFontWidth;
208

  
209
  //determine the origin of scale bar 
210
  int myOriginX = 0;
211
  int myOriginY = mBoundingRect.height()/2;
212

  
213
  //Set pen to draw with
214
  QColor mColor(Qt::black); //hard coded for now
215
  QPen myForegroundPen( mColor, 2 );
216
  QPen myBackgroundPen( Qt::white, 4 );
217

  
218
  //Cast myScaleBarWidth to int for drawing
219
  int myScaleBarWidthInt = ( int ) myScaleBarWidth;
220

  
221
  //Create array of vertices for scale bar depending on style
222
  int mStyleIndex = 0; //hard coded for now
223
  switch ( mStyleIndex )
224
  {
225
    case 0: // Tick Down
226
    {
227
      QPolygon myTickDownArray( 4 );
228
      //draw a buffer first so bar shows up on dark images
229
      theQPainter->setPen( myBackgroundPen );
230
      myTickDownArray.putPoints( 0, 4,
231
                                 myOriginX                    , ( myOriginY + myMajorTickSize ) ,
232
                                 myOriginX                    ,  myOriginY                    ,
233
                                 ( myScaleBarWidthInt + myOriginX ),  myOriginY                    ,
234
                                 ( myScaleBarWidthInt + myOriginX ), ( myOriginY + myMajorTickSize )
235
                               );
236
      theQPainter->drawPolyline( myTickDownArray );
237
      //now draw the bar itself in user selected color
238
      theQPainter->setPen( myForegroundPen );
239
      myTickDownArray.putPoints( 0, 4,
240
                                 myOriginX                    , ( myOriginY + myMajorTickSize ) ,
241
                                 myOriginX                    ,  myOriginY                    ,
242
                                 ( myScaleBarWidthInt + myOriginX ),  myOriginY                    ,
243
                                 ( myScaleBarWidthInt + myOriginX ), ( myOriginY + myMajorTickSize )
244
                               );
245
      theQPainter->drawPolyline( myTickDownArray );
246
      break;
247
    }
248
    case 1: // tick up
249
    {
250
      QPolygon myTickUpArray( 4 );
251
      //draw a buffer first so bar shows up on dark images
252
      theQPainter->setPen( myBackgroundPen );
253
      myTickUpArray.putPoints( 0, 4,
254
                               myOriginX                    ,  myOriginY                    ,
255
                               myOriginX                    ,  myOriginY + myMajorTickSize  ,
256
                               ( myScaleBarWidthInt + myOriginX ),  myOriginY + myMajorTickSize  ,
257
                               ( myScaleBarWidthInt + myOriginX ),  myOriginY
258
                             );
259
      theQPainter->drawPolyline( myTickUpArray );
260
      //now draw the bar itself in user selected color
261
      theQPainter->setPen( myForegroundPen );
262
      myTickUpArray.putPoints( 0, 4,
263
                               myOriginX                    ,  myOriginY                    ,
264
                               myOriginX                    ,  myOriginY + myMajorTickSize  ,
265
                               ( myScaleBarWidthInt + myOriginX ),  myOriginY + myMajorTickSize  ,
266
                               ( myScaleBarWidthInt + myOriginX ),  myOriginY
267
                             );
268
      theQPainter->drawPolyline( myTickUpArray );
269
      break;
270
    }
271
    case 2: // Bar
272
    {
273
      QPolygon myBarArray( 2 );
274
      //draw a buffer first so bar shows up on dark images
275
      theQPainter->setPen( myBackgroundPen );
276
      myBarArray.putPoints( 0, 2,
277
                            myOriginX                    , ( myOriginY + ( myMajorTickSize / 2 ) ),
278
                            ( myScaleBarWidthInt + myOriginX ), ( myOriginY + ( myMajorTickSize / 2 ) )
279
                          );
280
      theQPainter->drawPolyline( myBarArray );
281
      //now draw the bar itself in user selected color
282
      theQPainter->setPen( myForegroundPen );
283
      myBarArray.putPoints( 0, 2,
284
                            myOriginX                    , ( myOriginY + ( myMajorTickSize / 2 ) ),
285
                            ( myScaleBarWidthInt + myOriginX ), ( myOriginY + ( myMajorTickSize / 2 ) )
286
                          );
287
      theQPainter->drawPolyline( myBarArray );
288
      break;
289
    }
290
    case 3: // box
291
    {
292
      // Want square corners for a box
293
      myBackgroundPen.setJoinStyle( Qt::MiterJoin );
294
      myForegroundPen.setJoinStyle( Qt::MiterJoin );
295
      QPolygon myBoxArray( 5 );
296
      //draw a buffer first so bar shows up on dark images
297
      theQPainter->setPen( myBackgroundPen );
298
      myBoxArray.putPoints( 0, 5,
299
                            myOriginX                    ,  myOriginY,
300
                            ( myScaleBarWidthInt + myOriginX ),  myOriginY,
301
                            ( myScaleBarWidthInt + myOriginX ), ( myOriginY + myMajorTickSize ),
302
                            myOriginX                    , ( myOriginY + myMajorTickSize ),
303
                            myOriginX                    ,  myOriginY
304
                          );
305
      theQPainter->drawPolyline( myBoxArray );
306
      //now draw the bar itself in user selected color
307
      theQPainter->setPen( myForegroundPen );
308
      theQPainter->setBrush( QBrush( mColor, Qt::SolidPattern ) );
309
      int midPointX = myScaleBarWidthInt / 2 + myOriginX;
310
      myBoxArray.putPoints( 0, 5,
311
                            myOriginX                    ,  myOriginY,
312
                            midPointX,  myOriginY,
313
                            midPointX, ( myOriginY + myMajorTickSize ),
314
                            myOriginX                    , ( myOriginY + myMajorTickSize ),
315
                            myOriginX                    ,  myOriginY
316
                          );
317
      theQPainter->drawPolygon( myBoxArray );
318

  
319
      theQPainter->setBrush( Qt::NoBrush );
320
      myBoxArray.putPoints( 0, 5,
321
                            midPointX                    ,  myOriginY,
322
                            ( myScaleBarWidthInt + myOriginX ),  myOriginY,
323
                            ( myScaleBarWidthInt + myOriginX ), ( myOriginY + myMajorTickSize ),
324
                            midPointX                    , ( myOriginY + myMajorTickSize ),
325
                            midPointX                    ,  myOriginY
326
                          );
327
      theQPainter->drawPolygon( myBoxArray );
328
      break;
329
    }
330
    default:
331
      QgsDebugMsg( "Unknown style" );
332
  }
333

  
334
  //
335
  //Do drawing of scale bar text
336
  //
337

  
338
  QColor myBackColor = Qt::white;
339
  QColor myForeColor = Qt::black;
340

  
341
  //Draw the minimum label buffer
342
  theQPainter->setPen( myBackColor );
343
  myFontWidth = myFontMetrics.width( "0" );
344
  myFontHeight = myFontMetrics.height();
345

  
346
  for ( int i = 0 - myBufferSize; i <= myBufferSize; i++ )
347
  {
348
    for ( int j = 0 - myBufferSize; j <= myBufferSize; j++ )
349
    {
350
      theQPainter->drawText( int( i + ( myOriginX - ( myFontWidth / 2 ) ) ),
351
                             int( j + ( myOriginY - ( myFontHeight / 4 ) ) ),
352
                             "0" );
353
    }
354
  }
355

  
356
  //Draw minimum label
357
  theQPainter->setPen( myForeColor );
358

  
359
  theQPainter->drawText(
360
    int( myOriginX - ( myFontWidth / 2 ) ),
361
    int( myOriginY - ( myFontHeight / 4 ) ),
362
    "0"
363
  );
364

  
365
  //
366
  //Draw maximum label
367
  //
368
  theQPainter->setPen( myBackColor );
369
  myFontWidth = myFontMetrics.width( myScaleBarMaxLabel );
370
  myFontHeight = myFontMetrics.height();
371
  //first the buffer
372
  for ( int i = 0 - myBufferSize; i <= myBufferSize; i++ )
373
  {
374
    for ( int j = 0 - myBufferSize; j <= myBufferSize; j++ )
375
    {
376
      theQPainter->drawText( int( i + ( myOriginX + myScaleBarWidthInt - ( myFontWidth / 2 ) ) ),
377
                             int( j + ( myOriginY - ( myFontHeight / 4 ) ) ),
378
                             myScaleBarMaxLabel );
379
    }
380
  }
381
  //then the text itself
382
  theQPainter->setPen( myForeColor );
383
  theQPainter->drawText(
384
    int( myOriginX + myScaleBarWidthInt - ( myFontWidth / 2 ) ),
385
    int( myOriginY - ( myFontHeight / 4 ) ),
386
    myScaleBarMaxLabel
387
  );
388

  
389
  //
390
  //Draw unit label
391
  //
392
  theQPainter->setPen( myBackColor );
393
  myFontWidth = myFontMetrics.width( myScaleBarUnitLabel );
394
  myFontHeight = myFontMetrics.height();
395
  //first the buffer
396
  for ( int i = 0 - myBufferSize; i <= myBufferSize; i++ )
397
  {
398
    for ( int j = 0 - myBufferSize; j <= myBufferSize; j++ )
399
    {
400
      theQPainter->drawText( i + ( myOriginX + myScaleBarWidthInt + myTextOffsetX ),
401
                             j + ( myOriginY + myMajorTickSize ),
402
                             myScaleBarUnitLabel );
403
    }
404
  }
405
  //then the text itself
406
  theQPainter->setPen( myForeColor );
407
  theQPainter->drawText(
408
    ( myOriginX + myScaleBarWidthInt + myTextOffsetX ), ( myOriginY + myMajorTickSize ),
409
    myScaleBarUnitLabel
410
  );
411
}
412

  
413
void QgsScaleBarAnnotationItem::writeXML( QDomDocument& doc ) const
414
{
415
  QDomElement documentElem = doc.documentElement();
416
  if ( documentElem.isNull() )
417
  {
418
    return;
419
  }
420

  
421
  QDomElement scaleBarAnnotationElem = doc.createElement( "ScaleBarAnnotationItem" );
422
  scaleBarAnnotationElem.setAttribute( "scalebar", "foo");
423
  _writeXML( doc, scaleBarAnnotationElem );
424
  documentElem.appendChild( scaleBarAnnotationElem );
425
}
426

  
427
void QgsScaleBarAnnotationItem::readXML( const QDomDocument& doc, const QDomElement& itemElem )
428
{
429
  QObject::connect( mMapCanvas, SIGNAL( renderComplete( QPainter* ) ), this, SLOT( setFeatureScaleBarapPosition() ) );
430
  QDomElement annotationElem = itemElem.firstChildElement( "AnnotationItem" );
431
  if ( !annotationElem.isNull() )
432
  {
433
    _readXML( doc, annotationElem );
434
  }
435
}
src/gui/mapwidgets/qgsscalebarannotationitem.h (revision 0)
1
/***************************************************************************
2
                              qgsscalebarannotationitem.h
3
                              ------------------------
4
  begin                : September 15 2010
5
  copyright            : (C) 2010 by Tim Sutton
6
  email                : [email protected].com
7
 ***************************************************************************/
8

  
9
/***************************************************************************
10
 *                                                                         *
11
 *   This program is free software; you can redistribute it and/or modify  *
12
 *   it under the terms of the GNU General Public License as published by  *
13
 *   the Free Software Foundation; either version 2 of the License, or     *
14
 *   (at your option) any later version.                                   *
15
 *                                                                         *
16
 ***************************************************************************/
17

  
18
#ifndef QGSSCALEBARANNOTATIONITEM_H
19
#define QGSSCALEBARANNOTATIONITEM_H
20

  
21
#include "qgsannotationitem.h"
22
#include <QObject>
23

  
24
class QGraphicsProxyWidget;
25

  
26
/** \ingroup gui
27
 * An annotation item that embeds a ScaleBar */
28
class GUI_EXPORT QgsScaleBarAnnotationItem: public QObject, public QgsAnnotationItem
29
{
30
    Q_OBJECT
31
  public:
32
    QgsScaleBarAnnotationItem( QgsMapCanvas* canvas );
33
    ~QgsScaleBarAnnotationItem();
34

  
35
    void paint( QPainter * painter );
36

  
37
    //! paint function called by map canvas
38
    void paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0 );
39

  
40
    void writeXML( QDomDocument& doc ) const;
41
    void readXML( const QDomDocument& doc, const QDomElement& itemElem );
42

  
43

  
44
  private slots:
45

  
46
  private:
47
    void renderScaleBar( QPainter * theQPainter );
48
};
49

  
50
#endif // QGSSCALEBARANNOTATIONITEM_H
src/gui/mapwidgets/qgsannotationitem.h (working copy)
26 26
class QgsVectorLayer;
27 27
class QgsMarkerSymbolV2;
28 28

  
29
/**An annotation item can be either placed either on screen corrdinates or on map coordinates.
29
/** \ingroup gui
30
 * An annotation item can be either placed either on screen corrdinates or on map coordinates.
30 31
  It may reference a feature and displays that associatiation with a balloon like appearance*/
31 32
class GUI_EXPORT QgsAnnotationItem: public QgsMapCanvasItem
32 33
{
src/gui/qgsformannotationitem.cpp (working copy)
1
/***************************************************************************
2
                              qgsformannotationitem.h
3
                              ------------------------
4
  begin                : February 26, 2010
5
  copyright            : (C) 2010 by Marco Hugentobler
6
  email                : marco dot hugentobler at hugis dot net
7
 ***************************************************************************/
8

  
9
/***************************************************************************
10
 *                                                                         *
11
 *   This program is free software; you can redistribute it and/or modify  *
12
 *   it under the terms of the GNU General Public License as published by  *
13
 *   the Free Software Foundation; either version 2 of the License, or     *
14
 *   (at your option) any later version.                                   *
15
 *                                                                         *
16
 ***************************************************************************/
17

  
18
#include "qgsformannotationitem.h"
19
#include "qgsattributeeditor.h"
20
#include "qgsfeature.h"
21
#include "qgslogger.h"
22
#include "qgsmapcanvas.h"
23
#include "qgsmaplayerregistry.h"
24
#include "qgsvectorlayer.h"
25
#include <QDomElement>
26
#include <QDir>
27
#include <QFile>
28
#include <QFileInfo>
29
#include <QGraphicsProxyWidget>
30
#include <QPainter>
31
#include <QSettings>
32
#include <QUiLoader>
33
#include <QWidget>
34

  
35
QgsFormAnnotationItem::QgsFormAnnotationItem( QgsMapCanvas* canvas, QgsVectorLayer* vlayer, bool hasFeature, int feature ): \
36
    QgsAnnotationItem( canvas ), mWidgetContainer( 0 ), mDesignerWidget( 0 ), mVectorLayer( vlayer ), \
37
    mHasAssociatedFeature( hasFeature ), mFeature( feature )
38
{
39
  mWidgetContainer = new QGraphicsProxyWidget( this );
40
  if ( mVectorLayer && mMapCanvas ) //default to the layers edit form
41
  {
42
    mDesignerForm = mVectorLayer->annotationForm();
43
    QObject::connect( mVectorLayer, SIGNAL( layerModified( bool ) ), this, SLOT( setFeatureForMapPosition() ) );
44
    QObject::connect( mMapCanvas, SIGNAL( renderComplete( QPainter* ) ), this, SLOT( setFeatureForMapPosition() ) );
45
    QObject::connect( mMapCanvas, SIGNAL( layersChanged() ), this, SLOT( updateVisibility() ) );
46
  }
47

  
48
  setFeatureForMapPosition();
49
}
50

  
51
QgsFormAnnotationItem::~QgsFormAnnotationItem()
52
{
53
  delete mDesignerWidget;
54
}
55

  
56
void QgsFormAnnotationItem::setDesignerForm( const QString& uiFile )
57
{
58
  mDesignerForm = uiFile;
59
  mWidgetContainer->setWidget( 0 );
60
  delete mDesignerWidget;
61
  mDesignerWidget = createDesignerWidget( uiFile );
62
  if ( mDesignerWidget )
63
  {
64
    mFrameBackgroundColor = mDesignerWidget->palette().color( QPalette::Window );
65
    mWidgetContainer->setWidget( mDesignerWidget );
66
    setFrameSize( preferredFrameSize() );
67
  }
68
}
69

  
70
QWidget* QgsFormAnnotationItem::createDesignerWidget( const QString& filePath )
71
{
72
  QFile file( filePath );
73
  if ( !file.open( QFile::ReadOnly ) )
74
  {
75
    return 0;
76
  }
77

  
78
  QUiLoader loader;
79
  QFileInfo fi( file );
80
  loader.setWorkingDirectory( fi.dir() );
81
  QWidget* widget = loader.load( &file, 0 );
82
  file.close();
83

  
84
  //get feature and set attribute information
85
  if ( mVectorLayer && mHasAssociatedFeature )
86
  {
87
    QgsFeature f;
88
    if ( mVectorLayer->featureAtId( mFeature, f, false, true ) )
89
    {
90
      const QgsFieldMap& fieldMap = mVectorLayer->pendingFields();
91
      QgsAttributeMap attMap = f.attributeMap();
92
      QgsAttributeMap::const_iterator attIt = attMap.constBegin();
93
      for ( ; attIt != attMap.constEnd(); ++attIt )
94
      {
95
        QgsFieldMap::const_iterator fieldIt = fieldMap.find( attIt.key() );
96
        if ( fieldIt != fieldMap.constEnd() )
97
        {
98
          QWidget* attWidget = widget->findChild<QWidget*>( fieldIt->name() );
99
          if ( attWidget )
100
          {
101
            QgsAttributeEditor::createAttributeEditor( widget, attWidget, mVectorLayer, attIt.key(), attIt.value() );
102
          }
103
        }
104
      }
105
    }
106
  }
107
  return widget;
108
}
109

  
110
void QgsFormAnnotationItem::setMapPosition( const QgsPoint& pos )
111
{
112
  QgsAnnotationItem::setMapPosition( pos );
113
  setFeatureForMapPosition();
114
}
115

  
116
void QgsFormAnnotationItem::paint( QPainter * painter )
117
{
118

  
119
}
120

  
121
void QgsFormAnnotationItem::paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget )
122
{
123
  if ( !painter || !mWidgetContainer )
124
  {
125
    return;
126
  }
127

  
128
  drawFrame( painter );
129
  if ( mMapPositionFixed )
130
  {
131
    drawMarkerSymbol( painter );
132
  }
133

  
134
  mWidgetContainer->setGeometry( QRectF( mOffsetFromReferencePoint.x() + mFrameBorderWidth / 2.0, mOffsetFromReferencePoint.y() \
135
                                         + mFrameBorderWidth / 2.0, mFrameSize.width() - mFrameBorderWidth, mFrameSize.height() \
136
                                         - mFrameBorderWidth ) );
137

  
138
  if ( isSelected() )
139
  {
140
    drawSelectionBoxes( painter );
141
  }
142
}
143

  
144
QSizeF QgsFormAnnotationItem::minimumFrameSize() const
145
{
146
  if ( mDesignerWidget )
147
  {
148
    QSizeF widgetMinSize = mDesignerWidget->minimumSize();
149
    return QSizeF( 2 * mFrameBorderWidth + widgetMinSize.width(), 2 * mFrameBorderWidth + widgetMinSize.height() );
150
  }
151
  else
152
  {
153
    return QSizeF( 0, 0 );
154
  }
155
}
156

  
157
QSizeF QgsFormAnnotationItem::preferredFrameSize() const
158
{
159
  if ( mDesignerWidget )
160
  {
161
    return mDesignerWidget->sizeHint();
162
  }
163
  else
164
  {
165
    return QSizeF( 0, 0 );
166
  }
167
}
168

  
169
void QgsFormAnnotationItem::writeXML( QDomDocument& doc ) const
170
{
171
  QDomElement documentElem = doc.documentElement();
172
  if ( documentElem.isNull() )
173
  {
174
    return;
175
  }
176

  
177
  QDomElement formAnnotationElem = doc.createElement( "FormAnnotationItem" );
178
  if ( mVectorLayer )
179
  {
180
    formAnnotationElem.setAttribute( "vectorLayer", mVectorLayer->getLayerID() );
181
  }
182
  formAnnotationElem.setAttribute( "hasFeature", mHasAssociatedFeature );
183
  formAnnotationElem.setAttribute( "feature", mFeature );
184
  formAnnotationElem.setAttribute( "designerForm", mDesignerForm );
185
  _writeXML( doc, formAnnotationElem );
186
  documentElem.appendChild( formAnnotationElem );
187
}
188

  
189
void QgsFormAnnotationItem::readXML( const QDomDocument& doc, const QDomElement& itemElem )
190
{
191
  mVectorLayer = 0;
192
  if ( itemElem.hasAttribute( "vectorLayer" ) )
193
  {
194
    mVectorLayer = dynamic_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( itemElem.attribute( "vectorLayer", "" ) ) );
195
    if ( mVectorLayer )
196
    {
197
      QObject::connect( mVectorLayer, SIGNAL( layerModified( bool ) ), this, SLOT( setFeatureForMapPosition() ) );
198
      QObject::connect( mMapCanvas, SIGNAL( renderComplete( QPainter* ) ), this, SLOT( setFeatureForMapPosition() ) );
199
      QObject::connect( mMapCanvas, SIGNAL( layersChanged() ), this, SLOT( updateVisibility() ) );
200
    }
201
  }
202
  mHasAssociatedFeature = itemElem.attribute( "hasFeature", "0" ).toInt();
203
  mFeature = itemElem.attribute( "feature", "0" ).toInt();
204
  mDesignerForm = itemElem.attribute( "designerForm", "" );
205
  QDomElement annotationElem = itemElem.firstChildElement( "AnnotationItem" );
206
  if ( !annotationElem.isNull() )
207
  {
208
    _readXML( doc, annotationElem );
209
  }
210

  
211
  mDesignerWidget = createDesignerWidget( mDesignerForm );
212
  if ( mDesignerWidget )
213
  {
214
    mFrameBackgroundColor = mDesignerWidget->palette().color( QPalette::Window );
215
    mWidgetContainer->setWidget( mDesignerWidget );
216
  }
217
  updateVisibility();
218
}
219

  
220
void QgsFormAnnotationItem::setFeatureForMapPosition()
221
{
222
  if ( !mVectorLayer || !mMapCanvas )
223
  {
224
    return;
225
  }
226

  
227
  QgsAttributeList noAttributes;
228
  QSettings settings;
229
  double identifyValue = settings.value( "/Map/identifyRadius", QGis::DEFAULT_IDENTIFY_RADIUS ).toDouble();
230
  double halfIdentifyWidth = mMapCanvas->extent().width() / 100 / 2 * identifyValue;
231
  QgsRectangle searchRect( mMapPosition.x() - halfIdentifyWidth, mMapPosition.y() - halfIdentifyWidth, \
232
                           mMapPosition.x() + halfIdentifyWidth, mMapPosition.y() + halfIdentifyWidth );
233
  mVectorLayer->select( noAttributes, searchRect, false, true );
234

  
235
  QgsFeature currentFeature;
236
  int currentFeatureId = 0;
237
  bool featureFound = false;
238

  
239
  while ( mVectorLayer->nextFeature( currentFeature ) )
240
  {
241
    currentFeatureId = currentFeature.id();
242
    featureFound = true;
243
    break;
244
  }
245

  
246
  mHasAssociatedFeature = featureFound;
247
  mFeature = currentFeatureId;
248

  
249
  //create new embedded widget
250
  mWidgetContainer->setWidget( 0 );
251
  delete mDesignerWidget;
252
  mDesignerWidget = createDesignerWidget( mDesignerForm );
253
  if ( mDesignerWidget )
254
  {
255
    mFrameBackgroundColor = mDesignerWidget->palette().color( QPalette::Window );
256
    mWidgetContainer->setWidget( mDesignerWidget );
257
  }
258
}
259

  
260
void QgsFormAnnotationItem::updateVisibility()
261
{
262
  bool visible = true;
263
  if ( mVectorLayer && mMapCanvas )
264
  {
265
    visible = mMapCanvas->layers().contains( mVectorLayer );
266
  }
267
  setVisible( visible );
268
}
269

  
270

  
271

  
src/gui/qgsannotationitem.cpp (working copy)
1
/***************************************************************************
2
                              qgsannotationitem.cpp
3
                              ----------------------
4
  begin                : February 9, 2010
5
  copyright            : (C) 2010 by Marco Hugentobler
6
  email                : marco dot hugentobler at hugis dot net
7
 ***************************************************************************/
8

  
9
/***************************************************************************
10
 *                                                                         *
11
 *   This program is free software; you can redistribute it and/or modify  *
12
 *   it under the terms of the GNU General Public License as published by  *
13
 *   the Free Software Foundation; either version 2 of the License, or     *
14
 *   (at your option) any later version.                                   *
15
 *                                                                         *
16
 ***************************************************************************/
17

  
18
#include "qgsannotationitem.h"
19
#include "qgsmapcanvas.h"
20
#include "qgsrendercontext.h"
21
#include "qgssymbollayerv2utils.h"
22
#include "qgssymbolv2.h"
23
#include <QPainter>
24
#include <QPen>
25

  
26
QgsAnnotationItem::QgsAnnotationItem( QgsMapCanvas* mapCanvas ): QgsMapCanvasItem( mapCanvas ), mMapPositionFixed( true ), mOffsetFromReferencePoint( QPointF( 50, -50 ) )
27
{
28
  setFlag( QGraphicsItem::ItemIsSelectable, true );
29
  mMarkerSymbol = new QgsMarkerSymbolV2();
30
  mFrameBorderWidth = 1.0;
31
  mFrameColor = QColor( 0, 0, 0 );
32
  mFrameBackgroundColor = QColor( 255, 255, 255 );
33
}
34

  
35
QgsAnnotationItem::~QgsAnnotationItem()
36
{
37
  delete mMarkerSymbol;
38
}
39

  
40
void QgsAnnotationItem::setMarkerSymbol( QgsMarkerSymbolV2* symbol )
41
{
42
  delete mMarkerSymbol;
43
  mMarkerSymbol = symbol;
44
  updateBoundingRect();
45
}
46

  
47
void QgsAnnotationItem::setMapPosition( const QgsPoint& pos )
48
{
49
  mMapPosition = pos;
50
  setPos( toCanvasCoordinates( mMapPosition ) );
51
}
52

  
53
void QgsAnnotationItem::setOffsetFromReferencePoint( const QPointF& offset )
54
{
55
  mOffsetFromReferencePoint = offset;
56
  updateBoundingRect();
57
  updateBalloon();
58
}
59

  
60
void QgsAnnotationItem::setMapPositionFixed( bool fixed )
61
{
62
  if ( mMapPositionFixed && !fixed )
63
  {
64
    //set map position to the top left corner of the balloon
65
    setMapPosition( toMapCoordinates( QPointF( pos() + mOffsetFromReferencePoint ).toPoint() ) );
66
    mOffsetFromReferencePoint = QPointF( 0, 0 );
67
  }
68
  else if ( fixed && !mMapPositionFixed )
69
  {
70
    setMapPosition( toMapCoordinates( QPointF( pos() + QPointF( -100, -100 ) ).toPoint() ) );
71
    mOffsetFromReferencePoint = QPointF( 100, 100 );
72
  }
73
  mMapPositionFixed = fixed;
74
  updateBoundingRect();
75
  updateBalloon();
76
  update();
77
}
78

  
79
void QgsAnnotationItem::updatePosition()
80
{
81
  if ( mMapPositionFixed )
82
  {
83
    setPos( toCanvasCoordinates( mMapPosition ) );
84
  }
85
  else
86
  {
87
    mMapPosition = toMapCoordinates( pos().toPoint() );
88
  }
89
}
90

  
91
QRectF QgsAnnotationItem::boundingRect() const
92
{
93
  return mBoundingRect;
94
}
95

  
96
QSizeF QgsAnnotationItem::minimumFrameSize() const
97
{
98
  return QSizeF( 0, 0 );
99
}
100

  
101
void QgsAnnotationItem::updateBoundingRect()
102
{
103
  prepareGeometryChange();
104
  double halfSymbolSize = 0.0;
105
  if ( mMarkerSymbol )
106
  {
107
    halfSymbolSize = scaledSymbolSize() / 2.0;
108
  }
109

  
110
  double xMinPos = std::min( -halfSymbolSize, mOffsetFromReferencePoint.x() - mFrameBorderWidth );
111
  double xMaxPos = std::max( halfSymbolSize, mOffsetFromReferencePoint.x() + mFrameSize.width() + mFrameBorderWidth );
112
  double yMinPos = std::min( -halfSymbolSize, mOffsetFromReferencePoint.y() - mFrameBorderWidth );
113
  double yMaxPos = std::max( halfSymbolSize, mOffsetFromReferencePoint.y() + mFrameSize.height() + mFrameBorderWidth );
114
  mBoundingRect = QRectF( xMinPos, yMinPos, xMaxPos - xMinPos, yMaxPos - yMinPos );
115
}
116

  
117
void QgsAnnotationItem::updateBalloon()
118
{
119
  //first test if the point is in the frame. In that case we don't need a balloon.
120
  if ( !mMapPositionFixed ||
121
       ( mOffsetFromReferencePoint.x() < 0 && ( mOffsetFromReferencePoint.x() + mFrameSize.width() ) > 0 \
122
         && mOffsetFromReferencePoint.y() < 0 && ( mOffsetFromReferencePoint.y() + mFrameSize.height() ) > 0 ) )
123
  {
124
    mBalloonSegment = -1;
125
    return;
126
  }
127

  
128
  //edge list
129
  QList<QLineF> segmentList;
130
  segmentList << segment( 0 ); segmentList << segment( 1 ); segmentList << segment( 2 ); segmentList << segment( 3 );
131

  
132
  //find  closest edge / closest edge point
133
  double minEdgeDist = DBL_MAX;
134
  int minEdgeIndex = -1;
135
  QLineF minEdge;
136
  QgsPoint minEdgePoint;
137
  QgsPoint origin( 0, 0 );
138

  
139
  for ( int i = 0; i < 4; ++i )
140
  {
141
    QLineF currentSegment = segmentList.at( i );
142
    QgsPoint currentMinDistPoint;
143
    double currentMinDist = origin.sqrDistToSegment( currentSegment.x1(), currentSegment.y1(), currentSegment.x2(), currentSegment.y2(), currentMinDistPoint );
144
    if ( currentMinDist < minEdgeDist )
145
    {
146
      minEdgeIndex = i;
147
      minEdgePoint = currentMinDistPoint;
148
      minEdgeDist = currentMinDist;
149
      minEdge = currentSegment;
150
    }
151
  }
152

  
153
  if ( minEdgeIndex < 0 )
154
  {
155
    return;
156
  }
157

  
158
  //make that configurable for the item
159
  double segmentPointWidth = 10;
160

  
161
  mBalloonSegment = minEdgeIndex;
162
  QPointF minEdgeEnd = minEdge.p2();
163
  mBalloonSegmentPoint1 = QPointF( minEdgePoint.x(), minEdgePoint.y() );
164
  if ( sqrt( minEdgePoint.sqrDist( minEdgeEnd.x(), minEdgeEnd.y() ) ) < segmentPointWidth )
165
  {
166
    mBalloonSegmentPoint1 = pointOnLineWithDistance( minEdge.p2(), minEdge.p1(), segmentPointWidth );
167
  }
168

  
169
  mBalloonSegmentPoint2 = pointOnLineWithDistance( mBalloonSegmentPoint1, minEdge.p2(), 10 );
170
}
171

  
172
void QgsAnnotationItem::drawFrame( QPainter* p )
173
{
174
  QPen framePen( mFrameColor );
175
  framePen.setWidthF( mFrameBorderWidth );
176

  
177
  p->setPen( framePen );
178
  QBrush frameBrush( mFrameBackgroundColor );
179
  p->setBrush( frameBrush );
180
  p->setRenderHint( QPainter::Antialiasing, true );
181

  
182
  QPolygonF poly;
183
  for ( int i = 0; i < 4; ++i )
184
  {
185
    QLineF currentSegment = segment( i );
186
    poly << currentSegment.p1();
187
    if ( i == mBalloonSegment && mMapPositionFixed )
188
    {
189
      poly << mBalloonSegmentPoint1;
190
      poly << QPointF( 0, 0 );
191
      poly << mBalloonSegmentPoint2;
192
    }
193
    poly << currentSegment.p2();
194
  }
195
  p->drawPolygon( poly );
196
}
197

  
198
void QgsAnnotationItem::setFrameSize( const QSizeF& size )
199
{
200
  QSizeF frameSize = minimumFrameSize().expandedTo( size ); //don't allow frame sizes below minimum
201
  mFrameSize = frameSize;
202
  updateBoundingRect();
203
  updateBalloon();
204
}
205

  
206
void QgsAnnotationItem::drawMarkerSymbol( QPainter* p )
207
{
208
  if ( !p )
209
  {
210
    return;
211
  }
212

  
213
  QgsRenderContext renderContext;
214
  if ( !setRenderContextVariables( p, renderContext ) )
215
  {
216
    return;
217
  }
218

  
219
  QPointF canvasPoint = toCanvasCoordinates( mMapPosition );
220
  if ( mMarkerSymbol )
221
  {
222
    mMarkerSymbol->startRender( renderContext );
223
    mMarkerSymbol->renderPoint( QPointF( 0, 0 ), renderContext );
224
    mMarkerSymbol->stopRender( renderContext );
225
  }
226
}
227

  
228
void QgsAnnotationItem::drawSelectionBoxes( QPainter* p )
229
{
230
  if ( !p )
231
  {
232
    return;
233
  }
234

  
235
  //no selection boxes for composer mode
236
  if ( data( 0 ).toString() == "composer" )
237
  {
238
    return;
239
  }
240

  
241
  double handlerSize = 10;
242
  p->setPen( Qt::NoPen );
243
  p->setBrush( QColor( 200, 200, 210, 120 ) );
244
  p->drawRect( QRectF( mBoundingRect.left(), mBoundingRect.top(), handlerSize, handlerSize ) );
245
  p->drawRect( QRectF( mBoundingRect.right() - handlerSize, mBoundingRect.top(), handlerSize, handlerSize ) );
246
  p->drawRect( QRectF( mBoundingRect.right() - handlerSize, mBoundingRect.bottom() - handlerSize, handlerSize, handlerSize ) );
247
  p->drawRect( QRectF( mBoundingRect.left(), mBoundingRect.bottom() - handlerSize, handlerSize, handlerSize ) );
248
}
249

  
250
QLineF QgsAnnotationItem::segment( int index )
251
{
252
  switch ( index )
253
  {
254
    case 0:
255
      return QLineF( mOffsetFromReferencePoint.x(), mOffsetFromReferencePoint.y(), mOffsetFromReferencePoint.x() \
256
                     + mFrameSize.width(), mOffsetFromReferencePoint.y() );
257
    case 1:
258
      return QLineF( mOffsetFromReferencePoint.x() + mFrameSize.width(), mOffsetFromReferencePoint.y(), \
259
                     mOffsetFromReferencePoint.x() + mFrameSize.width(), mOffsetFromReferencePoint.y() + mFrameSize.height() );
260
    case 2:
261
      return QLineF( mOffsetFromReferencePoint.x() + mFrameSize.width(), mOffsetFromReferencePoint.y() + mFrameSize.height(), \
262
                     mOffsetFromReferencePoint.x(), mOffsetFromReferencePoint.y() + mFrameSize.height() );
263
    case 3:
264
      return QLineF( mOffsetFromReferencePoint.x(), mOffsetFromReferencePoint.y() + mFrameSize.height(), \
265
                     mOffsetFromReferencePoint.x(), mOffsetFromReferencePoint.y() );
266
    default:
267
      return QLineF();
268
  }
269
}
270

  
271
QPointF QgsAnnotationItem::pointOnLineWithDistance( const QPointF& startPoint, const QPointF& directionPoint, double distance ) const
272
{
273
  double dx = directionPoint.x() - startPoint.x();
274
  double dy = directionPoint.y() - startPoint.y();
275
  double length = sqrt( dx * dx + dy * dy );
276
  double scaleFactor = distance / length;
277
  return QPointF( startPoint.x() + dx * scaleFactor, startPoint.y() + dy * scaleFactor );
278
}
279

  
280
QgsAnnotationItem::MouseMoveAction QgsAnnotationItem::moveActionForPosition( const QPointF& pos ) const
281
{
282
  QPointF itemPos = mapFromScene( pos );
283

  
284
  int cursorSensitivity = 7;
285

  
286
  if ( abs( itemPos.x() ) < cursorSensitivity && abs( itemPos.y() ) < cursorSensitivity ) //move map point if position is close to the origin
287
  {
288
    return MoveMapPosition;
289
  }
290

  
291
  bool left, right, up, down;
292
  left = abs( itemPos.x() - mOffsetFromReferencePoint.x() ) < cursorSensitivity;
293
  right = abs( itemPos.x() - ( mOffsetFromReferencePoint.x() + mFrameSize.width() ) ) < cursorSensitivity;
294
  up = abs( itemPos.y() - mOffsetFromReferencePoint.y() ) < cursorSensitivity;
295
  down = abs( itemPos.y() - ( mOffsetFromReferencePoint.y() + mFrameSize.height() ) ) < cursorSensitivity;
296

  
297
  if ( left && up )
298
  {
299
    return ResizeFrameLeftUp;
300
  }
301
  else if ( right && up )
302
  {
303
    return ResizeFrameRightUp;
304
  }
305
  else if ( left && down )
306
  {
307
    return ResizeFrameLeftDown;
308
  }
309
  else if ( right && down )
310
  {
311
    return ResizeFrameRightDown;
312
  }
313
  if ( left )
314
  {
315
    return ResizeFrameLeft;
316
  }
317
  if ( right )
318
  {
319
    return ResizeFrameRight;
320
  }
321
  if ( up )
322
  {
323
    return ResizeFrameUp;
324
  }
325
  if ( down )
326
  {
327
    return ResizeFrameDown;
... This diff was truncated because it exceeds the maximum size that can be displayed.