QGIS API Documentation
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 
29 #include "qgswebpage.h"
30 #include "qgswebframe.h"
31 
32 #include <QCoreApplication>
33 #include <QPainter>
34 #include <QImage>
35 #include <QNetworkReply>
36 
37 QgsComposerHtml::QgsComposerHtml( QgsComposition* c, bool createUndoCommands )
38  : QgsComposerMultiFrame( c, createUndoCommands )
39  , mContentMode( QgsComposerHtml::Url )
40  , mWebPage( nullptr )
41  , mLoaded( false )
42  , mHtmlUnitsToMM( 1.0 )
43  , mRenderedPage( nullptr )
44  , mEvaluateExpressions( true )
45  , mUseSmartBreaks( true )
46  , mMaxBreakDistance( 10 )
47  , mExpressionLayer( nullptr )
48  , mDistanceArea( nullptr )
49  , mEnableUserStylesheet( false )
50  , mFetcher( nullptr )
51 {
52  mDistanceArea = new QgsDistanceArea();
53  mHtmlUnitsToMM = htmlUnitsToMM();
54  mWebPage = new QWebPage();
55  mWebPage->mainFrame()->setScrollBarPolicy( Qt::Horizontal, Qt::ScrollBarAlwaysOff );
56  mWebPage->mainFrame()->setScrollBarPolicy( Qt::Vertical, Qt::ScrollBarAlwaysOff );
57 
58  //This makes the background transparent. Found on http://blog.qt.digia.com/blog/2009/06/30/transparent-qwebview-or-qwebpage/
59  QPalette palette = mWebPage->palette();
60  palette.setBrush( QPalette::Base, Qt::transparent );
61  mWebPage->setPalette( palette );
62 
64  QObject::connect( mWebPage, SIGNAL( loadFinished( bool ) ), this, SLOT( frameLoaded( bool ) ) );
65  if ( mComposition )
66  {
67  QObject::connect( mComposition, SIGNAL( itemRemoved( QgsComposerItem* ) ), this, SLOT( handleFrameRemoval( QgsComposerItem* ) ) );
68  }
69 
70  // data defined strings
71  mDataDefinedNames.insert( QgsComposerObject::SourceUrl, QString( "dataDefinedSourceUrl" ) );
72 
74  {
75  //a html item added while atlas preview is enabled needs to have the expression context set,
76  //otherwise fields in the html aren't correctly evaluated until atlas preview feature changes (#9457)
78  }
79 
80  //connect to atlas feature changes
81  //to update the expression context
82  connect( &mComposition->atlasComposition(), SIGNAL( featureChanged( QgsFeature* ) ), this, SLOT( refreshExpressionContext() ) );
83 
84  mFetcher = new QgsNetworkContentFetcher();
85  connect( mFetcher, SIGNAL( finished() ), this, SLOT( frameLoaded() ) );
86 
87 }
88 
90 {
91  delete mDistanceArea;
92  delete mWebPage;
93  delete mRenderedPage;
94  mFetcher->deleteLater();
95 }
96 
98 {
99  if ( !mWebPage )
100  {
101  return;
102  }
103 
104  mUrl = url;
105  loadHtml( true );
106  emit changed();
107 }
108 
110 {
111  mHtml = html;
112  //TODO - this signal should be emitted, but without changing the signal which sets the html
113  //to an equivalent of editingFinished it causes a lot of problems. Need to investigate
114  //ways of doing this using QScintilla widgets.
115  //emit changed();
116 }
117 
119 {
120  mEvaluateExpressions = evaluateExpressions;
121  loadHtml( true );
122  emit changed();
123 }
124 
125 void QgsComposerHtml::loadHtml( const bool useCache, const QgsExpressionContext *context )
126 {
127  if ( !mWebPage )
128  {
129  return;
130  }
131 
132  const QgsExpressionContext* evalContext = context;
134  if ( !evalContext )
135  {
136  scopedContext.reset( createExpressionContext() );
137  evalContext = scopedContext.data();
138  }
139 
140  QString loadedHtml;
141  switch ( mContentMode )
142  {
144  {
145 
146  QString currentUrl = mUrl.toString();
147 
148  //data defined url set?
149  QVariant exprVal;
150  if ( dataDefinedEvaluate( QgsComposerObject::SourceUrl, exprVal, *evalContext ) )
151  {
152  currentUrl = exprVal.toString().trimmed();
153  QgsDebugMsg( QString( "exprVal Source Url:%1" ).arg( currentUrl ) );
154  }
155  if ( currentUrl.isEmpty() )
156  {
157  return;
158  }
159  if ( !( useCache && currentUrl == mLastFetchedUrl ) )
160  {
161  loadedHtml = fetchHtml( QUrl( currentUrl ) );
162  mLastFetchedUrl = currentUrl;
163  }
164  else
165  {
166  loadedHtml = mFetchedHtml;
167  }
168 
169  break;
170  }
172  loadedHtml = mHtml;
173  break;
174  }
175 
176  //evaluate expressions
177  if ( mEvaluateExpressions )
178  {
179  loadedHtml = QgsExpression::replaceExpressionText( loadedHtml, evalContext, nullptr, mDistanceArea );
180  }
181 
182  mLoaded = false;
183 
184  //reset page size. otherwise viewport size increases but never decreases again
185  mWebPage->setViewportSize( QSize( maxFrameWidth() * mHtmlUnitsToMM, 0 ) );
186 
187  //set html, using the specified url as base if in Url mode or the project file if in manual mode
188  const QUrl baseUrl = mContentMode == QgsComposerHtml::Url ?
189  QUrl( mActualFetchedUrl ) :
190  QUrl::fromLocalFile( QgsProject::instance()->fileInfo().absoluteFilePath() );
191  mWebPage->mainFrame()->setHtml( loadedHtml, baseUrl );
192 
193  //set user stylesheet
194  QWebSettings* settings = mWebPage->settings();
195  if ( mEnableUserStylesheet && ! mUserStylesheet.isEmpty() )
196  {
197  QByteArray ba;
198  ba.append( mUserStylesheet.toUtf8() );
199  QUrl cssFileURL = QUrl( "data:text/css;charset=utf-8;base64," + ba.toBase64() );
200  settings->setUserStyleSheetUrl( cssFileURL );
201  }
202  else
203  {
204  settings->setUserStyleSheetUrl( QUrl() );
205  }
206 
207  while ( !mLoaded )
208  {
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;
227  for ( ; frameIt != mFrameItems.constEnd(); ++frameIt )
228  {
229  maxWidth = qMax( 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 );
327  QObject::connect( frame, SIGNAL( sizeChanged() ), this, SLOT( recalculateFrameSizes() ) );
328  if ( mComposition )
329  {
330  mComposition->addComposerHtmlFrame( this, frame );
331  }
332 
333  if ( recalcFrameSizes )
334  {
336  }
337 }
338 
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 = qMax( 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  qSort( 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 
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( "ComposerHtml" );
473  htmlElem.setAttribute( "contentMode", QString::number( static_cast< int >( mContentMode ) ) );
474  htmlElem.setAttribute( "url", mUrl.toString() );
475  htmlElem.setAttribute( "html", mHtml );
476  htmlElem.setAttribute( "evaluateExpressions", mEvaluateExpressions ? "true" : "false" );
477  htmlElem.setAttribute( "useSmartBreaks", mUseSmartBreaks ? "true" : "false" );
478  htmlElem.setAttribute( "maxBreakDistance", QString::number( mMaxBreakDistance ) );
479  htmlElem.setAttribute( "stylesheet", mUserStylesheet );
480  htmlElem.setAttribute( "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( "contentMode" ).toInt( &contentModeOK ) );
502  if ( !contentModeOK )
503  {
504  mContentMode = QgsComposerHtml::Url;
505  }
506  mEvaluateExpressions = itemElem.attribute( "evaluateExpressions", "true" ) == "true" ? true : false;
507  mUseSmartBreaks = itemElem.attribute( "useSmartBreaks", "true" ) == "true" ? true : false;
508  mMaxBreakDistance = itemElem.attribute( "maxBreakDistance", "10" ).toDouble();
509  mHtml = itemElem.attribute( "html" );
510  mUserStylesheet = itemElem.attribute( "stylesheet" );
511  mEnableUserStylesheet = itemElem.attribute( "stylesheetEnabled", "false" ) == "true" ? true : false;
512 
513  //finally load the set url
514  QString urlString = itemElem.attribute( "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().srsid() );
535  }
536  else if ( mComposition )
537  {
538  //set to composition's mapsettings' crs
539  mDistanceArea->setSourceCrs( mComposition->mapSettings().destinationCrs().srsid() );
540  }
541  if ( mComposition )
542  {
544  }
545  mDistanceArea->setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );
546 }
547 
549 {
550  QgsVectorLayer * vl = nullptr;
551  QgsFeature feature;
552 
554  {
556  }
558  {
559  feature = mComposition->atlasComposition().feature();
560  }
561 
562  setExpressionContext( feature, vl );
563  loadHtml( true );
564 }
565 
567 {
568  const QgsExpressionContext* evalContext = context;
570  if ( !evalContext )
571  {
572  scopedContext.reset( createExpressionContext() );
573  evalContext = scopedContext.data();
574  }
575 
576  //updates data defined properties and redraws item to match
577  if ( property == QgsComposerObject::SourceUrl || property == QgsComposerObject::AllProperties )
578  {
579  loadHtml( true, evalContext );
580  }
582 }
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)
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
QString toString(QFlags< QUrl::FormattingOption > options) const
QString tr(const char *sourceText, const char *disambiguation, int n)
qreal left() const
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...
The QWebPage class is a collection of stubs to mimic the API of a QWebPage on systems where QtWebkit ...
Definition: qgswebpage.h:99
void setUseSmartBreaks(bool useSmartBreaks)
Sets whether the html item should use smart breaks.
void deleteLater()
T & first()
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()
access to canonical QgsProject instance
Definition: qgsproject.cpp:388
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
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.
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:36
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