QGIS API Documentation  2.0.1-Dufour
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
qgsformannotationitem.cpp
Go to the documentation of this file.
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  mWidgetContainer->setData( 0, "AnnotationItem" ); //mark embedded widget as belonging to an annotation item (composer knows it needs to be printed)
41  if ( mVectorLayer && mMapCanvas ) //default to the layers edit form
42  {
44  QObject::connect( mVectorLayer, SIGNAL( layerModified() ), this, SLOT( setFeatureForMapPosition() ) );
45  QObject::connect( mMapCanvas, SIGNAL( renderComplete( QPainter* ) ), this, SLOT( setFeatureForMapPosition() ) );
46  QObject::connect( mMapCanvas, SIGNAL( layersChanged() ), this, SLOT( updateVisibility() ) );
47  }
48 
50 }
51 
53 {
54  delete mDesignerWidget;
55 }
56 
57 void QgsFormAnnotationItem::setDesignerForm( const QString& uiFile )
58 {
59  mDesignerForm = uiFile;
60  mWidgetContainer->setWidget( 0 );
61  delete mDesignerWidget;
63  if ( mDesignerWidget )
64  {
65  mFrameBackgroundColor = mDesignerWidget->palette().color( QPalette::Window );
66  mWidgetContainer->setWidget( mDesignerWidget );
68  }
69 }
70 
71 QWidget* QgsFormAnnotationItem::createDesignerWidget( const QString& filePath )
72 {
73  QFile file( filePath );
74  if ( !file.open( QFile::ReadOnly ) )
75  {
76  return 0;
77  }
78 
79  QUiLoader loader;
80  QFileInfo fi( file );
81  loader.setWorkingDirectory( fi.dir() );
82  QWidget* widget = loader.load( &file, 0 );
83  file.close();
84 
85  //get feature and set attribute information
87  {
88  QgsFeature f;
90  {
91  const QgsFields& fields = mVectorLayer->pendingFields();
92  const QgsAttributes& attrs = f.attributes();
93  for ( int i = 0; i < attrs.count(); ++i )
94  {
95  if ( i < fields.count() )
96  {
97  QWidget* attWidget = widget->findChild<QWidget*>( fields[i].name() );
98  if ( attWidget )
99  {
100  QgsAttributeEditor::createAttributeEditor( widget, attWidget, mVectorLayer, i, attrs[i] );
101  }
102  }
103  }
104  }
105  }
106  return widget;
107 }
108 
110 {
113 }
114 
115 void QgsFormAnnotationItem::paint( QPainter * painter )
116 {
117  Q_UNUSED( painter );
118 }
119 
120 void QgsFormAnnotationItem::paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget )
121 {
122  Q_UNUSED( option );
123  Q_UNUSED( widget );
124  if ( !painter || !mWidgetContainer )
125  {
126  return;
127  }
128 
129  drawFrame( painter );
130  if ( mMapPositionFixed )
131  {
132  drawMarkerSymbol( painter );
133  }
134 
136  + mFrameBorderWidth / 2.0, mFrameSize.width() - mFrameBorderWidth, mFrameSize.height()
137  - mFrameBorderWidth ) );
138 
139  if ( isSelected() )
140  {
141  drawSelectionBoxes( painter );
142  }
143 }
144 
146 {
147  if ( mDesignerWidget )
148  {
149  QSizeF widgetMinSize = mDesignerWidget->minimumSize();
150  return QSizeF( 2 * mFrameBorderWidth + widgetMinSize.width(), 2 * mFrameBorderWidth + widgetMinSize.height() );
151  }
152  else
153  {
154  return QSizeF( 0, 0 );
155  }
156 }
157 
159 {
160  if ( mDesignerWidget )
161  {
162  return mDesignerWidget->sizeHint();
163  }
164  else
165  {
166  return QSizeF( 0, 0 );
167  }
168 }
169 
170 void QgsFormAnnotationItem::writeXML( QDomDocument& doc ) const
171 {
172  QDomElement documentElem = doc.documentElement();
173  if ( documentElem.isNull() )
174  {
175  return;
176  }
177 
178  QDomElement formAnnotationElem = doc.createElement( "FormAnnotationItem" );
179  if ( mVectorLayer )
180  {
181  formAnnotationElem.setAttribute( "vectorLayer", mVectorLayer->id() );
182  }
183  formAnnotationElem.setAttribute( "hasFeature", mHasAssociatedFeature );
184  formAnnotationElem.setAttribute( "feature", mFeature );
185  formAnnotationElem.setAttribute( "designerForm", mDesignerForm );
186  _writeXML( doc, formAnnotationElem );
187  documentElem.appendChild( formAnnotationElem );
188 }
189 
190 void QgsFormAnnotationItem::readXML( const QDomDocument& doc, const QDomElement& itemElem )
191 {
192  mVectorLayer = 0;
193  if ( itemElem.hasAttribute( "vectorLayer" ) )
194  {
195  mVectorLayer = dynamic_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( itemElem.attribute( "vectorLayer", "" ) ) );
196  if ( mVectorLayer )
197  {
198  QObject::connect( mVectorLayer, SIGNAL( layerModified() ), this, SLOT( setFeatureForMapPosition() ) );
199  QObject::connect( mMapCanvas, SIGNAL( renderComplete( QPainter* ) ), this, SLOT( setFeatureForMapPosition() ) );
200  QObject::connect( mMapCanvas, SIGNAL( layersChanged() ), this, SLOT( updateVisibility() ) );
201  }
202  }
203  mHasAssociatedFeature = itemElem.attribute( "hasFeature", "0" ).toInt();
204  mFeature = itemElem.attribute( "feature", "0" ).toInt();
205  mDesignerForm = itemElem.attribute( "designerForm", "" );
206  QDomElement annotationElem = itemElem.firstChildElement( "AnnotationItem" );
207  if ( !annotationElem.isNull() )
208  {
209  _readXML( doc, annotationElem );
210  }
211 
213  if ( mDesignerWidget )
214  {
215  mFrameBackgroundColor = mDesignerWidget->palette().color( QPalette::Window );
216  mWidgetContainer->setWidget( mDesignerWidget );
217  }
219 }
220 
222 {
223  if ( !mVectorLayer || !mMapCanvas )
224  {
225  return;
226  }
227 
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 
234  QgsFeatureIterator fit = mVectorLayer->getFeatures( QgsFeatureRequest().setFilterRect( searchRect ).setFlags( QgsFeatureRequest::NoGeometry | QgsFeatureRequest::ExactIntersect ).setSubsetOfAttributes( QgsAttributeList() ) );
235 
236  QgsFeature currentFeature;
237  QgsFeatureId currentFeatureId = 0;
238  bool featureFound = false;
239 
240  while ( fit.nextFeature( currentFeature ) )
241  {
242  currentFeatureId = currentFeature.id();
243  featureFound = true;
244  break;
245  }
246 
247  mHasAssociatedFeature = featureFound;
248  mFeature = currentFeatureId;
249 
250  //create new embedded widget
251  mWidgetContainer->setWidget( 0 );
252  delete mDesignerWidget;
254  if ( mDesignerWidget )
255  {
256  mFrameBackgroundColor = mDesignerWidget->palette().color( QPalette::Window );
257  mWidgetContainer->setWidget( mDesignerWidget );
258  }
259 }
260 
262 {
263  bool visible = true;
264  if ( mVectorLayer && mMapCanvas )
265  {
266  visible = mMapCanvas->layers().contains( mVectorLayer );
267  }
268  setVisible( visible );
269 }
270 
271 
272