Skip to content

Commit

Permalink
Add map tip preview in raster layers properties
Browse files Browse the repository at this point in the history
  • Loading branch information
YoannQDQ committed Mar 28, 2023
1 parent 7d1cc05 commit 0e61eb8
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 26 deletions.
Expand Up @@ -46,6 +46,9 @@ Adds a properties page factory to the raster layer properties dialog.
virtual QgsExpressionContext createExpressionContext() const;


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


protected slots:

};
Expand Down
93 changes: 92 additions & 1 deletion src/gui/raster/qgsrasterlayerproperties.cpp
Expand Up @@ -63,6 +63,11 @@
#include "qgsrasterattributetablewidget.h"
#include "qgsrasterlayertemporalpropertieswidget.h"
#include "qgsexpressioncontextutils.h"
#include "qgsmaptip.h"
#include "qgswebframe.h"
#if WITH_QTWEBKIT
#include <QWebElement>
#endif

#include <QDesktopServices>
#include <QTableWidgetItem>
Expand Down Expand Up @@ -222,7 +227,7 @@ QgsRasterLayerProperties::QgsRasterLayerProperties( QgsMapLayer *lyr, QgsMapCanv
mRasterTransparencyWidget->pbnDefaultValues->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionOpenTable.svg" ) ) );
mRasterTransparencyWidget->pbnImportTransparentPixelValues->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionFileOpen.svg" ) ) );
mRasterTransparencyWidget->pbnExportTransparentPixelValues->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionFileSave.svg" ) ) );

initMapTipPreview();

if ( !mRasterLayer )
{
Expand Down Expand Up @@ -1921,3 +1926,89 @@ void QgsRasterLayerProperties::updateGammaSlider( double value )
{
whileBlocking( mSliderGamma )->setValue( value * 100 );
}


bool QgsRasterLayerProperties::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 QgsRasterLayerProperties::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, &QgsRasterLayerProperties::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, &QgsRasterLayerProperties::updateMapTipPreview );
}

void QgsRasterLayerProperties::updateMapTipPreview()
{
mMapTipPreviewWidget->setMaximumSize( mMapTipPreviewContainer->width(), mMapTipPreviewContainer->height() );
const QString htmlContent = QgsMapTip::rasterMapTipPreviewText( mRasterLayer, mMapCanvas, mMapTipWidget->text() );
mMapTipPreview->setHtml( htmlContent );
}

void QgsRasterLayerProperties::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/raster/qgsrasterlayerproperties.h
Expand Up @@ -48,6 +48,7 @@ class QgsMapLayerConfigWidget;
class QgsPropertyOverrideButton;
class QgsRasterTransparencyWidget;
class QgsRasterAttributeTableWidget;
class QgsWebView;


/**
Expand Down Expand Up @@ -92,6 +93,8 @@ class GUI_EXPORT QgsRasterLayerProperties : public QgsOptionsDialogBase, private

QgsExpressionContext createExpressionContext() const override;

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

protected slots:
//! \brief auto slot executed when the active page in the main widget stack is changed
void optionsStackedWidget_CurrentChanged( int index ) override SIP_SKIP ;
Expand Down Expand Up @@ -199,6 +202,11 @@ class GUI_EXPORT QgsRasterLayerProperties : 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:
QPushButton *mBtnStyle = nullptr;
QPushButton *mBtnMetadata = nullptr;
Expand Down Expand Up @@ -305,5 +313,11 @@ class GUI_EXPORT QgsRasterLayerProperties : public QgsOptionsDialogBase, private
QgsCoordinateReferenceSystem mBackupCrs;

QgsRasterAttributeTableWidget *mRasterAttributeTableWidget = nullptr;

void initMapTipPreview();

QWidget *mMapTipPreviewWidget = nullptr;
QgsWebView *mMapTipPreview = nullptr;
const int MARGIN_VALUE = 5;
};
#endif
72 changes: 47 additions & 25 deletions src/ui/qgsrasterlayerpropertiesbase.ui
Expand Up @@ -1487,8 +1487,46 @@ p, li { white-space: pre-wrap; }
<property name="title">
<string>HTML Map Tip</string>
</property>
<layout class="QGridLayout" name="gridLayout_81">
<item row="1" column="2">
<layout class="QGridLayout" name="gridLayout_8">
<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 @@ -1504,23 +1542,17 @@ p, li { white-space: pre-wrap; }
</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="QgsExpressionLineEdit" name="mMapTipExpressionWidget" native="true">
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
Expand All @@ -1530,16 +1562,6 @@ p, li { white-space: pre-wrap; }
</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.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
Expand Down

0 comments on commit 0e61eb8

Please sign in to comment.