|
@@ -18,15 +18,22 @@ |
|
|
#include "qgsvectorlayer.h" |
|
|
#include "qgsexpression.h" |
|
|
#include "qgslogger.h" |
|
|
#include "qgswebview.h" |
|
|
#include "qgswebframe.h" |
|
|
|
|
|
// Qt includes |
|
|
#include <QPoint> |
|
|
#include <QToolTip> |
|
|
#include <QSettings> |
|
|
#include <QLabel> |
|
|
#include <QWebElement> |
|
|
#include <QHBoxLayout> |
|
|
|
|
|
|
|
|
#include "qgsmaptip.h" |
|
|
|
|
|
QgsMapTip::QgsMapTip() |
|
|
: mWidget( nullptr ), mWebView( nullptr ) |
|
|
{ |
|
|
// init the visible flag |
|
|
mMapTipVisible = false; |
|
@@ -37,38 +44,115 @@ QgsMapTip::~QgsMapTip() |
|
|
|
|
|
} |
|
|
|
|
|
void QgsMapTip::showMapTip( QgsMapLayer *thepLayer, |
|
|
QgsPoint & theMapPosition, |
|
|
void QgsMapTip::showMapTip( QgsMapLayer *pLayer, |
|
|
QgsPoint & mapPosition, |
|
|
QPoint & thePixelPosition, |
|
|
QgsMapCanvas *thepMapCanvas ) |
|
|
QgsMapCanvas *pMapCanvas ) |
|
|
{ |
|
|
// Do the search using the active layer and the preferred label |
|
|
// field for the layer. The label field must be defined in the layer configuration |
|
|
// Do the search using the active layer and the preferred label field for the |
|
|
// layer. The label field must be defined in the layer configuration |
|
|
// file/database. The code required to do this is similar to identify, except |
|
|
// we only want the first qualifying feature and we will only display the |
|
|
// field defined as the label field in the layer configuration file/database. |
|
|
// |
|
|
// TODO: Define the label (display) field for each map layer in the map configuration file/database |
|
|
// field defined as the label field in the layer configuration file/database |
|
|
|
|
|
// Show the maptip on the canvas |
|
|
QString myTipText = fetchFeature( thepLayer, theMapPosition, thepMapCanvas ); |
|
|
mMapTipVisible = !myTipText.isEmpty(); |
|
|
QString tipText, lastTipText, tipHtml, bodyStyle, containerStyle, |
|
|
backgroundColor, borderColor; |
|
|
|
|
|
delete mWidget; |
|
|
mWidget = new QWidget( pMapCanvas ); |
|
|
mWebView = new QgsWebView( mWidget ); |
|
|
|
|
|
mWebView->page()->settings()->setAttribute( |
|
|
QWebSettings::DeveloperExtrasEnabled, true ); |
|
|
mWebView->page()->settings()->setAttribute( |
|
|
QWebSettings::JavascriptEnabled, true ); |
|
|
|
|
|
QHBoxLayout* layout = new QHBoxLayout; |
|
|
layout->addWidget( mWebView ); |
|
|
|
|
|
mWidget->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ); |
|
|
mWidget->setLayout( layout ); |
|
|
|
|
|
//assure the map tip is never larger than half the map canvas |
|
|
const int MAX_WIDTH = pMapCanvas->geometry().width() / 2; |
|
|
const int MAX_HEIGHT = pMapCanvas->geometry().height() / 2; |
|
|
mWidget->setMaximumSize( MAX_WIDTH, MAX_HEIGHT ); |
|
|
|
|
|
// start with 0 size, |
|
|
// the content will automatically make it grow up to MaximumSize |
|
|
mWidget->resize( 0, 0 ); |
|
|
|
|
|
backgroundColor = mWidget->palette().base().color().name(); |
|
|
borderColor = mWidget->palette().shadow().color().name(); |
|
|
mWidget->setStyleSheet( QString( |
|
|
".QWidget{" |
|
|
"border: 1px solid %1;" |
|
|
"background-color: %2;}" ).arg( |
|
|
borderColor, backgroundColor ) ); |
|
|
|
|
|
if ( mMapTipVisible ) |
|
|
tipText = fetchFeature( pLayer, mapPosition, pMapCanvas ); |
|
|
|
|
|
mMapTipVisible = !tipText.isEmpty(); |
|
|
if ( !mMapTipVisible ) |
|
|
{ |
|
|
QToolTip::showText( thepMapCanvas->mapToGlobal( thePixelPosition ), myTipText, thepMapCanvas ); |
|
|
// store the point so we can use it to clear the maptip later |
|
|
mLastPosition = thePixelPosition; |
|
|
clear(); |
|
|
return; |
|
|
} |
|
|
|
|
|
if ( tipText == lastTipText ) |
|
|
{ |
|
|
return; |
|
|
} |
|
|
|
|
|
bodyStyle = QString( |
|
|
"background-color: %1;" |
|
|
"margin: 0;" ).arg( backgroundColor ); |
|
|
|
|
|
containerStyle = QString( |
|
|
"display: inline-block;" |
|
|
"margin: 0px" ); |
|
|
|
|
|
tipHtml = QString( |
|
|
"<html>" |
|
|
"<body style='%1'>" |
|
|
"<div id='QgsWebViewContainer' style='%2'>%3</div>" |
|
|
"</body>" |
|
|
"</html>" ).arg( bodyStyle, containerStyle, tipText ); |
|
|
|
|
|
mWidget->move( thePixelPosition.x(), |
|
|
thePixelPosition.y() ); |
|
|
|
|
|
mWebView->setHtml( tipHtml ); |
|
|
lastTipText = tipText; |
|
|
|
|
|
mWidget->show(); |
|
|
|
|
|
int scrollbarWidth = mWebView->page()->mainFrame()->scrollBarGeometry( |
|
|
Qt::Vertical ).width(); |
|
|
int scrollbarHeight = mWebView->page()->mainFrame()->scrollBarGeometry( |
|
|
Qt::Horizontal ).height(); |
|
|
|
|
|
if ( scrollbarWidth > 0 || scrollbarHeight > 0 ) |
|
|
{ |
|
|
// Get the content size |
|
|
QWebElement container = mWebView->page()->mainFrame()->findFirstElement( |
|
|
"#QgsWebViewContainer" ); |
|
|
int width = container.geometry().width() + 5 + scrollbarWidth; |
|
|
int height = container.geometry().height() + 5 + scrollbarHeight; |
|
|
|
|
|
mWidget->resize( width, height ); |
|
|
} |
|
|
} |
|
|
|
|
|
void QgsMapTip::clear( QgsMapCanvas *mpMapCanvas ) |
|
|
void QgsMapTip::clear( QgsMapCanvas * ) |
|
|
{ |
|
|
if ( !mMapTipVisible ) |
|
|
return; |
|
|
|
|
|
// set the maptip to blank |
|
|
QToolTip::showText( mpMapCanvas->mapToGlobal( mLastPosition ), "", mpMapCanvas ); |
|
|
mWebView->setHtml( QString() ); |
|
|
mWidget->hide(); |
|
|
|
|
|
// reset the visible flag |
|
|
mMapTipVisible = false; |
|
|
} |
|
@@ -77,7 +161,7 @@ QString QgsMapTip::fetchFeature( QgsMapLayer *layer, QgsPoint &mapPosition, QgsM |
|
|
{ |
|
|
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer ); |
|
|
if ( !vlayer ) |
|
|
return ""; |
|
|
return QString(); |
|
|
|
|
|
double searchRadius = QgsMapTool::searchRadiusMU( mpMapCanvas ); |
|
|
|
|
@@ -92,7 +176,7 @@ QString QgsMapTip::fetchFeature( QgsMapLayer *layer, QgsPoint &mapPosition, QgsM |
|
|
QgsFeature feature; |
|
|
|
|
|
if ( !vlayer->getFeatures( QgsFeatureRequest().setFilterRect( r ).setFlags( QgsFeatureRequest::ExactIntersect ) ).nextFeature( feature ) ) |
|
|
return ""; |
|
|
return QString(); |
|
|
|
|
|
int idx = vlayer->fieldNameIndex( vlayer->displayField() ); |
|
|
if ( idx < 0 ) |
|
@@ -108,5 +192,7 @@ QString QgsMapTip::fetchFeature( QgsMapLayer *layer, QgsPoint &mapPosition, QgsM |
|
|
return QgsExpression::replaceExpressionText( vlayer->displayField(), &context ); |
|
|
} |
|
|
else |
|
|
{ |
|
|
return feature.attribute( idx ).toString(); |
|
|
} |
|
|
} |