Skip to content

Commit

Permalink
Add map tip preview in vector layers properties
Browse files Browse the repository at this point in the history
  • Loading branch information
YoannQDQ committed Mar 28, 2023
1 parent 66b64bc commit 7d1cc05
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 33 deletions.
Expand Up @@ -27,6 +27,9 @@ class QgsVectorLayerProperties : QgsOptionsDialogBase
Adds a properties page factory to the vector layer properties dialog.
%End

virtual bool eventFilter( QObject *obj, QEvent *ev );


protected slots:
void optionsStackedWidget_CurrentChanged( int index ) final;

Expand Down
93 changes: 93 additions & 0 deletions src/gui/vector/qgsvectorlayerproperties.cpp
Expand Up @@ -66,6 +66,12 @@
#include "qgsproviderregistry.h"
#include "qgsmaplayerstylemanager.h"
#include "qgslayertreemodel.h"
#include "qgsmaptip.h"
#include "qgswebview.h"
#include "qgswebframe.h"
#if WITH_QTWEBKIT
#include <QWebElement>
#endif

#include <QDesktopServices>
#include <QMessageBox>
Expand Down Expand Up @@ -162,6 +168,7 @@ QgsVectorLayerProperties::QgsVectorLayerProperties(
mMapTipExpressionFieldWidget->registerExpressionContextGenerator( this );
mDisplayExpressionWidget->setLayer( lyr );
mDisplayExpressionWidget->registerExpressionContextGenerator( this );
initMapTipPreview();

connect( mInsertExpressionButton, &QAbstractButton::clicked, this, &QgsVectorLayerProperties::insertFieldOrExpression );

Expand Down Expand Up @@ -2248,3 +2255,89 @@ void QgsVectorLayerProperties::deleteAuxiliaryField( int index )
mMessageBar->pushMessage( title, msg, Qgis::MessageLevel::Warning );
}
}

bool QgsVectorLayerProperties::eventFilter( QObject *obj, QEvent *ev )
{
// If the map tip preview container is resized, resize the map tip
if ( obj == mMapTipPreviewContainer && ev->type() == QEvent::Resize )
{
resizeMapTip();
}
return QgsOptionsDialogBase::eventFilter( obj, ev );
}

void QgsVectorLayerProperties::initMapTipPreview()
{
// HTML editor and preview are in a splitter. By default, the editor takes 2/3 of the space
mMapTipSplitter->setSizes( { 400, 200 } );
// Event filter is used to resize the map tip when the container is resized
mMapTipPreviewContainer->installEventFilter( this );

// Note: there's quite a bit of overlap between this and the code in QgsMapTip::showMapTip
// Create and style the map tip frame
mMapTipPreviewWidget = new QWidget( mMapTipPreviewContainer );
mMapTipPreviewWidget->setContentsMargins( MARGIN_VALUE, MARGIN_VALUE, MARGIN_VALUE, MARGIN_VALUE );
const QString backgroundColor = mMapTipPreviewWidget->palette().base().color().name();
const QString strokeColor = mMapTipPreviewWidget->palette().shadow().color().name();
mMapTipPreviewWidget->setStyleSheet( QString(
".QWidget{"
"border: 1px solid %1;"
"background-color: %2;}" ).arg(
strokeColor, backgroundColor ) );

// Create the WebView
mMapTipPreview = new QgsWebView( mMapTipPreviewWidget );

#if WITH_QTWEBKIT
mMapTipPreview->page()->setLinkDelegationPolicy( QWebPage::DelegateAllLinks );//Handle link clicks by yourself
mMapTipPreview->setContextMenuPolicy( Qt::NoContextMenu ); //No context menu is allowed if you don't need it
connect( mMapTipPreview, &QWebView::loadFinished, this, &QgsVectorLayerProperties::resizeMapTip );
#endif

mMapTipPreview->page()->settings()->setAttribute( QWebSettings::DeveloperExtrasEnabled, true );
mMapTipPreview->page()->settings()->setAttribute( QWebSettings::JavascriptEnabled, true );
mMapTipPreview->page()->settings()->setAttribute( QWebSettings::LocalStorageEnabled, true );

// Disable scrollbars, avoid random resizing issues
mMapTipPreview->page()->mainFrame()->setScrollBarPolicy( Qt::Horizontal, Qt::ScrollBarAlwaysOff );
mMapTipPreview->page()->mainFrame()->setScrollBarPolicy( Qt::Vertical, Qt::ScrollBarAlwaysOff );

QHBoxLayout *hlayout = new QHBoxLayout;
hlayout->setContentsMargins( 0, 0, 0, 0 );
hlayout->addWidget( mMapTipPreview );

mMapTipPreviewWidget->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
mMapTipPreviewWidget->setLayout( hlayout );

// Update the map tip preview when the expression or the map tip template changes
connect( mMapTipWidget, &QgsCodeEditorHTML::textChanged, this, &QgsVectorLayerProperties::updateMapTipPreview );
connect( mDisplayExpressionWidget, qOverload< const QString & >( &QgsFieldExpressionWidget::fieldChanged ), this, &QgsVectorLayerProperties::updateMapTipPreview );
}

void QgsVectorLayerProperties::updateMapTipPreview()
{
mMapTipPreviewWidget->setMaximumSize( mMapTipPreviewContainer->width(), mMapTipPreviewContainer->height() );
const QString htmlContent = QgsMapTip::vectorMapTipPreviewText( mLayer, mCanvas, mMapTipWidget->text(), mDisplayExpressionWidget->asExpression() );
mMapTipPreview->setHtml( htmlContent );
}

