38#include <QDesktopServices> 
   47const QString QgsMapTip::sMapTipTemplate = 
"<html>\n" 
   52    "        font: %1pt \"%2\";\n" 
   56    "    #QgsWebViewContainer {\n" 
   57    "        background-color: %5;\n" 
   58    "        border: 1px solid %6;\n" 
   59    "        display: inline-block;\n" 
   62    "    #QgsWebViewContainerInner {\n" 
   68    "    <div id='QgsWebViewContainer'>\n" 
   69    "      <div id='QgsWebViewContainerInner'>\n" 
   80  mMapTipVisible = 
false;
 
   82  mDelayedClearTimer.setSingleShot( 
true );
 
   83  connect( &mDelayedClearTimer, &QTimer::timeout, 
this, [ = ]() {this->
clear();} );
 
   88                            const QPoint &pixelPosition,
 
   98  if ( !pMapCanvas->
layers( 
true ).contains( pLayer ) )
 
  104  if ( mWebView && mWebView->underMouse() )
 
  110  QString tipText, lastTipText, tipHtml;
 
  116    mWebView->setStyleSheet( QStringLiteral( 
"background:transparent;" ) );
 
  120    mWebView->page()->setLinkDelegationPolicy( QWebPage::DelegateAllLinks );
 
  121    mWebView->setContextMenuPolicy( Qt::NoContextMenu ); 
 
  122    connect( mWebView, &QWebView::linkClicked, 
this, &QgsMapTip::onLinkClicked );
 
  123    connect( mWebView, &QWebView::loadFinished, 
this, [ = ]( 
bool ) { resizeAndMoveToolTip(); } );
 
  126    mWebView->page()->settings()->setAttribute( QWebSettings::DeveloperExtrasEnabled, 
true );
 
  127    mWebView->page()->settings()->setAttribute( QWebSettings::JavascriptEnabled, 
true );
 
  128    mWebView->page()->settings()->setAttribute( QWebSettings::LocalStorageEnabled, 
true );
 
  131    mWebView->page()->mainFrame()->setScrollBarPolicy( Qt::Horizontal, Qt::ScrollBarAlwaysOff );
 
  132    mWebView->page()->mainFrame()->setScrollBarPolicy( Qt::Vertical, Qt::ScrollBarAlwaysOff );
 
  137  switch ( pLayer->
type() )
 
  139    case Qgis::LayerType::Vector:
 
  140      tipText = fetchFeature( pLayer, mapPosition, pMapCanvas );
 
  142    case Qgis::LayerType::Raster:
 
  143      tipText = fetchRaster( pLayer, mapPosition, pMapCanvas );
 
  149  mMapTipVisible = !tipText.isEmpty();
 
  150  if ( !mMapTipVisible )
 
  156  if ( tipText == lastTipText )
 
  162  int cursorOffset = 0;
 
  169    cursorOffset = 
static_cast< int >( std::ceil( scale * 32 ) );
 
  173  const int MAX_WIDTH = pMapCanvas->width() / 2 - cursorOffset;
 
  174  const int MAX_HEIGHT = pMapCanvas->height() / 2;
 
  176  mWebView->setMaximumSize( MAX_WIDTH, MAX_HEIGHT );
 
  178  tipHtml = QgsMapTip::htmlText( tipText, MAX_WIDTH );
 
  182  mPosition = pixelPosition;
 
  183  mMapCanvas = pMapCanvas;
 
  184  mWebView->setHtml( tipHtml );
 
  185  lastTipText = tipText;
 
  188  resizeAndMoveToolTip();
 
  193void QgsMapTip::resizeAndMoveToolTip()
 
  197  const QWebElement container = mWebView->page()->mainFrame()->findFirstElement(
 
  198                                  QStringLiteral( 
"#QgsWebViewContainer" ) );
 
  199  const int width = container.geometry().width();
 
  200  const int height = container.geometry().height();
 
  201  mWebView->resize( width, height );
 
  203  mWebView->adjustSize();
 
  206  int cursorOffset = 0;
 
  214    cursorOffset = 
