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