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