static_cast< int >( std::ceil( scale * 32 ) );
 
  217  if ( mMapCanvas == 
nullptr )
 
  219    mWebView->move( mPosition );
 
  225  int availableWidthRight = mMapCanvas->width() - mPosition.x() - cursorOffset;
 
  226  int availableWidthLeft = mPosition.x() - cursorOffset;
 
  227  int availableHeightBottom = mMapCanvas->height() - mPosition.y();
 
  228  int availableHeightTop = mPosition.y();
 
  231  if ( mWebView->width() < availableWidthRight || availableWidthRight > availableWidthLeft )
 
  233    x = mPosition.x() + cursorOffset;
 
  238    x = mPosition.x() - mWebView->width() - cursorOffset;
 
  242  if ( mWebView->height() < availableHeightBottom || availableHeightBottom > availableHeightTop )
 
  249    y = mPosition.y() - mWebView->height();
 
  251  mWebView->move( x, y );
 
  257  if ( !mMapTipVisible )
 
  263  if ( mDelayedClearTimer.isActive() || mWebView->underMouse() )
 
  270    mDelayedClearTimer.start( msDelay );
 
  273  mWebView->setHtml( QString() );
 
  277  mMapTipVisible = 
false;
 
  309  if ( canvasFilter ==  QLatin1String( 
"FALSE" ) )
 
  322  if ( !canvasFilter.isEmpty() )
 
  327  if ( mapTip.isEmpty() )
 
  329    exp.prepare( &context );
 
  338  std::unique_ptr< QgsFeatureRenderer > renderer;
 
  342    renderer->startRender( renderCtx, vlayer->
fields() );
 
  345    const QString filterExpression = renderer->filter( vlayer->
fields() );
 
  346    if ( ! filterExpression.isEmpty() )
 
  358    context.setFeature( feature );
 
  361    if ( filter && renderer && !renderer->willRenderFeature( feature, renderCtx ) )
 
  366    if ( !mapTip.isEmpty() )
 
  372      tipString = exp.evaluate( &context ).toString();
 
  375    if ( !tipString.isEmpty() || timer.elapsed() >= 1000 )
 
  383    renderer->stopRender( renderCtx );
 
  421QString QgsMapTip::htmlText( 
const QString &text, 
int maxWidth )
 
  425  const QFont defaultFont = qApp->font();
 
  426  const int fontSize = defaultFont.pointSize();
 
  427  const QString fontFamily = defaultFont.family();
 
  428  const QString backgroundColor = QgsApplication::palette().base().color().name();
 
  429  const QString strokeColor = QgsApplication::palette().shadow().color().name();
 
  430  const QString textColor = QgsApplication::palette().toolTipText().color().name();
 
  431  return sMapTipTemplate.arg( fontSize ).arg( fontFamily ).arg( textColor ).arg( maxWidth == -1 ? 
"" : QString::number( maxWidth ) ).arg( backgroundColor ).arg( strokeColor ).arg( text );
 
  435void QgsMapTip::onLinkClicked( 
const QUrl &url )
 
  437  QDesktopServices::openUrl( url );
 
  445  if ( !mapCanvas || !vlayer || !vlayer->
isSpatial() )
 
  449  if ( mapTemplate.isEmpty() && displayExpression.isEmpty() )
 
  471  if ( mapTemplate.isEmpty() )
 
  475    tipText = exp.
evaluate( &context ).toString();
 
  483  return QgsMapTip::htmlText( tipText, mapCanvas->width() / 2 );
 
  490  if ( !mapCanvas || !rlayer || mapTemplate.isEmpty() )
 
  507  return QgsMapTip::htmlText( tipText, mapCanvas->width() / 2 );
 
static const double UI_SCALE_FACTOR
UI scaling factor.
 
static QgsApplication * instance()
Returns the singleton instance of the QgsApplication.
 
static QgsExpressionContextScope * mapLayerPositionScope(const QgsPointXY &position)
Sets the expression context variables which are available for expressions triggered by moving the mou...
 
static QgsExpressionContextScope * mapSettingsScope(const QgsMapSettings &mapSettings)
Creates a new scope which contains variables and functions relating to a QgsMapSettings object.
 
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
 
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
 
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
 
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
 
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
 
Class for parsing and evaluation of expressions (formerly called "search strings").
 
bool prepare(const QgsExpressionContext *context)
Gets the expression ready for evaluation - find out column indexes.
 
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...
 
QVariant evaluate()
Evaluate the feature and return the result.
 
Wrapper for iterator of features from vector data provider or vector layer.
 
bool nextFeature(QgsFeature &f)
 
