Skip to content
Permalink
Browse files

Add html support in map tips

 - Add new display tab to edit html text
  • Loading branch information
NathanW2 committed Aug 5, 2012
1 parent ddd3b27 commit 8aa160bcb3548a881248c7d46d92c4f2e12ffc02
@@ -95,6 +95,10 @@ QgsVectorLayerProperties::QgsVectorLayerProperties(
connect( layer, SIGNAL( attributeAdded( int ) ), this, SLOT( attributeAdded( int ) ) );
connect( layer, SIGNAL( attributeDeleted( int ) ), this, SLOT( attributeDeleted( int ) ) );

connect( insertFieldButton, SIGNAL( clicked() ), this, SLOT( insertField() ) );
connect( insertExpressionButton, SIGNAL( clicked() ), this, SLOT( insertExpression() ) );


mAddAttributeButton->setIcon( QgsApplication::getThemeIcon( "/mActionNewAttribute.png" ) );
mDeleteAttributeButton->setIcon( QgsApplication::getThemeIcon( "/mActionDeleteAttribute.png" ) );
mToggleEditingButton->setIcon( QgsApplication::getThemeIcon( "/mActionToggleEditing.png" ) );
@@ -481,9 +485,55 @@ void QgsVectorLayerProperties::setLegendType( QString type )
legendtypecombobox->setItemText( legendtypecombobox->currentIndex(), type );
}

void QgsVectorLayerProperties::insertField()
{
// Convert the selected field to an expression and
// insert it into the action at the cursor position

if ( !fieldComboBox->currentText().isNull() )
{
QString field = "[% \"";
field += fieldComboBox->currentText();
field += "\" %]";
htmlMapTip->insertPlainText( field );
}
}

void QgsVectorLayerProperties::insertExpression()
{
QString selText = htmlMapTip->textCursor().selectedText();

// edit the selected expression if there's one
if ( selText.startsWith( "[%" ) && selText.endsWith( "%]" ) )
selText = selText.mid( 2, selText.size() - 4 );

// display the expression builder
QgsExpressionBuilderDialog dlg( layer , selText, this );
dlg.setWindowTitle( tr( "Insert expression" ) );
if ( dlg.exec() == QDialog::Accepted )
{
QString expression = dlg.expressionBuilder()->expressionText();
//Only add the expression if the user has entered some text.
if ( !expression.isEmpty() )
{
htmlMapTip->insertPlainText( "[%" + expression + "%]" );
}
}
}

void QgsVectorLayerProperties::setDisplayField( QString name )
{
displayFieldComboBox->setItemText( displayFieldComboBox->currentIndex(), name );
int idx = displayFieldComboBox->findText( name );
if ( idx == -1 )
{
htmlRadio->setChecked( true );
htmlMapTip->setPlainText( name );
}
else
{
fieldComboRadio->setChecked( true );
displayFieldComboBox->setCurrentIndex( idx );
}
}

//! @note in raster props, this method is called sync()
@@ -520,9 +570,10 @@ void QgsVectorLayerProperties::reset( void )
for ( QgsFieldMap::const_iterator it = myFields.begin(); it != myFields.end(); ++it )
{
displayFieldComboBox->addItem( it->name() );
fieldComboBox->addItem( it->name() );
}
displayFieldComboBox->setCurrentIndex( displayFieldComboBox->findText(
layer->displayField() ) );

setDisplayField( layer-> displayField() );

// set up the scale based layer visibility stuff....
chkUseScaleDependentRendering->setChecked( layer->hasScaleBasedVisibility() );
@@ -633,7 +684,15 @@ void QgsVectorLayerProperties::apply()
}

// update the display field
layer->setDisplayField( displayFieldComboBox->currentText() );
if ( htmlRadio->isChecked() )
{
layer->setDisplayField( htmlMapTip->toPlainText() );
}

if ( fieldComboRadio->isChecked() )
{
layer->setDisplayField( displayFieldComboBox->currentText() );
}

layer->setEditForm( leEditForm->text() );
layer->setEditFormInit( leEditFormInit->text() );
@@ -28,6 +28,7 @@
#include "qgsfield.h"
#include "qgsmapcanvas.h"
#include "qgscontexthelp.h"
#include "qgsexpressionbuilderdialog.h"

class QgsMapLayer;

@@ -55,6 +56,7 @@ class QgsVectorLayerProperties : public QDialog, private Ui::QgsVectorLayerPrope
/**Returns the display name entered in the dialog*/
QString displayName();
void setRendererDirty( bool ) {}

