QGIS API Documentation  3.4.15-Madeira (e83d02e274)
qgshtmlannotation.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgshtmlannotation.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 "qgshtmlannotation.h"
19 #include "qgsfeature.h"
20 #include "qgsfeatureiterator.h"
21 #include "qgslogger.h"
22 #include "qgsproject.h"
23 #include "qgsvectorlayer.h"
24 #include "qgsexpression.h"
26 #include "qgswebpage.h"
27 #include "qgswebframe.h"
28 
29 #include <QDomElement>
30 #include <QDir>
31 #include <QFile>
32 #include <QFileInfo>
33 #include <QGraphicsProxyWidget>
34 #include <QPainter>
35 #include <QSettings>
36 #include <QWidget>
37 
38 
40  : QgsAnnotation( parent )
41 {
42  mWebPage = new QgsWebPage();
43  mWebPage->mainFrame()->setScrollBarPolicy( Qt::Horizontal, Qt::ScrollBarAlwaysOff );
44  mWebPage->mainFrame()->setScrollBarPolicy( Qt::Vertical, Qt::ScrollBarAlwaysOff );
45  mWebPage->setNetworkAccessManager( QgsNetworkAccessManager::instance() );
46 
47  connect( mWebPage->mainFrame(), &QWebFrame::javaScriptWindowObjectCleared, this, &QgsHtmlAnnotation::javascript );
48 }
49 
51 {
52  std::unique_ptr< QgsHtmlAnnotation > c( new QgsHtmlAnnotation() );
53  copyCommonProperties( c.get() );
54  c->setSourceFile( mHtmlFile );
55  return c.release();
56 }
57 
58 void QgsHtmlAnnotation::setSourceFile( const QString &htmlFile )
59 {
60  QFile file( htmlFile );
61  mHtmlFile = htmlFile;
62  if ( !file.open( QIODevice::ReadOnly | QIODevice::Text ) )
63  {
64  mHtmlSource.clear();
65  }
66  else
67  {
68  QTextStream in( &file );
69  in.setCodec( "UTF-8" );
70  mHtmlSource = in.readAll();
71  }
72 
73  file.close();
75  emit appearanceChanged();
76 }
77 
78 void QgsHtmlAnnotation::renderAnnotation( QgsRenderContext &context, QSizeF size ) const
79 {
80  if ( !context.painter() )
81  {
82  return;
83  }
84 
85  // scale painter back to 96 dpi, so layout prints match screen rendering
86  context.painter()->save();
87  const double scaleFactor = context.painter()->device()->logicalDpiX() / 96.0;
88  context.painter()->scale( scaleFactor, scaleFactor );
89  size /= scaleFactor;
90 
91  mWebPage->setViewportSize( size.toSize() );
92  mWebPage->mainFrame()->render( context.painter() );
93 
94  context.painter()->restore();
95 }
96 
98 {
99  if ( mWebPage )
100  {
101  QSizeF widgetMinSize = QSizeF( 0, 0 ); // mWebPage->minimumSize();
102  return QSizeF( contentsMargin().left() + contentsMargin().right() + widgetMinSize.width(),
103  contentsMargin().top() + contentsMargin().bottom() + widgetMinSize.height() );
104  }
105  else
106  {
107  return QSizeF( 0, 0 );
108  }
109 }
110 
111 void QgsHtmlAnnotation::writeXml( QDomElement &elem, QDomDocument &doc, const QgsReadWriteContext &context ) const
112 {
113  QDomElement formAnnotationElem = doc.createElement( QStringLiteral( "HtmlAnnotationItem" ) );
114  formAnnotationElem.setAttribute( QStringLiteral( "htmlfile" ), sourceFile() );
115 
116  _writeXml( formAnnotationElem, doc, context );
117  elem.appendChild( formAnnotationElem );
118 }
119 
120 void QgsHtmlAnnotation::readXml( const QDomElement &itemElem, const QgsReadWriteContext &context )
121 {
122  mHtmlFile = itemElem.attribute( QStringLiteral( "htmlfile" ), QString() );
123  QDomElement annotationElem = itemElem.firstChildElement( QStringLiteral( "AnnotationItem" ) );
124  if ( !annotationElem.isNull() )
125  {
126  _readXml( annotationElem, context );
127  }
128 
129  // upgrade old layer
130  if ( !mapLayer() && itemElem.hasAttribute( QStringLiteral( "vectorLayer" ) ) )
131  {
132  setMapLayer( QgsProject::instance()->mapLayer( itemElem.attribute( QStringLiteral( "vectorLayer" ) ) ) );
133  }
134 
135  if ( mWebPage )
136  {
137  setSourceFile( mHtmlFile );
138  }
139 }
140 
142 {
144  QString newText;
145  QgsVectorLayer *vectorLayer = qobject_cast< QgsVectorLayer * >( mapLayer() );
146  if ( feature.isValid() && vectorLayer )
147  {
149  context.setFeature( feature );
150  newText = QgsExpression::replaceExpressionText( mHtmlSource, &context );
151  }
152  else
153  {
154  newText = mHtmlSource;
155  }
156  mWebPage->mainFrame()->setHtml( newText );
157  emit appearanceChanged();
158 }
159 
160 void QgsHtmlAnnotation::javascript()
161 {
162  QWebFrame *frame = mWebPage->mainFrame();
163  frame->addToJavaScriptWindowObject( QStringLiteral( "layer" ), mapLayer() );
164 }
165 
166 
167 
The class is used as a container of context for various read/write operations on other objects...
QgsHtmlAnnotation(QObject *parent=nullptr)
Constructor for QgsHtmlAnnotation.
void appearanceChanged()
Emitted whenever the annotation&#39;s appearance changes.
QgsFeature associatedFeature() const
Returns the feature associated with the annotation, or an invalid feature if none has been set...
bool isValid() const
Returns the validity of this feature.
Definition: qgsfeature.cpp:183
void setMapLayer(QgsMapLayer *layer)
Sets the map layer associated with the annotation.
QgsHtmlAnnotation * clone() const override
Clones the annotation, returning a new copy of the annotation reflecting the annotation&#39;s current sta...
void setSourceFile(const QString &htmlFile)
Sets the file path for the source HTML file.
void renderAnnotation(QgsRenderContext &context, QSizeF size) const override
Renders the annotation&#39;s contents to a target /a context at the specified /a size.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:55
An annotation item that embeds HTML content.
void _writeXml(QDomElement &itemElem, QDomDocument &doc, const QgsReadWriteContext &context) const
Writes common annotation properties to a DOM element.
Abstract base class for annotation items which are drawn over a map.
Definition: qgsannotation.h:48
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
void readXml(const QDomElement &itemElem, const QgsReadWriteContext &context) override
Restores the annotation&#39;s state from a DOM element.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void copyCommonProperties(QgsAnnotation *target) const
Copies common annotation properties to the targe annotation.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer&#39;s project and layer.
QSizeF minimumFrameSize() const override
Returns the minimum frame size for the annotation.
void _readXml(const QDomElement &annotationElem, const QgsReadWriteContext &context)
Reads common annotation properties from a DOM element.
void setAssociatedFeature(const QgsFeature &feature) override
Sets the feature associated with the annotation.
static QgsNetworkAccessManager * instance(Qt::ConnectionType connectionType=Qt::BlockingQueuedConnection)
Returns a pointer to the active QgsNetworkAccessManager for the current thread.
Contains information about the context of a rendering operation.
double bottom() const
Returns the bottom margin.
Definition: qgsmargins.h:90
QPainter * painter()
Returns the destination QPainter for the render operation.
double top() const
Returns the top margin.
Definition: qgsmargins.h:78
QgsMargins contentsMargin() const
Returns the margins (in millimeters) between the outside of the frame and the annotation content...
void writeXml(QDomElement &elem, QDomDocument &doc, const QgsReadWriteContext &context) const override
Writes the annotation state to a DOM element.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:411
QgsMapLayer * mapLayer() const
Returns the map layer associated with the annotation.
Represents a vector layer which manages a vector based data sets.
virtual void setAssociatedFeature(const QgsFeature &feature)
Sets the feature associated with the annotation.
QWebPage subclass which redirects JavaScript errors and console output to the QGIS message log...
Definition: qgswebpage.h:216
The QWebFrame class is a collection of stubs to mimic the API of a QWebFrame on systems where QtWebki...
Definition: qgswebframe.h:37
QString sourceFile() const
Returns the file path for the source HTML file.
static QString replaceExpressionText(const QString &action, const QgsExpressionContext *context, const QgsDistanceArea *distanceArea=nullptr)
This function replaces each expression between [% and %] in the string with the result of its evaluat...