Quantum GIS API Documentation  1.7.5-Wroclaw
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator 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  if ( mVectorLayer && mMapCanvas ) //default to the layers edit form
41  {
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 
49 }
50 
52 {
53  delete mDesignerWidget;
54 }
55 
56 void QgsFormAnnotationItem::setDesignerForm( const QString& uiFile )
57 {
58  mDesignerForm = uiFile;
59  mWidgetContainer->setWidget( 0 );
60  delete mDesignerWidget;
62  if ( mDesignerWidget )
63  {
64  mFrameBackgroundColor = mDesignerWidget->palette().color( QPalette::Window );
65  mWidgetContainer->setWidget( mDesignerWidget );
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
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 
111 {
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 
135  + mFrameBorderWidth / 2.0, mFrameSize.width() - mFrameBorderWidth, mFrameSize.height() \
136  - mFrameBorderWidth ) );
137 
138  if ( isSelected() )
139  {
140  drawSelectionBoxes( painter );
141  }
142 }
143 
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 
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->id() );
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 
212  if ( mDesignerWidget )
213  {
214  mFrameBackgroundColor = mDesignerWidget->palette().color( QPalette::Window );
215  mWidgetContainer->setWidget( mDesignerWidget );
216  }
218 }
219 
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;
253  if ( mDesignerWidget )
254  {
255  mFrameBackgroundColor = mDesignerWidget->palette().color( QPalette::Window );
256  mWidgetContainer->setWidget( mDesignerWidget );
257  }
258 }
259 
261 {
262  bool visible = true;
263  if ( mVectorLayer && mMapCanvas )
264  {
265  visible = mMapCanvas->layers().contains( mVectorLayer );
266  }
267  setVisible( visible );
268 }
269 
270 
271