void QgsVectorLayerProperties::resizeMapTip()
{
// Ensure the map tip is not bigger than the container
mMapTipPreviewWidget->setMaximumSize( mMapTipPreviewContainer->width(), mMapTipPreviewContainer->height() );
#if WITH_QTWEBKIT
// Get the content size
const QWebElement container = mMapTipPreview->page()->mainFrame()->findFirstElement(
QStringLiteral( "#QgsWebViewContainer" ) );
const int width = container.geometry().width() + MARGIN_VALUE * 2;
const int height = container.geometry().height() + MARGIN_VALUE * 2;
mMapTipPreviewWidget->resize( width, height );

// Move the map tip to the center of the container
mMapTipPreviewWidget->move( ( mMapTipPreviewContainer->width() - mMapTipPreviewWidget->width() ) / 2,
( mMapTipPreviewContainer->height() - mMapTipPreviewWidget->height() ) / 2 );

#else
mMapTipPreview->adjustSize();
#endif
}
14 changes: 14 additions & 0 deletions src/gui/vector/qgsvectorlayerproperties.h
Expand Up @@ -49,6 +49,7 @@ class QgsDoubleSpinBox;
class QgsMaskingWidget;
class QgsVectorLayerTemporalPropertiesWidget;
class QgsProviderSourceWidget;
class QgsWebView;

/**
* \ingroup gui
Expand All @@ -75,6 +76,8 @@ class GUI_EXPORT QgsVectorLayerProperties : public QgsOptionsDialogBase, private
//! Adds a properties page factory to the vector layer properties dialog.
void addPropertiesPageFactory( const QgsMapLayerConfigWidgetFactory *factory );

bool eventFilter( QObject *obj, QEvent *ev ) override;

protected slots:
void optionsStackedWidget_CurrentChanged( int index ) final;

Expand Down Expand Up @@ -162,6 +165,11 @@ class GUI_EXPORT QgsVectorLayerProperties : public QgsOptionsDialogBase, private

void urlClicked( const QUrl &url );

// Update the preview of the map tip
void updateMapTipPreview();
// Resize the map tip preview
void resizeMapTip();

private:

enum PropertyType
Expand Down Expand Up @@ -255,6 +263,12 @@ class GUI_EXPORT QgsVectorLayerProperties : public QgsOptionsDialogBase, private

QgsCoordinateReferenceSystem mBackupCrs;

void initMapTipPreview();

QWidget *mMapTipPreviewWidget = nullptr;
QgsWebView *mMapTipPreview = nullptr;
const int MARGIN_VALUE = 5;

private slots:
void openPanel( QgsPanelWidget *panel );

Expand Down
88 changes: 55 additions & 33 deletions src/ui/qgsvectorlayerpropertiesbase.ui
Expand Up @@ -363,7 +363,7 @@
</sizepolicy>
</property>
<property name="currentIndex">
<number>11</number>
<number>0</number>
</property>
<widget class="QWidget" name="mOptsPage_Information">
<layout class="QVBoxLayout" name="verticalLayout_5">
Expand Down Expand Up @@ -439,8 +439,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>239</width>
<height>480</height>
<width>336</width>
<height>562</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_9">
Expand Down Expand Up @@ -950,8 +950,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>110</width>
<height>87</height>
<width>164</width>
<height>103</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_23">
Expand Down Expand Up @@ -1460,7 +1460,45 @@
<string>HTML Map Tip</string>
</property>
<layout class="QGridLayout" name="gridLayout_8">
<item row="1" column="2">
<item row="0" column="0" colspan="2">
<widget class="QSplitter" name="mMapTipSplitter">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QgsCodeEditorHTML" name="mMapTipWidget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
</widget>
<widget class="QGroupBox" name="mMapTipPreviewContainer">
<property name="minimumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="title">
<string>Preview</string>
</property>
</widget>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="mInsertExpressionButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
Expand All @@ -1476,23 +1514,17 @@
</property>
</widget>
</item>
<item row="0" column="0" colspan="3">
<widget class="QgsCodeEditorHTML" name="mMapTipWidget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
<item row="2" column="0" colspan="2">
<widget class="QLabel" name="labelMapTipInfo">
<property name="text">
<string>The HTML map tips are shown when moving mouse over features of the currently selected layer when the 'Show Map Tips' action is toggled on. If no HTML code is set, the feature display name is used.</string>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>100</height>
</size>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<item row="1" column="0">
<widget class="QgsFieldExpressionWidget" name="mMapTipExpressionFieldWidget" native="true">
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
Expand All @@ -1502,16 +1534,6 @@
</property>
</widget>
</item>
<item row="3" column="0" colspan="3">
<widget class="QLabel" name="labelMapTipInfo">
<property name="text">
<string>The HTML map tips are shown when moving mouse over features of the currently selected layer when the 'Show Map Tips' action is toggled on. If no HTML code is set, the feature display name is used.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
Expand Down Expand Up @@ -1547,8 +1569,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>493</width>
<height>473</height>
<width>695</width>
<height>552</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_32">
Expand Down Expand Up @@ -2106,8 +2128,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>263</width>
<height>713</height>
<width>374</width>
<height>815</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_13">
Expand Down

0 comments on commit 7d1cc05

Please sign in to comment.