QGIS API Documentation  2.15.0-Master (1f0fce7)
qgscomposerhtml.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgscomposerhtml.cpp
3  ------------------------------------------------------------
4  begin : July 2012
5  copyright : (C) 2012 by Marco Hugentobler
6  email : marco dot hugentobler at sourcepole dot ch
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgscomposerhtml.h"
17 #include "qgscomposerframe.h"
18 #include "qgscomposition.h"
21 #include "qgsmessagelog.h"
22 #include "qgsexpression.h"
23 #include "qgslogger.h"
25 #include "qgsvectorlayer.h"
26 #include "qgsproject.h"
27 #include "qgsdistancearea.h"
28 #include "qgsjsonutils.h"
29 
30 #include "qgswebpage.h"
31 #include "qgswebframe.h"
32 
33 #include <QCoreApplication>
34 #include <QPainter>
35 #include <QImage>
36 #include <QNetworkReply>
37 
38 QgsComposerHtml::QgsComposerHtml( QgsComposition* c, bool createUndoCommands )
39  : QgsComposerMultiFrame( c, createUndoCommands )
40  , mContentMode( QgsComposerHtml::Url )
41  , mWebPage( nullptr )
42  , mLoaded( false )
43  , mHtmlUnitsToMM( 1.0 )
44  , mRenderedPage( nullptr )
45  , mEvaluateExpressions( true )
46  , mUseSmartBreaks( true )
47  , mMaxBreakDistance( 10 )
48  , mExpressionLayer( nullptr )
49  , mDistanceArea( nullptr )
50  , mEnableUserStylesheet( false )
51  , mFetcher( nullptr )
52 {
53  mDistanceArea = new QgsDistanceArea();
54  mHtmlUnitsToMM = htmlUnitsToMM();
55  mWebPage = new QgsWebPage();
56  mWebPage->setIdentifier( tr( "Composer HTML item" ) );
57  mWebPage->mainFrame()->setScrollBarPolicy( Qt::Horizontal, Qt::ScrollBarAlwaysOff );
58  mWebPage->mainFrame()->setScrollBarPolicy( Qt::Vertical, Qt::ScrollBarAlwaysOff );
59 
60  //This makes the background transparent. Found on http://blog.qt.digia.com/blog/2009/06/30/transparent-qwebview-or-qwebpage/
61  QPalette palette = mWebPage->palette();
62  palette.setBrush( QPalette::Base, Qt::transparent );
63  mWebPage->setPalette( palette );
64 
66  QObject::connect( mWebPage, SIGNAL( loadFinished( bool ) ), this, SLOT( frameLoaded( bool ) ) );
67  if ( mComposition )
68  {
69  QObject::connect( mComposition, SIGNAL( itemRemoved( QgsComposerItem* ) ), this, SLOT( handleFrameRemoval( QgsComposerItem* ) ) );
70  }
71 
72  // data defined strings
73  mDataDefinedNames.insert( QgsComposerObject::SourceUrl, QString( "dataDefinedSourceUrl" ) );
74 
76  {
77  //a html item added while atlas preview is enabled needs to have the expression context set,
78  //otherwise fields in the html aren't correctly evaluated until atlas preview feature changes (#9457)
80  }
81 
82  //connect to atlas feature changes
83  //to update the expression context
84  connect( &mComposition->atlasComposition(), SIGNAL( featureChanged( QgsFeature* ) ), this, SLOT( refreshExpressionContext() ) );
85 
86  mFetcher = new QgsNetworkContentFetcher();
87  connect( mFetcher, SIGNAL( finished() ), this, SLOT( frameLoaded() ) );
88 
89 }
90 
92 {
93  delete mDistanceArea;
94  delete mWebPage;
95  delete mRenderedPage;
96  mFetcher->deleteLater();
97 }
98 
100 {
101  if ( !mWebPage )
102  {
103  return;
104  }
105 
106  mUrl = url;
107  loadHtml( true );
108  emit changed();
109 }
110 
112 {
113  mHtml = html;
114  //TODO - this signal should be emitted, but without changing the signal which sets the html
115  //to an equivalent of editingFinished it causes a lot of problems. Need to investigate
116  //ways of doing this using QScintilla widgets.
117  //emit changed();
118 }
119 
121 {
122  mEvaluateExpressions = evaluateExpressions;
123  loadHtml( true );
124  emit changed();
125 }
126 
127 void QgsComposerHtml::loadHtml( const bool useCache, const QgsExpressionContext *context )
128 {
129  if ( !mWebPage )
130  {
131  return;
132  }
133 
134  const QgsExpressionContext* evalContext = context;
136  if ( !evalContext )
137  {
138  scopedContext.reset( createExpressionContext() );
139  evalContext = scopedContext.data();
140  }
141 
142  QString loadedHtml;
143  switch ( mContentMode )
144  {
146  {
147 
148  QString currentUrl = mUrl.toString();
149 
150  //data defined url set?
151  QVariant exprVal;
152  if ( dataDefinedEvaluate( QgsComposerObject::SourceUrl, exprVal, *evalContext ) )
153  {
154  currentUrl = exprVal.toString().trimmed();
155  QgsDebugMsg( QString( "exprVal Source Url:%1" ).arg( currentUrl ) );
156  }
157  if ( currentUrl.isEmpty() )
158  {
159  return;
160  }
161  if ( !( useCache && currentUrl == mLastFetchedUrl ) )
162  {
163  loadedHtml = fetchHtml( QUrl( currentUrl ) );
164  mLastFetchedUrl = currentUrl;
165  }
166  else
167  {
168  loadedHtml = mFetchedHtml;
169  }
170 
171  break;
172  }
174  loadedHtml = mHtml;
175  break;
176  }
177 
178  //evaluate expressions
179  if ( mEvaluateExpressions )
180  {
181  loadedHtml = QgsExpression::replaceExpressionText( loadedHtml, evalContext, nullptr, mDistanceArea );
182  }
183 
184  mLoaded = false;
185 
186  //reset page size. otherwise viewport size increases but never decreases again
187  mWebPage->setViewportSize( QSize( maxFrameWidth() * mHtmlUnitsToMM, 0 ) );
188 
189  //set html, using the specified url as base if in Url mode or the project file if in manual mode
190  const QUrl baseUrl = mContentMode == QgsComposerHtml::Url ?
191  QUrl( mActualFetchedUrl ) :
192  QUrl::fromLocalFile( QgsProject::instance()->fileInfo().absoluteFilePath() );
193  mWebPage->mainFrame()->setHtml( loadedHtml, baseUrl );
194 
195  //set user stylesheet
196  QWebSettings* settings = mWebPage->settings();
197  if ( mEnableUserStylesheet && ! mUserStylesheet.isEmpty() )
198  {
199  QByteArray ba;
200  ba.append( mUserStylesheet.toUtf8() );
201  QUrl cssFileURL = QUrl( "data:text/css;charset=utf-8;base64," + ba.toBase64() );
202  settings->setUserStyleSheetUrl( cssFileURL );
203  }
204  else
205  {
206  settings->setUserStyleSheetUrl( QUrl() );
207  }
208 
209  while ( !mLoaded )
210  {
211  qApp->processEvents();
212  }
213 
214  //inject JSON feature
215  if ( !mAtlasFeatureJSON.isEmpty() )
216  {
217  mWebPage->mainFrame()->evaluateJavaScript( QString( "if ( typeof setFeature === \"function\" ) { setFeature(%1); }" ).arg( mAtlasFeatureJSON ) );
218  //needs an extra process events here to give javascript a chance to execute
219  qApp->processEvents();
220  }
221 
223  //trigger a repaint
224  emit contentsChanged();
225 }
226 
227 void QgsComposerHtml::frameLoaded( bool ok )
228 {
229  Q_UNUSED( ok );
230  mLoaded = true;
231 }
232 
233 double QgsComposerHtml::maxFrameWidth() const
234 {
235  double maxWidth = 0;
237  for ( ; frameIt != mFrameItems.constEnd(); ++frameIt )
238  {
239  maxWidth = qMax( maxWidth, static_cast< double >(( *frameIt )->boundingRect().width() ) );
240  }
241 
242  return maxWidth;
243 }
244 
246 {
247  if ( frameCount() < 1 ) return;
248 
249  QSize contentsSize = mWebPage->mainFrame()->contentsSize();
250 
251  //find maximum frame width
252  double maxWidth = maxFrameWidth();
253  //set content width to match maximum frame width
254  contentsSize.setWidth( maxWidth * mHtmlUnitsToMM );
255 
256  mWebPage->setViewportSize( contentsSize );
257  mSize.setWidth( contentsSize.width() / mHtmlUnitsToMM );
258  mSize.setHeight( contentsSize.height() / mHtmlUnitsToMM );
259  if ( contentsSize.isValid() )
260  {
261  renderCachedImage();
262  }
264  emit changed();
265 }
266 
267 void QgsComposerHtml::renderCachedImage()
268 {
269  //render page to cache image
270  if ( mRenderedPage )
271  {
272  delete mRenderedPage;
273  }
274  mRenderedPage = new QImage( mWebPage->viewportSize(), QImage::Format_ARGB32 );
275  if ( mRenderedPage->isNull() )
276  {
277  return;
278  }
279  mRenderedPage->fill( Qt::transparent );
280  QPainter painter;
281  painter.begin( mRenderedPage );
282  mWebPage->mainFrame()->render( &painter );
283  painter.end();
284 }
285 
286 QString QgsComposerHtml::fetchHtml( const QUrl& url )
287 {
288  //pause until HTML fetch
289  mLoaded = false;
290  mFetcher->fetchContent( url );
291 
292  while ( !mLoaded )
293  {
294  qApp->processEvents();
295  }
296 
297  mFetchedHtml = mFetcher->contentAsString();
298  mActualFetchedUrl = mFetcher->reply()->url().toString();
299  return mFetchedHtml;
300 }
301 
303 {
304  return mSize;
305 }
306 
307 void QgsComposerHtml::render( QPainter* p, const QRectF& renderExtent, const int frameIndex )
308 {
309  Q_UNUSED( frameIndex );
310 
311  if ( !mWebPage )
312  {
313  return;
314  }
315 
316  p->save();
317  p->setRenderHint( QPainter::Antialiasing );
318  p->scale( 1.0 / mHtmlUnitsToMM, 1.0 / mHtmlUnitsToMM );
319  p->translate( 0.0, -renderExtent.top() * mHtmlUnitsToMM );
320  mWebPage->mainFrame()->render( p, QRegion( renderExtent.left(), renderExtent.top() * mHtmlUnitsToMM, renderExtent.width() * mHtmlUnitsToMM, renderExtent.height() * mHtmlUnitsToMM ) );
321  p->restore();
322 }
323 
324 double QgsComposerHtml::htmlUnitsToMM()
325 {
326  if ( !mComposition )
327  {
328  return 1.0;
329  }
330 
331  return ( mComposition->printResolution() / 72.0 ); //webkit seems to assume a standard dpi of 96
332 }
333 
334 void QgsComposerHtml::addFrame( QgsComposerFrame* frame, bool recalcFrameSizes )
335 {
336  mFrameItems.push_back( frame );
337  QObject::connect( frame, SIGNAL( sizeChanged() ), this, SLOT( recalculateFrameSizes() ) );
338  if ( mComposition )
339  {
340  mComposition->addComposerHtmlFrame( this, frame );
341  }
342 
343  if ( recalcFrameSizes )
344  {
346  }
347 }
348 
350 {
351  if ( c1.second < c2.second )
352  return true;
353  else if ( c1.second > c2.second )
354  return false;
355  else if ( c1.first > c2.first )
356  return true;
357  else
358  return false;
359 }
360 
362 {
363  if ( !mWebPage || !mRenderedPage || !mUseSmartBreaks )
364  {
365  return yPos;
366  }
367 
368  //convert yPos to pixels
369  int idealPos = yPos * htmlUnitsToMM();
370 
371  //if ideal break pos is past end of page, there's nothing we need to do
372  if ( idealPos >= mRenderedPage->height() )
373  {
374  return yPos;
375  }
376 
377  int maxSearchDistance = mMaxBreakDistance * htmlUnitsToMM();
378 
379  //loop through all lines just before ideal break location, up to max distance
380  //of maxSearchDistance
381  int changes = 0;
382  QRgb currentColor;
383  bool currentPixelTransparent = false;
384  bool previousPixelTransparent = false;
385  QRgb pixelColor;
386  QList< QPair<int, int> > candidates;
387  int minRow = qMax( idealPos - maxSearchDistance, 0 );
388  for ( int candidateRow = idealPos; candidateRow >= minRow; --candidateRow )
389  {
390  changes = 0;
391  currentColor = qRgba( 0, 0, 0, 0 );
392  //check all pixels in this line
393  for ( int col = 0; col < mRenderedPage->width(); ++col )
394  {
395  //count how many times the pixels change color in this row
396  //eventually, we select a row to break at with the minimum number of color changes
397  //since this is likely a line break, or gap between table cells, etc
398  //but very unlikely to be midway through a text line or picture
399  pixelColor = mRenderedPage->pixel( col, candidateRow );
400  currentPixelTransparent = qAlpha( pixelColor ) == 0;
401  if ( pixelColor != currentColor && !( currentPixelTransparent && previousPixelTransparent ) )
402  {
403  //color has changed
404  currentColor = pixelColor;
405  changes++;
406  }
407  previousPixelTransparent = currentPixelTransparent;
408  }
409  candidates.append( qMakePair( candidateRow, changes ) );
410  }
411 
412  //sort candidate rows by number of changes ascending, row number descending
413  qSort( candidates.begin(), candidates.end(), candidateSort );
414  //first candidate is now the largest row with smallest number of changes
415 
416  //ok, now take the mid point of the best candidate position
417  //we do this so that the spacing between text lines is likely to be split in half
418  //otherwise the html will be broken immediately above a line of text, which
419  //looks a little messy
420  int maxCandidateRow = candidates[0].first;
421  int minCandidateRow = maxCandidateRow + 1;
422  int minCandidateChanges = candidates[0].second;
423 
424  QList< QPair<int, int> >::iterator it;
425  for ( it = candidates.begin(); it != candidates.end(); ++it )
426  {
427  if (( *it ).second != minCandidateChanges || ( *it ).first != minCandidateRow - 1 )
428  {
429  //no longer in a consecutive block of rows of minimum pixel color changes
430  //so return the row mid-way through the block
431  //first converting back to mm
432  return ( minCandidateRow + ( maxCandidateRow - minCandidateRow ) / 2 ) / htmlUnitsToMM();
433  }
434  minCandidateRow = ( *it ).first;
435  }
436 
437  //above loop didn't work for some reason
438  //return first candidate converted to mm
439  return candidates[0].first / htmlUnitsToMM();
440 }
441 
443 {
444  mUseSmartBreaks = useSmartBreaks;
446  emit changed();
447 }
448 
450 {
451  mMaxBreakDistance = maxBreakDistance;
453  emit changed();
454 }
455 
457 {
458  mUserStylesheet = stylesheet;
459  //TODO - this signal should be emitted, but without changing the signal which sets the css
460  //to an equivalent of editingFinished it causes a lot of problems. Need to investigate
461  //ways of doing this using QScintilla widgets.
462  //emit changed();
463 }
464 
465 void QgsComposerHtml::setUserStylesheetEnabled( const bool stylesheetEnabled )
466 {
467  if ( mEnableUserStylesheet != stylesheetEnabled )
468  {
469  mEnableUserStylesheet = stylesheetEnabled;
470  loadHtml( true );
471  emit changed();
472  }
473 }
474 
476 {
477  return tr( "<HTML frame>" );
478 }
479 
480 bool QgsComposerHtml::writeXML( QDomElement& elem, QDomDocument & doc, bool ignoreFrames ) const
481 {
482  QDomElement htmlElem = doc.createElement( "ComposerHtml" );
483  htmlElem.setAttribute( "contentMode", QString::number( static_cast< int >( mContentMode ) ) );
484  htmlElem.setAttribute( "url", mUrl.toString() );
485  htmlElem.setAttribute( "html", mHtml );
486  htmlElem.setAttribute( "evaluateExpressions", mEvaluateExpressions ? "true" : "false" );
487  htmlElem.setAttribute( "useSmartBreaks", mUseSmartBreaks ? "true" : "false" );
488  htmlElem.setAttribute( "maxBreakDistance", QString::number( mMaxBreakDistance ) );
489  htmlElem.setAttribute( "stylesheet", mUserStylesheet );
490  htmlElem.setAttribute( "stylesheetEnabled", mEnableUserStylesheet ? "true" : "false" );
491 
492  bool state = _writeXML( htmlElem, doc, ignoreFrames );
493  elem.appendChild( htmlElem );
494  return state;
495 }
496 
497 bool QgsComposerHtml::readXML( const QDomElement& itemElem, const QDomDocument& doc, bool ignoreFrames )
498 {
499  if ( !ignoreFrames )
500  {
501  deleteFrames();
502  }
503 
504  //first create the frames
505  if ( !_readXML( itemElem, doc, ignoreFrames ) )
506  {
507  return false;
508  }
509 
510  bool contentModeOK;
511  mContentMode = static_cast< QgsComposerHtml::ContentMode >( itemElem.attribute( "contentMode" ).toInt( &contentModeOK ) );
512  if ( !contentModeOK )
513  {
514  mContentMode = QgsComposerHtml::Url;
515  }
516  mEvaluateExpressions = itemElem.attribute( "evaluateExpressions", "true" ) == "true" ? true : false;
517  mUseSmartBreaks = itemElem.attribute( "useSmartBreaks", "true" ) == "true" ? true : false;
518  mMaxBreakDistance = itemElem.attribute( "maxBreakDistance", "10" ).toDouble();
519  mHtml = itemElem.attribute( "html" );
520  mUserStylesheet = itemElem.attribute( "stylesheet" );
521  mEnableUserStylesheet = itemElem.attribute( "stylesheetEnabled", "false" ) == "true" ? true : false;
522 
523  //finally load the set url
524  QString urlString = itemElem.attribute( "url" );
525  if ( !urlString.isEmpty() )
526  {
527  mUrl = urlString;
528  }
529  loadHtml( true );
530 
531  //since frames had to be created before, we need to emit a changed signal to refresh the widget
532  emit changed();
533  return true;
534 }
535 
536 void QgsComposerHtml::setExpressionContext( const QgsFeature &feature, QgsVectorLayer* layer )
537 {
538  mExpressionFeature = feature;
539  mExpressionLayer = layer;
540 
541  //setup distance area conversion
542  if ( layer )
543  {
544  mDistanceArea->setSourceCrs( layer->crs().srsid() );
545  }
546  else if ( mComposition )
547  {
548  //set to composition's mapsettings' crs
549  mDistanceArea->setSourceCrs( mComposition->mapSettings().destinationCrs().srsid() );
550  }
551  if ( mComposition )
552  {
554  }
555  mDistanceArea->setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );
556 
557  // create JSON representation of feature
558  QgsJSONExporter exporter( layer );
559  exporter.setIncludeRelated( true );
560  mAtlasFeatureJSON = exporter.exportFeature( feature );
561 }
562 
564 {
565  QgsVectorLayer * vl = nullptr;
566  QgsFeature feature;
567 
569  {
571  }
573  {
574  feature = mComposition->atlasComposition().feature();
575  }
576 
577  setExpressionContext( feature, vl );
578  loadHtml( true );
579 }
580 
582 {
583  const QgsExpressionContext* evalContext = context;
585  if ( !evalContext )
586  {
587  scopedContext.reset( createExpressionContext() );
588  evalContext = scopedContext.data();
589  }
590 
591  //updates data defined properties and redraws item to match
592  if ( property == QgsComposerObject::SourceUrl || property == QgsComposerObject::AllProperties )
593  {
594  loadHtml( true, evalContext );
595  }
597 }
void setBrush(ColorRole role, const QBrush &brush)
virtual void recalculateFrameSizes()
Recalculates the portion of the multiframe item which is shown in each of it&#39;s component frames...
QgsComposition::AtlasMode atlasMode() const
Returns the current atlas mode of the composition.
QString contentAsString() const
Returns the fetched content as a string.
bool isValid() const
int width() const
bool end()
void setRenderHint(RenderHint hint, bool on)
QDomNode appendChild(const QDomNode &newChild)
void push_back(const T &value)
void setIdentifier(const QString &identifier)
Sets an identifier for the QgsWebPage.
Definition: qgswebpage.h:218
QString attribute(const QString &name, const QString &defValue) const
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
bool writeXML(QDomElement &elem, QDomDocument &doc, bool ignoreFrames=false) const override
Stores state information about multiframe in DOM element.
long srsid() const
Returns the SrsId, if available.
virtual QString displayName() const override
Get multiframe display name.
const QgsMapSettings & mapSettings() const
Return setting of QGIS map canvas.
void setSourceCrs(long srsid)
sets source spatial reference system (by QGIS CRS)
void scale(qreal sx, qreal sy)
QMap< QgsComposerObject::DataDefinedProperty, QString > mDataDefinedNames
Map of data defined properties for the item to string name to use when exporting item to xml...
A item that forms part of a map composition.
virtual void refreshDataDefinedProperty(const DataDefinedProperty property=AllProperties, const QgsExpressionContext *context=nullptr)
Refreshes a data defined property for the item by reevaluating the property&#39;s value and redrawing the...
void save()
bool enabled() const
Returns whether the atlas generation is enabled.
bool hasCrsTransformEnabled() const
returns true if projections are enabled for this layer set
QgsComposerHtml(QgsComposition *c, bool createUndoCommands)
qreal top() const
QgsFeature feature() const
Returns the current atlas feature.
QNetworkReply * reply()
Returns a reference to the network reply.
bool setEllipsoid(const QString &ellipsoid)
Sets ellipsoid by its acronym.
bool isNull() const
void setEvaluateExpressions(bool evaluateExpressions)
Sets whether the html item will evaluate QGIS expressions prior to rendering the HTML content...
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:187
double toDouble(bool *ok) const
void setIncludeRelated(bool includeRelated)
Sets whether to include attributes of features linked via references in the JSON exports.
Definition: qgsjsonutils.h:84
QString toString(QFlags< QUrl::FormattingOption > options) const
QString tr(const char *sourceText, const char *disambiguation, int n)
qreal left() const
Handles exporting QgsFeature features to GeoJSON features.
Definition: qgsjsonutils.h:35
DataDefinedProperty
Data defined properties for different item types.
QSizeF totalSize() const override
Returns the total size of the multiframe&#39;s content.
const QString GEO_NONE
Constant that holds the string representation for "No ellips/No CRS".
Definition: qgis.cpp:76
bool useSmartBreaks() const
Returns whether html item is using smart breaks.
void reset(T *other)
QString html() const
Returns the HTML source displayed in the item if the item is using the QgsComposerHtml::ManualHtml mo...
void loadHtml(const bool useCache=false, const QgsExpressionContext *context=nullptr)
Reloads the html source from the url and redraws the item.
void setHtml(const QString &html)
Sets the HTML to display in the item when the item is using the QgsComposerHtml::ManualHtml mode...
bool _readXML(const QDomElement &itemElem, const QDomDocument &doc, bool ignoreFrames=false)
Restores state information about base multiframe object from a DOM element.
virtual QgsExpressionContext * createExpressionContext() const
Creates an expression context relating to the objects&#39; current state.
QRgb pixel(int x, int y) const
QString number(int n, int base)
void append(const T &value)
QVariant property(const char *name) const
void setHtml(const QString &html, const QUrl &baseUrl)
void setUserStyleSheetUrl(const QUrl &location)
void fill(uint pixelValue)
HTTP network content fetcher.
int printResolution() const
int width() const
void setAttribute(const QString &name, const QString &value)
void setWidth(qreal width)
void recalculateFrameSizes() override
Recalculates the frame sizes for the current viewport dimensions.
const QgsCoordinateReferenceSystem & destinationCrs() const
returns CRS of destination coordinate reference system
int toInt(bool *ok, int base) const
void setWidth(int width)
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Abstract base class for composer items with the ability to distribute the content to several frames (...
void addFrame(QgsComposerFrame *frame, bool recalcFrameSizes=true) override
Adds a frame to the multiframe.
bool isEmpty() const
QString trimmed() const
QList< QgsComposerFrame * > mFrameItems
QWebFrame * mainFrame() const
bool _writeXML(QDomElement &elem, QDomDocument &doc, bool ignoreFrames=false) const
Stores state information about base multiframe object in DOM element.
void setMaxBreakDistance(double maxBreakDistance)
Sets the maximum distance allowed when calculating where to place page breaks in the html...
bool evaluateExpressions() const
Returns whether html item will evaluate QGIS expressions prior to rendering the HTML content...
void setUseSmartBreaks(bool useSmartBreaks)
Sets whether the html item should use smart breaks.
void deleteLater()
T & first()
QVariant evaluateJavaScript(const QString &scriptSource)
int frameCount() const
Returns the number of frames associated with this multiframe.
Graphics scene for map printing.
Frame item for a composer multiframe item.
QByteArray & append(char ch)
T * data() const
iterator end()
const QUrl & url() const
Returns the URL of the content displayed in the item if the item is using the QgsComposerHtml::Url mo...
bool dataDefinedEvaluate(const QgsComposerObject::DataDefinedProperty property, QVariant &expressionValue, const QgsExpressionContext &context=QgsExpressionContext()) const
Evaluate a data defined property and return the calculated value.
QWebSettings * settings() const
void restore()
General purpose distance and area calculator.
virtual void refreshDataDefinedProperty(const QgsComposerObject::DataDefinedProperty property=QgsComposerObject::AllProperties, const QgsExpressionContext *context=nullptr) override
QgsComposition * mComposition
void deleteFrames()
Removes and deletes all child frames.
void setUserStylesheet(const QString &stylesheet)
Sets the user stylesheet CSS rules to use while rendering the HTML content.
void refreshExpressionContext()
void render(QPainter *painter)
void contentsChanged()
Emitted when the contents of the multi frame have changed and the frames must be redrawn.
qreal width() const
static QgsNetworkAccessManager * instance()
returns a pointer to the single instance
double maxBreakDistance() const
Returns the maximum distance allowed when calculating where to place page breaks in the html...
void addComposerHtmlFrame(QgsComposerHtml *html, QgsComposerFrame *frame)
Adds composer html frame and advises composer to create a widget for it (through signal) ...
void setUrl(const QUrl &url)
Sets the URL for content to display in the item when the item is using the QgsComposerHtml::Url mode...
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:382
void setScrollBarPolicy(Qt::Orientation orientation, Qt::ScrollBarPolicy policy)
int height() const
QUrl url() const
void translate(const QPointF &offset)
static Q_DECL_DEPRECATED QString replaceExpressionText(const QString &action, const QgsFeature *feat, QgsVectorLayer *layer, const QMap< QString, QVariant > *substitutionMap=nullptr, const QgsDistanceArea *distanceArea=nullptr)
This function currently replaces each expression between [% and %] in the string with the result of i...
int frameIndex(QgsComposerFrame *frame) const
Returns the index of a frame within the multiframe.
const QgsCoordinateReferenceSystem & crs() const
Returns layer&#39;s spatial reference system.
bool candidateSort(QPair< int, int > c1, QPair< int, int > c2)
qreal height() const
int height() const
QgsAtlasComposition & atlasComposition()
iterator insert(const Key &key, const T &value)
QgsComposerFrame * frame(int i) const
Returns a child frame from the multiframe.
QgsVectorLayer * coverageLayer() const
Returns the coverage layer used for the atlas features.
QByteArray toBase64() const
QString exportFeature(const QgsFeature &feature, const QVariantMap &extraProperties=QVariantMap(), const QVariant &id=QVariant()) const
Returns a GeoJSON string representation of a feature.
void setUserStylesheetEnabled(const bool stylesheetEnabled)
Sets whether user stylesheets are enabled for the HTML content.
bool readXML(const QDomElement &itemElem, const QDomDocument &doc, bool ignoreFrames=false) override
Reads multiframe state information from a DOM element.
const_iterator constEnd() const
QDomElement createElement(const QString &tagName)
const_iterator constBegin() const
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void fetchContent(const QUrl &url)
Fetches content from a remote URL and handles redirects.
Represents a vector layer which manages a vector based data sets.
bool begin(QPaintDevice *device)
ContentMode
Source modes for the HTML content to render in the item.
void setHeight(qreal height)
void setViewportSize(const QSize &size) const
double findNearbyPageBreak(double yPos) override
Finds the optimal position to break a frame at.
QString toString() const
void setNetworkAccessManager(QNetworkAccessManager *manager)
void handleFrameRemoval(QgsComposerItem *item)
Called before a frame is going to be removed.
QWebPage subclass which redirects JavaScript errors and console output to the QGIS message log...
Definition: qgswebpage.h:199
iterator begin()
void setEllipsoidalMode(bool flag)
Sets whether coordinates must be projected to ellipsoid before measuring.
QUrl fromLocalFile(const QString &localFile)
The QWebSettings class is a collection of stubs to mimic the API of a QWebSettings on systems where Q...
Definition: qgswebpage.h:37
void render(QPainter *p, const QRectF &renderExtent, const int frameIndex) override
Renders a portion of the multiframe&#39;s content into a painter.
void changed()
Emitted when the properties of a multi frame have changed, and the GUI item widget must be updated...
QByteArray toUtf8() const