QGIS API Documentation  2.99.0-Master (dc72e14)
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 #include "qgsmapsettings.h"
30 #include "qgscomposermap.h"
31 
32 #include "qgswebpage.h"
33 #include "qgswebframe.h"
34 
35 #include <QCoreApplication>
36 #include <QPainter>
37 #include <QImage>
38 #include <QNetworkReply>
39 
40 QgsComposerHtml::QgsComposerHtml( QgsComposition *c, bool createUndoCommands )
41  : QgsComposerMultiFrame( c, createUndoCommands )
42  , mContentMode( QgsComposerHtml::Url )
43  , mLoaded( false )
44  , mHtmlUnitsToMM( 1.0 )
45  , mEvaluateExpressions( true )
46  , mUseSmartBreaks( true )
47  , mMaxBreakDistance( 10 )
48  , mEnableUserStylesheet( false )
49 {
50  mDistanceArea = new QgsDistanceArea();
51  mHtmlUnitsToMM = htmlUnitsToMM();
52  mWebPage = new QgsWebPage();
53  mWebPage->setIdentifier( tr( "Composer HTML item" ) );
54  mWebPage->mainFrame()->setScrollBarPolicy( Qt::Horizontal, Qt::ScrollBarAlwaysOff );
55  mWebPage->mainFrame()->setScrollBarPolicy( Qt::Vertical, Qt::ScrollBarAlwaysOff );
56 
57  //This makes the background transparent. Found on http://blog.qt.digia.com/blog/2009/06/30/transparent-qwebview-or-qwebpage/
58  QPalette palette = mWebPage->palette();
59  palette.setBrush( QPalette::Base, Qt::transparent );
60  mWebPage->setPalette( palette );
61 
62  mWebPage->setNetworkAccessManager( QgsNetworkAccessManager::instance() );
63  connect( mWebPage, &QWebPage::loadFinished, this, &QgsComposerHtml::frameLoaded );
64  if ( mComposition )
65  {
67  }
68 
70  {
71  //a html item added while atlas preview is enabled needs to have the expression context set,
72  //otherwise fields in the html aren't correctly evaluated until atlas preview feature changes (#9457)
74  }
75 
76  //connect to atlas feature changes
77  //to update the expression context
79 
80  mFetcher = new QgsNetworkContentFetcher();
81  connect( mFetcher, &QgsNetworkContentFetcher::finished, this, [ = ] { frameLoaded(); } );
82 
83 }
84 
86 {
87  delete mDistanceArea;
88  delete mWebPage;
89  delete mRenderedPage;
90  mFetcher->deleteLater();
91 }
92 
93 void QgsComposerHtml::setUrl( const QUrl &url )
94 {
95  if ( !mWebPage )
96  {
97  return;
98  }
99 
100  mUrl = url;
101  loadHtml( true );
102  emit changed();
103 }
104 
105 void QgsComposerHtml::setHtml( const QString &html )
106 {
107  mHtml = html;
108  //TODO - this signal should be emitted, but without changing the signal which sets the html
109  //to an equivalent of editingFinished it causes a lot of problems. Need to investigate
110  //ways of doing this using QScintilla widgets.
111  //emit changed();
112 }
113 
115 {
116  mEvaluateExpressions = evaluateExpressions;
117  loadHtml( true );
118  emit changed();
119 }
120 
121 void QgsComposerHtml::loadHtml( const bool useCache, const QgsExpressionContext *context )
122 {
123  if ( !mWebPage )
124  {
125  return;
126  }
127 
129  const QgsExpressionContext *evalContext = context ? context : &scopedContext;
130 
131  QString loadedHtml;
132  switch ( mContentMode )
133  {
135  {
136 
137  QString currentUrl = mUrl.toString();
138 
139  //data defined url set?
140  bool ok = false;
141  currentUrl = mDataDefinedProperties.valueAsString( QgsComposerObject::SourceUrl, *evalContext, currentUrl, &ok );
142  if ( ok )
143  {
144  currentUrl = currentUrl.trimmed();
145  QgsDebugMsg( QString( "exprVal Source Url:%1" ).arg( currentUrl ) );
146  }
147  if ( currentUrl.isEmpty() )
148  {
149  return;
150  }
151  if ( !( useCache && currentUrl == mLastFetchedUrl ) )
152  {
153  loadedHtml = fetchHtml( QUrl( currentUrl ) );
154  mLastFetchedUrl = currentUrl;
155  }
156  else
157  {
158  loadedHtml = mFetchedHtml;
159  }
160 
161  break;
162  }
164  loadedHtml = mHtml;
165  break;
166  }
167 
168  //evaluate expressions
169  if ( mEvaluateExpressions )
170  {
171  loadedHtml = QgsExpression::replaceExpressionText( loadedHtml, evalContext, mDistanceArea );
172  }
173 
174  mLoaded = false;
175 
176  //reset page size. otherwise viewport size increases but never decreases again
177  mWebPage->setViewportSize( QSize( maxFrameWidth() * mHtmlUnitsToMM, 0 ) );
178 
179  //set html, using the specified url as base if in Url mode or the project file if in manual mode
180  const QUrl baseUrl = mContentMode == QgsComposerHtml::Url ?
181  QUrl( mActualFetchedUrl ) :
182  QUrl::fromLocalFile( mComposition->project()->fileInfo().absoluteFilePath() );
183  mWebPage->mainFrame()->setHtml( loadedHtml, baseUrl );
184 
185  //set user stylesheet
186  QWebSettings *settings = mWebPage->settings();
187  if ( mEnableUserStylesheet && ! mUserStylesheet.isEmpty() )
188  {
189  QByteArray ba;
190  ba.append( mUserStylesheet.toUtf8() );
191  QUrl cssFileURL = QUrl( "data:text/css;charset=utf-8;base64," + ba.toBase64() );
192  settings->setUserStyleSheetUrl( cssFileURL );
193  }
194  else
195  {
196  settings->setUserStyleSheetUrl( QUrl() );
197  }
198 
199  while ( !mLoaded )
200  {
201  qApp->processEvents();
202  }
203 
204  //inject JSON feature
205  if ( !mAtlasFeatureJSON.isEmpty() )
206  {
207  mWebPage->mainFrame()->evaluateJavaScript( QStringLiteral( "if ( typeof setFeature === \"function\" ) { setFeature(%1); }" ).arg( mAtlasFeatureJSON ) );
208  //needs an extra process events here to give JavaScript a chance to execute
209  qApp->processEvents();
210  }
211 
213  //trigger a repaint
214  emit contentsChanged();
215 }
216 
217 void QgsComposerHtml::frameLoaded( bool ok )
218 {
219  Q_UNUSED( ok );
220  mLoaded = true;
221 }
222 
223 double QgsComposerHtml::maxFrameWidth() const
224 {
225  double maxWidth = 0;
226  QList<QgsComposerFrame *>::const_iterator frameIt = mFrameItems.constBegin();
227  for ( ; frameIt != mFrameItems.constEnd(); ++frameIt )
228  {
229  maxWidth = std::max( maxWidth, static_cast< double >( ( *frameIt )->boundingRect().width() ) );
230  }
231 
232  return maxWidth;
233 }
234 
236 {
237  if ( frameCount() < 1 ) return;
238 
239  QSize contentsSize = mWebPage->mainFrame()->contentsSize();
240 
241  //find maximum frame width
242  double maxWidth = maxFrameWidth();
243  //set content width to match maximum frame width
244  contentsSize.setWidth( maxWidth * mHtmlUnitsToMM );
245 
246  mWebPage->setViewportSize( contentsSize );
247  mSize.setWidth( contentsSize.width() / mHtmlUnitsToMM );
248  mSize.setHeight( contentsSize.height() / mHtmlUnitsToMM );
249  if ( contentsSize.isValid() )
250  {
251  renderCachedImage();
252  }
254  emit changed();
255 }
256 
257 void QgsComposerHtml::renderCachedImage()
258 {
259  //render page to cache image
260  if ( mRenderedPage )
261  {
262  delete mRenderedPage;
263  }
264  mRenderedPage = new QImage( mWebPage->viewportSize(), QImage::Format_ARGB32 );
265  if ( mRenderedPage->isNull() )
266  {
267  return;
268  }
269  mRenderedPage->fill( Qt::transparent );
270  QPainter painter;
271  painter.begin( mRenderedPage );
272  mWebPage->mainFrame()->render( &painter );
273  painter.end();
274 }
275 
276 QString QgsComposerHtml::fetchHtml( const QUrl &url )
277 {
278  //pause until HTML fetch
279  mLoaded = false;
280  mFetcher->fetchContent( url );
281 
282  while ( !mLoaded )
283  {
284  qApp->processEvents();
285  }
286 
287  mFetchedHtml = mFetcher->contentAsString();
288  mActualFetchedUrl = mFetcher->reply()->url().toString();
289  return mFetchedHtml;
290 }
291 
293 {
294  return mSize;
295 }
296 
297 void QgsComposerHtml::render( QPainter *p, const QRectF &renderExtent, const int frameIndex )
298 {
299  Q_UNUSED( frameIndex );
300 
301  if ( !mWebPage )
302  {
303  return;
304  }
305 
306  p->save();
307  p->setRenderHint( QPainter::Antialiasing );
308  p->scale( 1.0 / mHtmlUnitsToMM, 1.0 / mHtmlUnitsToMM );
309  p->translate( 0.0, -renderExtent.top() * mHtmlUnitsToMM );
310  mWebPage->mainFrame()->render( p, QRegion( renderExtent.left(), renderExtent.top() * mHtmlUnitsToMM, renderExtent.width() * mHtmlUnitsToMM, renderExtent.height() * mHtmlUnitsToMM ) );
311  p->restore();
312 }
313 
314 double QgsComposerHtml::htmlUnitsToMM()
315 {
316  if ( !mComposition )
317  {
318  return 1.0;
319  }
320 
321  return ( mComposition->printResolution() / 72.0 ); //webkit seems to assume a standard dpi of 96
322 }
323 
324 void QgsComposerHtml::addFrame( QgsComposerFrame *frame, bool recalcFrameSizes )
325 {
326  mFrameItems.push_back( frame );
328  if ( mComposition )
329  {
330  mComposition->addComposerHtmlFrame( this, frame );
331  }
332 
333  if ( recalcFrameSizes )
334  {
336  }
337 }
338 
339 bool candidateSort( QPair<int, int> c1, QPair<int, int> c2 )
340 {
341  if ( c1.second < c2.second )
342  return true;
343  else if ( c1.second > c2.second )
344  return false;
345  else if ( c1.first > c2.first )
346  return true;
347  else
348  return false;
349 }
350 
352 {
353  if ( !mWebPage || !mRenderedPage || !mUseSmartBreaks )
354  {
355  return yPos;
356  }
357 
358  //convert yPos to pixels
359  int idealPos = yPos * htmlUnitsToMM();
360 
361  //if ideal break pos is past end of page, there's nothing we need to do
362  if ( idealPos >= mRenderedPage->height() )
363  {
364  return yPos;
365  }
366 
367  int maxSearchDistance = mMaxBreakDistance * htmlUnitsToMM();
368 
369  //loop through all lines just before ideal break location, up to max distance
370  //of maxSearchDistance
371  int changes = 0;
372  QRgb currentColor;
373  bool currentPixelTransparent = false;
374  bool previousPixelTransparent = false;
375  QRgb pixelColor;
376  QList< QPair<int, int> > candidates;
377  int minRow = std::max( idealPos - maxSearchDistance, 0 );
378  for ( int candidateRow = idealPos; candidateRow >= minRow; --candidateRow )
379  {
380  changes = 0;
381  currentColor = qRgba( 0, 0, 0, 0 );
382  //check all pixels in this line
383  for ( int col = 0; col < mRenderedPage->width(); ++col )
384  {
385  //count how many times the pixels change color in this row
386  //eventually, we select a row to break at with the minimum number of color changes
387  //since this is likely a line break, or gap between table cells, etc
388  //but very unlikely to be midway through a text line or picture
389  pixelColor = mRenderedPage->pixel( col, candidateRow );
390  currentPixelTransparent = qAlpha( pixelColor ) == 0;
391  if ( pixelColor != currentColor && !( currentPixelTransparent && previousPixelTransparent ) )
392  {
393  //color has changed
394  currentColor = pixelColor;
395  changes++;
396  }
397  previousPixelTransparent = currentPixelTransparent;
398  }
399  candidates.append( qMakePair( candidateRow, changes ) );
400  }
401 
402  //sort candidate rows by number of changes ascending, row number descending
403  std::sort( candidates.begin(), candidates.end(), candidateSort );
404  //first candidate is now the largest row with smallest number of changes
405 
406  //OK, now take the mid point of the best candidate position
407  //we do this so that the spacing between text lines is likely to be split in half
408  //otherwise the html will be broken immediately above a line of text, which
409  //looks a little messy
410  int maxCandidateRow = candidates[0].first;
411  int minCandidateRow = maxCandidateRow + 1;
412  int minCandidateChanges = candidates[0].second;
413 
414  QList< QPair<int, int> >::iterator it;
415  for ( it = candidates.begin(); it != candidates.end(); ++it )
416  {
417  if ( ( *it ).second != minCandidateChanges || ( *it ).first != minCandidateRow - 1 )
418  {
419  //no longer in a consecutive block of rows of minimum pixel color changes
420  //so return the row mid-way through the block
421  //first converting back to mm
422  return ( minCandidateRow + ( maxCandidateRow - minCandidateRow ) / 2 ) / htmlUnitsToMM();
423  }
424  minCandidateRow = ( *it ).first;
425  }
426 
427  //above loop didn't work for some reason
428  //return first candidate converted to mm
429  return candidates[0].first / htmlUnitsToMM();
430 }
431 
433 {
434  mUseSmartBreaks = useSmartBreaks;
436  emit changed();
437 }
438 
440 {
441  mMaxBreakDistance = maxBreakDistance;
443  emit changed();
444 }
445 
446 void QgsComposerHtml::setUserStylesheet( const QString &stylesheet )
447 {
448  mUserStylesheet = stylesheet;
449  //TODO - this signal should be emitted, but without changing the signal which sets the css
450  //to an equivalent of editingFinished it causes a lot of problems. Need to investigate
451  //ways of doing this using QScintilla widgets.
452  //emit changed();
453 }
454 
455 void QgsComposerHtml::setUserStylesheetEnabled( const bool stylesheetEnabled )
456 {
457  if ( mEnableUserStylesheet != stylesheetEnabled )
458  {
459  mEnableUserStylesheet = stylesheetEnabled;
460  loadHtml( true );
461  emit changed();
462  }
463 }
464 
466 {
467  return tr( "<HTML frame>" );
468 }
469 
470 bool QgsComposerHtml::writeXml( QDomElement &elem, QDomDocument &doc, bool ignoreFrames ) const
471 {
472  QDomElement htmlElem = doc.createElement( QStringLiteral( "ComposerHtml" ) );
473  htmlElem.setAttribute( QStringLiteral( "contentMode" ), QString::number( static_cast< int >( mContentMode ) ) );
474  htmlElem.setAttribute( QStringLiteral( "url" ), mUrl.toString() );
475  htmlElem.setAttribute( QStringLiteral( "html" ), mHtml );
476  htmlElem.setAttribute( QStringLiteral( "evaluateExpressions" ), mEvaluateExpressions ? "true" : "false" );
477  htmlElem.setAttribute( QStringLiteral( "useSmartBreaks" ), mUseSmartBreaks ? "true" : "false" );
478  htmlElem.setAttribute( QStringLiteral( "maxBreakDistance" ), QString::number( mMaxBreakDistance ) );
479  htmlElem.setAttribute( QStringLiteral( "stylesheet" ), mUserStylesheet );
480  htmlElem.setAttribute( QStringLiteral( "stylesheetEnabled" ), mEnableUserStylesheet ? "true" : "false" );
481 
482  bool state = _writeXml( htmlElem, doc, ignoreFrames );
483  elem.appendChild( htmlElem );
484  return state;
485 }
486 
487 bool QgsComposerHtml::readXml( const QDomElement &itemElem, const QDomDocument &doc, bool ignoreFrames )
488 {
489  if ( !ignoreFrames )
490  {
491  deleteFrames();
492  }
493 
494  //first create the frames
495  if ( !_readXml( itemElem, doc, ignoreFrames ) )
496  {
497  return false;
498  }
499 
500  bool contentModeOK;
501  mContentMode = static_cast< QgsComposerHtml::ContentMode >( itemElem.attribute( QStringLiteral( "contentMode" ) ).toInt( &contentModeOK ) );
502  if ( !contentModeOK )
503  {
504  mContentMode = QgsComposerHtml::Url;
505  }
506  mEvaluateExpressions = itemElem.attribute( QStringLiteral( "evaluateExpressions" ), QStringLiteral( "true" ) ) == QLatin1String( "true" );
507  mUseSmartBreaks = itemElem.attribute( QStringLiteral( "useSmartBreaks" ), QStringLiteral( "true" ) ) == QLatin1String( "true" );
508  mMaxBreakDistance = itemElem.attribute( QStringLiteral( "maxBreakDistance" ), QStringLiteral( "10" ) ).toDouble();
509  mHtml = itemElem.attribute( QStringLiteral( "html" ) );
510  mUserStylesheet = itemElem.attribute( QStringLiteral( "stylesheet" ) );
511  mEnableUserStylesheet = itemElem.attribute( QStringLiteral( "stylesheetEnabled" ), QStringLiteral( "false" ) ) == QLatin1String( "true" );
512 
513  //finally load the set url
514  QString urlString = itemElem.attribute( QStringLiteral( "url" ) );
515  if ( !urlString.isEmpty() )
516  {
517  mUrl = urlString;
518  }
519  loadHtml( true );
520 
521  //since frames had to be created before, we need to emit a changed signal to refresh the widget
522  emit changed();
523  return true;
524 }
525 
526 void QgsComposerHtml::setExpressionContext( const QgsFeature &feature, QgsVectorLayer *layer )
527 {
528  mExpressionFeature = feature;
529  mExpressionLayer = layer;
530 
531  //setup distance area conversion
532  if ( layer )
533  {
534  mDistanceArea->setSourceCrs( layer->crs() );
535  }
536  else if ( mComposition )
537  {
538  //set to composition's mapsettings' crs
539  QgsComposerMap *referenceMap = mComposition->referenceMap();
540  if ( referenceMap )
541  mDistanceArea->setSourceCrs( referenceMap->crs() );
542  }
543  if ( mComposition )
544  {
545  mDistanceArea->setEllipsoid( mComposition->project()->ellipsoid() );
546  }
547 
548  // create JSON representation of feature
549  QgsJsonExporter exporter( layer );
550  exporter.setIncludeRelated( true );
551  mAtlasFeatureJSON = exporter.exportFeature( feature );
552 }
553 
555 {
556  QgsVectorLayer *vl = nullptr;
557  QgsFeature feature;
558 
560  {
562  }
564  {
565  feature = mComposition->atlasComposition().feature();
566  }
567 
568  setExpressionContext( feature, vl );
569  loadHtml( true );
570 }
571 
573 {
575  const QgsExpressionContext *evalContext = context ? context : &scopedContext;
576 
577 
578  //updates data defined properties and redraws item to match
579  if ( property == QgsComposerObject::SourceUrl || property == QgsComposerObject::AllProperties )
580  {
581  loadHtml( true, evalContext );
582  }
584 }
virtual void recalculateFrameSizes()
Recalculates the portion of the multiframe item which is shown in each of it&#39;s component frames...
virtual QgsExpressionContext createExpressionContext() const
Creates an expression context relating to the objects&#39; current state.
void setIdentifier(const QString &identifier)
Sets an identifier for the QgsWebPage.
Definition: qgswebpage.h:233
HTML content is manually set for the item.
#define QgsDebugMsg(str)
Definition: qgslogger.h:37
virtual QString displayName() const override
Get multiframe display name.
int printResolution() const
The QWebSettings class is a collection of stubs to mimic the API of a QWebSettings on systems where Q...
Definition: qgswebpage.h:41
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...
QUrl url() const
Returns the URL of the content displayed in the item if the item is using the QgsComposerHtml::Url mo...
bool writeXml(QDomElement &elem, QDomDocument &doc, bool ignoreFrames=false) const override
Stores state information about multiframe in DOM element.
Using this mode item fetches its content via a url.
QgsComposerHtml(QgsComposition *c, bool createUndoCommands)
QNetworkReply * reply()
Returns a reference to the network reply.
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
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:61
QString ellipsoid
Definition: qgsproject.h:86
double maxBreakDistance() const
Returns the maximum distance allowed when calculating where to place page breaks in the html...
QString contentAsString() const
Returns the fetched content as a string.
QgsComposition::AtlasMode atlasMode() const
Returns the current atlas mode of the composition.
DataDefinedProperty
Data defined properties for different item types.
QSizeF totalSize() const override
Returns the total size of the multiframe&#39;s content.
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...
HTTP network content fetcher.
bool _readXml(const QDomElement &itemElem, const QDomDocument &doc, bool ignoreFrames=false)
Restores state information about base multiframe object from a DOM element.
void itemRemoved(QgsComposerItem *)
Is emitted when a composer item has been removed from the scene.
QgsComposerMap * referenceMap() const
Returns the map item which will be used to generate corresponding world files when the composition is...
bool useSmartBreaks() const
Returns whether html item is using smart breaks.
void recalculateFrameSizes() override
Recalculates the frame sizes for the current viewport dimensions.
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.
void setIncludeRelated(bool includeRelated)
Sets whether to include attributes of features linked via references in the JSON exports.
Definition: qgsjsonutils.h:88
void setMaxBreakDistance(double maxBreakDistance)
Sets the maximum distance allowed when calculating where to place page breaks in the html...
void finished()
Emitted when content has loaded.
QgsCoordinateReferenceSystem crs() const
Returns the layer&#39;s spatial reference system.
QgsPropertyCollection mDataDefinedProperties
void setUseSmartBreaks(bool useSmartBreaks)
Sets whether the html item should use smart breaks.
bool evaluateExpressions() const
Returns whether html item will evaluate QGIS expressions prior to rendering the HTML content...
QString html() const
Returns the HTML source displayed in the item if the item is using the QgsComposerHtml::ManualHtml mo...
Graphics scene for map printing.
bool readXml(const QDomElement &itemElem, const QDomDocument &doc, bool ignoreFrames=false) override
Reads multiframe state information from a DOM element.
Object representing map window.
Frame item for a composer multiframe item.
void featureChanged(QgsFeature *feature)
Is emitted when the current atlas feature changes.
Handles exporting QgsFeature features to GeoJSON features.
Definition: qgsjsonutils.h:37
bool _writeXml(QDomElement &elem, QDomDocument &doc, bool ignoreFrames=false) const
Stores state information about base multiframe object in DOM element.
A general purpose distance and area calculator, capable of performing ellipsoid based calculations...
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()
QgsCoordinateReferenceSystem crs() const
Returns coordinate reference system used for rendering the map.
QFileInfo fileInfo() const
Returns QFileInfo object for the project&#39;s associated file.
Definition: qgsproject.cpp:439
void contentsChanged()
Emitted when the contents of the multi frame have changed and the frames must be redrawn.
static QgsNetworkAccessManager * instance()
returns a pointer to the single instance
int frameCount() const
Returns the number of frames associated with this multiframe.
QgsProject * project() const
The project associated with the composition.
QString valueAsString(int key, const QgsExpressionContext &context, const QString &defaultString=QString(), bool *ok=0) const
Calculates the current value of the property with the specified key and interprets it as a string...
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...
void sizeChanged()
Emitted if the rectangle changes.
QList< QgsComposerFrame * > mFrameItems
bool candidateSort(QPair< int, int > c1, QPair< int, int > c2)
int frameIndex(QgsComposerFrame *frame) const
Returns the index of a frame within the multiframe.
QgsVectorLayer * coverageLayer() const
Returns the coverage layer used for the atlas features.
QgsAtlasComposition & atlasComposition()
QgsFeature feature() const
Returns the current atlas feature.
void setSourceCrs(const QgsCoordinateReferenceSystem &srcCRS)
Sets source spatial reference system.
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.
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.
ContentMode
Source modes for the HTML content to render in the item.
double findNearbyPageBreak(double yPos) override
Finds the optimal position to break a frame at.
QgsComposerFrame * frame(int i) const
Returns a child frame from the multiframe.
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:214
bool enabled() const
Returns whether the atlas generation is enabled.
All properties for item.
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...