@ Filter
Features may be filtered, i.e. some features may not be rendered (categorized, rule based ....
 
virtual QgsFeatureRenderer * clone() const =0
Create a deep copy of this renderer.
 
This class wraps a request for features to a vector layer (or directly its vector data provider).
 
QgsFeatureRequest & combineFilterExpression(const QString &expression)
Modifies the existing filter expression to add an additional expression filter.
 
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags flags)
Sets flags that affect how features will be fetched.
 
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
 
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
 
@ ExactIntersect
Use exact geometry intersection (slower) instead of bounding boxes.
 
QgsFeatureRequest & setExpressionContext(const QgsExpressionContext &context)
Sets the expression context used to evaluate filter expressions.
 
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
 
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
 
static QString filterForLayer(QgsMapCanvas *canvas, QgsVectorLayer *layer)
Constructs a filter to use for selecting features from the given layer, in order to apply filters whi...
 
Map canvas is a class for displaying all GIS data types on a canvas.
 
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
 
const QgsDateTimeRange & temporalRange() const
Returns map canvas datetime range.
 
QList< QgsMapLayer * > layers(bool expandGroupLayers=false) const
Returns the list of layers shown within the map canvas.
 
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
 
virtual bool isVisibleInTemporalRange(const QgsDateTimeRange &range) const
Returns true if the layer should be visible and rendered for the specified time range.
 
Base class for all map layer types.
 
bool isInScaleRange(double scale) const
Tests whether the layer should be visible at the specified scale.
 
virtual QgsRectangle extent() const
Returns the extent of the layer.
 
virtual QgsMapLayerTemporalProperties * temporalProperties()
Returns the layer's temporal properties.
 
double scale() const
Returns the calculated map scale.
 
QgsPointXY mapToLayerCoordinates(const QgsMapLayer *layer, QgsPointXY point) const
transform point coordinates from output CRS to layer's CRS
 
void showMapTip(QgsMapLayer *thepLayer, QgsPointXY &mapPosition, const QPoint &pixelPosition, QgsMapCanvas *mpMapCanvas)
Show a maptip at a given point on the map canvas.
 
static QString rasterMapTipPreviewText(QgsMapLayer *layer, QgsMapCanvas *mapCanvas, const QString &mapTemplate)
Returns the html that would be displayed in a maptip for a given layer.
 
static QString vectorMapTipPreviewText(QgsMapLayer *layer, QgsMapCanvas *mapCanvas, const QString &mapTemplate, const QString &displayExpression)
Returns the html that would be displayed in a maptip for a given layer.
 
QgsMapTip()
Default constructor.
 
void clear(QgsMapCanvas *mpMapCanvas=nullptr, int msDelay=0)
Clear the current maptip if it exists.
 
A class to represent a 2D point.
 
Represents a raster layer.
 
A rectangle specified with double values.
 
void setYMinimum(double y) SIP_HOLDGIL
Set the minimum y value.
 
void setXMaximum(double x) SIP_HOLDGIL
Set the maximum x value.
 
void setXMinimum(double x) SIP_HOLDGIL
Set the minimum x value.
 
void setYMaximum(double y) SIP_HOLDGIL
Set the maximum y value.
 
bool contains(const QgsRectangle &rect) const SIP_HOLDGIL
Returns true when rectangle contains other rectangle.
 
QgsPointXY center() const SIP_HOLDGIL
Returns the center point of the rectangle.
 
Contains information about the context of a rendering operation.
 
QgsExpressionContext & expressionContext()
Gets the expression context.
 
static QgsRenderContext fromMapSettings(const QgsMapSettings &mapSettings)
create initialized QgsRenderContext instance from given QgsMapSettings
 
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
 
This class is a composition of two QSettings instances:
 
bool isTemporal() const
Returns true if the object's temporal range is enabled, and the object will be filtered when renderin...
 
Represents a vector layer which manages a vector based data sets.
 
long long featureCount(const QString &legendKey) const
Number of features rendered with specified legend key.
 
bool isSpatial() const FINAL
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
 
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
 
QgsFields fields() const FINAL
Returns the list of fields of this layer.
 
QgsFeatureRenderer * renderer()
Returns the feature renderer used for rendering the features in the layer in 2D map views.
 
QString displayExpression
 
The QgsWebView class is a collection of stubs to mimic the API of QWebView on systems where the real ...
 
#define QgsDebugMsgLevel(str, level)