QGIS API Documentation  2.3.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
qgshtmlannotationitem.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgshtmlannotationitem.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 "qgshtmlannotationitem.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 "qgsexpression.h"
27 
28 #include <QDomElement>
29 #include <QDir>
30 #include <QFile>
31 #include <QFileInfo>
32 #include <QGraphicsProxyWidget>
33 #include <QPainter>
34 #include <QSettings>
35 #include <QWidget>
36 
37 
38 QgsHtmlAnnotationItem::QgsHtmlAnnotationItem( QgsMapCanvas* canvas, QgsVectorLayer* vlayer, bool hasFeature, int feature )
39  : QgsAnnotationItem( canvas ), mWidgetContainer( 0 ), mWebView( 0 ), mVectorLayer( vlayer ),
40  mHasAssociatedFeature( hasFeature ), mFeatureId( feature )
41 {
42  mWebView = new QWebView();
43  mWidgetContainer = new QGraphicsProxyWidget( this );
44  mWidgetContainer->setWidget( mWebView );
45 
46  QObject::connect( mWebView->page()->mainFrame(), SIGNAL( javaScriptWindowObjectCleared() ), this, SLOT( javascript() ) );
47 
48  if ( mVectorLayer && mMapCanvas )
49  {
50  QObject::connect( mVectorLayer, SIGNAL( layerModified() ), this, SLOT( setFeatureForMapPosition() ) );
51  QObject::connect( mMapCanvas, SIGNAL( renderComplete( QPainter* ) ), this, SLOT( setFeatureForMapPosition() ) );
52  QObject::connect( mMapCanvas, SIGNAL( layersChanged() ), this, SLOT( updateVisibility() ) );
53  }
54 
56 }
57 
59 {
60  delete mWebView;
61 }
62 
63 void QgsHtmlAnnotationItem::setHTMLPage( const QString& htmlFile )
64 {
65  QFile file( htmlFile );
66  mHtmlFile = htmlFile;
67  if ( !file.open( QIODevice::ReadOnly | QIODevice::Text ) )
68  {
69  mHtmlSource = "";
70  }
71  else
72  {
73  QTextStream in( &file );
74  in.setCodec( "UTF-8" );
75  mHtmlSource = in.readAll();
76  }
77 
78  file.close();
80 }
81 
83 {
86 }
87 
88 void QgsHtmlAnnotationItem::paint( QPainter * painter )
89 {
90  Q_UNUSED( painter );
91 }
92 
93 void QgsHtmlAnnotationItem::paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget )
94 {
95  Q_UNUSED( option );
96  Q_UNUSED( widget );
97  if ( !painter || !mWidgetContainer )
98  {
99  return;
100  }
101 
102  drawFrame( painter );
103  if ( mMapPositionFixed )
104  {
105  drawMarkerSymbol( painter );
106  }
107 
109  + mFrameBorderWidth / 2.0, mFrameSize.width() - mFrameBorderWidth, mFrameSize.height()
110  - mFrameBorderWidth ) );
111  if ( data( 1 ).toString() == "composer" )
112  {
113  mWidgetContainer->widget()->render( painter, mOffsetFromReferencePoint.toPoint() );
114  }
115 
116  if ( isSelected() )
117  {
118  drawSelectionBoxes( painter );
119  }
120 }
121 
123 {
124  if ( mWebView )
125  {
126  QSizeF widgetMinSize = mWebView->minimumSize();
127  return QSizeF( 2 * mFrameBorderWidth + widgetMinSize.width(), 2 * mFrameBorderWidth + widgetMinSize.height() );
128  }
129  else
130  {
131  return QSizeF( 0, 0 );
132  }
133 }
134 
135 void QgsHtmlAnnotationItem::writeXML( QDomDocument& doc ) const
136 {
137  QDomElement documentElem = doc.documentElement();
138  if ( documentElem.isNull() )
139  {
140  return;
141  }
142 
143  QDomElement formAnnotationElem = doc.createElement( "HtmlAnnotationItem" );
144  if ( mVectorLayer )
145  {
146  formAnnotationElem.setAttribute( "vectorLayer", mVectorLayer->id() );
147  }
148  formAnnotationElem.setAttribute( "hasFeature", mHasAssociatedFeature );
149  formAnnotationElem.setAttribute( "feature", mFeatureId );
150  formAnnotationElem.setAttribute( "htmlfile", htmlPage() );
151 
152  _writeXML( doc, formAnnotationElem );
153  documentElem.appendChild( formAnnotationElem );
154 }
155 
156 void QgsHtmlAnnotationItem::readXML( const QDomDocument& doc, const QDomElement& itemElem )
157 {
158  mVectorLayer = 0;
159  if ( itemElem.hasAttribute( "vectorLayer" ) )
160  {
161  mVectorLayer = dynamic_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( itemElem.attribute( "vectorLayer", "" ) ) );
162  if ( mVectorLayer )
163  {
164  QObject::connect( mVectorLayer, SIGNAL( layerModified() ), this, SLOT( setFeatureForMapPosition() ) );
165  QObject::connect( mMapCanvas, SIGNAL( renderComplete( QPainter* ) ), this, SLOT( setFeatureForMapPosition() ) );
166  QObject::connect( mMapCanvas, SIGNAL( layersChanged() ), this, SLOT( updateVisibility() ) );
167  }
168  }
169  mHasAssociatedFeature = itemElem.attribute( "hasFeature", "0" ).toInt();
170  mFeatureId = itemElem.attribute( "feature", "0" ).toInt();
171  mHtmlFile = itemElem.attribute( "htmlfile", "" );
172  QDomElement annotationElem = itemElem.firstChildElement( "AnnotationItem" );
173  if ( !annotationElem.isNull() )
174  {
175  _readXML( doc, annotationElem );
176  }
177 
178  if ( mWebView )
179  {
181  }
183 }
184 
186 {
187  if ( !mVectorLayer || !mMapCanvas )
188  {
189  return;
190  }
191 
192  QSettings settings;
193  double halfIdentifyWidth = QgsMapTool::searchRadiusMU( mMapCanvas );
194  QgsRectangle searchRect( mMapPosition.x() - halfIdentifyWidth, mMapPosition.y() - halfIdentifyWidth,
195  mMapPosition.x() + halfIdentifyWidth, mMapPosition.y() + halfIdentifyWidth );
196 
198 
199  QgsFeature currentFeature;
200  QgsFeatureId currentFeatureId = 0;
201  bool featureFound = false;
202 
203  while ( fit.nextFeature( currentFeature ) )
204  {
205  currentFeatureId = currentFeature.id();
206  featureFound = true;
207  break;
208  }
209 
210  mHasAssociatedFeature = featureFound;
211  mFeatureId = currentFeatureId;
212  mFeature = currentFeature;
213 
215  mWebView->setHtml( newtext );
216 }
217 
219 {
220  bool visible = true;
221  if ( mVectorLayer && mMapCanvas )
222  {
223  visible = mMapCanvas->layers().contains( mVectorLayer );
224  }
225  setVisible( visible );
226 }
227 
229 {
230  QWebFrame *frame = mWebView->page()->mainFrame();
231  frame->addToJavaScriptWindowObject( "canvas", mMapCanvas );
232  frame->addToJavaScriptWindowObject( "layer", mVectorLayer );
233 }
234 
235 
236 
QgsFeatureId id() const
Get the feature id for this feature.
Definition: qgsfeature.cpp:100
Wrapper for iterator of features from vector data provider or vector layer.
A rectangle specified with double values.
Definition: qgsrectangle.h:35
QgsVectorLayer * mVectorLayer
Associated vectorlayer (or 0 if attributes are not supposed to be replaced)
static double searchRadiusMU(const QgsRenderContext &context)
Get search radius in map units for given context.
Definition: qgsmaptool.cpp:199
QgsVectorLayer * vectorLayer() const
void _readXML(const QDomDocument &doc, const QDomElement &annotationElem)
double mFrameBorderWidth
Width of the frame.
Use exact geometry intersection (slower) instead of bounding boxes.
QgsFeatureId mFeatureId
Associated feature.
QPointF mOffsetFromReferencePoint
Describes the shift of the item content box to the reference point.
void writeXML(QDomDocument &doc) const
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())
Query the provider for features specified in request.
QList< QgsMapLayer * > layers() const
return list of layers within map canvas. Added in v1.5
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:114
void readXML(const QDomDocument &doc, const QDomElement &itemElem)
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:105
QgsHtmlAnnotationItem(QgsMapCanvas *canvas, QgsVectorLayer *vlayer=0, bool hasFeature=false, int feature=0)
double x() const
Definition: qgspoint.h:110
void drawSelectionBoxes(QPainter *p)
virtual void setMapPosition(const QgsPoint &pos)
This class wraps a request for features to a vector layer (or directly its vector data provider)...
QString id() const
Get this layer's unique ID, this ID is used to access this layer from map layer registry.
Definition: qgsmaplayer.cpp:92
void drawMarkerSymbol(QPainter *p)
QGraphicsProxyWidget * mWidgetContainer
void updateVisibility()
Sets visibility status based on mVectorLayer visibility.
A class to represent a point geometry.
Definition: qgspoint.h:63
An annotation item can be either placed either on screen corrdinates or on map coordinates.
QString file
Definition: qgssvgcache.cpp:76
void setMapPosition(const QgsPoint &pos)
Reimplemented from QgsAnnotationItem.
bool mMapPositionFixed
True: the item stays at the same map position, False: the item stays on same screen position...
static QgsMapLayerRegistry * instance()
Returns the instance pointer, creating the object on the first call.
void _writeXML(QDomDocument &doc, QDomElement &itemElem) const
void setHTMLPage(const QString &htmlFile)
QgsMapCanvas * mMapCanvas
pointer to map canvas
void drawFrame(QPainter *p)
qint64 QgsFeatureId
Definition: qgsfeature.h:30
double y() const
Definition: qgspoint.h:118
QgsMapLayer * mapLayer(QString theLayerId)
Retrieve a pointer to a loaded layer by id.
void setFeatureForMapPosition()
Sets a feature for the current map position and updates the dialog.
Geometry is not required. It may still be returned if e.g. required for a filter condition.
Represents a vector layer which manages a vector based data sets.
QgsPoint mMapPosition
Map position (in case mMapPositionFixed is true)
QSizeF mFrameSize
Size of the frame (without balloon)
static QString replaceExpressionText(const QString &action, const QgsFeature *feat, QgsVectorLayer *layer, const QMap< QString, QVariant > *substitutionMap=0)
This function currently replaces each expression between [% and %] in the string with the result of i...
bool mHasAssociatedFeature
True if the item is related to a vector feature.
void paint(QPainter *painter)
function to be implemented by derived classes