/**Sets the attribute that is used in the Identify Results dialog box*/
void setDisplayField( QString name );

@@ -70,6 +72,11 @@ class QgsVectorLayerProperties : public QDialog, private Ui::QgsVectorLayerPrope

public slots:

/** Insert a field in the expression text for the map tip **/
void insertField();

void insertExpression();

void attributeTypeDialog();

void alterLayerDialog( const QString& string );
@@ -13,8 +13,10 @@
* *
***************************************************************************/
// QGIS includes
#include <qgsmapcanvas.h>
#include <qgsvectorlayer.h>
#include "qgsmapcanvas.h"
#include "qgsvectorlayer.h"
#include "qgsexpression.h"
#include "qgslogger.h"

// Qt includes
#include <QPoint>
@@ -91,15 +93,59 @@ QString QgsMapTip::fetchFeature( QgsMapLayer *layer, QgsPoint &mapPosition, QgsM

r = mpMapCanvas->mapRenderer()->mapToLayerCoordinates( layer, r );

int idx = vlayer->fieldNameIndex( vlayer->displayField() );
if ( idx < 0 )
return "";

QgsFeature feature;

vlayer->select( QgsAttributeList() << idx, r, true, true );
vlayer->select( vlayer->pendingAllAttributesList() , r, true, true );
if ( !vlayer->nextFeature( feature ) )
return "";

return feature.attributeMap().value( idx, "" ).toString();
int idx = vlayer->fieldNameIndex( vlayer->displayField() );
if ( idx < 0 )
return replaceText( vlayer->displayField(), vlayer, feature );
else
return feature.attributeMap().value( idx, "" ).toString();

}

QString QgsMapTip::replaceText( QString displayText, QgsVectorLayer *layer, QgsFeature &feat )
{
QString expr_action;

int index = 0;
while ( index < displayText.size() )
{
QRegExp rx = QRegExp( "\\[%([^\\]]+)%\\]" );

int pos = rx.indexIn( displayText, index );
if ( pos < 0 )
break;

int start = index;
index = pos + rx.matchedLength();

QString to_replace = rx.cap( 1 ).trimmed();
QgsDebugMsg( "Found expression: " + to_replace );

QgsExpression exp( to_replace );
if ( exp.hasParserError() )
{
QgsDebugMsg( "Expression parser error: " + exp.parserErrorString() );
expr_action += displayText.mid( start, index - start );
continue;
}

QVariant result = exp.evaluate( &feat, layer->pendingFields() );
if ( exp.hasEvalError() )
{
QgsDebugMsg( "Expression parser eval error: " + exp.evalErrorString() );
expr_action += displayText.mid( start, index - start );
continue;
}

QgsDebugMsg( "Expression result is: " + result.toString() );
expr_action += displayText.mid( start, pos - start ) + result.toString();
}

expr_action += displayText.mid( index );
return expr_action;
}
@@ -20,6 +20,7 @@ class QgsMapCanvas;
class QPoint;
class QString;

#include "qgsfeature.h"

/** \ingroup gui
* A maptip is a class to display a tip on a map canvas
@@ -57,6 +58,9 @@ class GUI_EXPORT QgsMapTip
QString fetchFeature( QgsMapLayer * thepLayer,
QgsPoint & theMapPosition,
QgsMapCanvas *thepMapCanvas );

QString replaceText( QString displayText, QgsVectorLayer *layer, QgsFeature &feat );

// Flag to indicate if a maptip is currently being displayed
bool mMapTipVisible;
// Last point on the map canvas when the maptip timer fired. This point is in widget pixel

2 comments on commit 8aa160b

@AndrewM-

This comment has been minimized.

Copy link

@AndrewM- AndrewM- replied Feb 28, 2014

Hi Nathan,
I cannot get the img display working. Can you please document the types of image paths that map tips can support. I have tried about a dozen variations on image URLs for displaying images in maptips without success. I am using GGIS 2.2 on a Win64 system. The image addresses that I would like to display look like this - 'H:\Photos\NonWork\2012-04-20_RedCliffPoint\Thumbs\P1190276.JPG'.

@AndrewM-

This comment has been minimized.

Copy link

@AndrewM- AndrewM- replied Mar 3, 2014

Correction, the maptips do work with images e.g.[img src=''H:\Photos\NonWork\2012-04-20_RedCliffPoint\Thumbs\P1190276.JPG"/] with angle brakets. However if you see text instead of an image, then the problem is probably text before or after the line with the image link. I found that putting
tags on either side of the above line to separate the image from other content made things work.

Please sign in to comment.
You can’t perform that action at this time.