diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index 5f599be32ef1..61bbc3fa1879 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -30,6 +30,7 @@ SET(QGIS_APP_SRCS qgsdecorationgriddialog.cpp qgsembedlayerdialog.cpp qgsformannotationdialog.cpp + qgshtmlannotationdialog.cpp qgsdelattrdialog.cpp qgsdisplayangle.cpp qgsfieldcalculator.cpp @@ -55,6 +56,7 @@ SET(QGIS_APP_SRCS qgsmaptooledit.cpp qgsmaptoolfeatureaction.cpp qgsmaptoolformannotation.cpp + qgsmaptoolhtmlannotation.cpp qgsmaptoolpinlabels.cpp qgsmaptoolshowhidelabels.cpp qgsmaptoolidentify.cpp @@ -188,6 +190,7 @@ SET (QGIS_APP_MOC_HDRS qgsfeatureaction.h qgsfieldcalculator.h qgsformannotationdialog.h + qgshtmlannotationdialog.h qgsgraduatedsymboldialog.h qgsidentifyresults.h qgslabeldialog.h diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp index 57eef40a85c9..7c7f02e24ea9 100644 --- a/src/app/qgisapp.cpp +++ b/src/app/qgisapp.cpp @@ -124,6 +124,7 @@ #include "qgsexception.h" #include "qgsfeature.h" #include "qgsformannotationitem.h" +#include "qgshtmlannotationitem.h" #include "qgsgenericprojectionselector.h" #include "qgsgpsinformationwidget.h" #include "qgslabelinggui.h" @@ -217,6 +218,7 @@ #include "qgsmaptooldeletevertex.h" #include "qgsmaptoolfeatureaction.h" #include "qgsmaptoolformannotation.h" +#include "qgsmaptoolhtmlannotation.h" #include "qgsmaptoolidentify.h" #include "qgsmaptoolmeasureangle.h" #include "qgsmaptoolmovefeature.h" @@ -728,6 +730,7 @@ QgisApp::~QgisApp() delete mMapTools.mMeasureAngle; delete mMapTools.mTextAnnotation; delete mMapTools.mFormAnnotation; + delete mMapTools.mHtmlAnnotation; delete mMapTools.mAnnotation; delete mMapTools.mAddFeature; delete mMapTools.mMoveFeature; @@ -931,6 +934,7 @@ void QgisApp::createActions() connect( mActionDraw, SIGNAL( triggered() ), this, SLOT( refreshMapCanvas() ) ); connect( mActionTextAnnotation, SIGNAL( triggered() ), this, SLOT( addTextAnnotation() ) ); connect( mActionFormAnnotation, SIGNAL( triggered() ), this, SLOT( addFormAnnotation() ) ); + connect( mActionHtmlAnnotation, SIGNAL( triggered() ), this, SLOT( addHtmlAnnotation() ) ); connect( mActionAnnotation, SIGNAL( triggered() ), this, SLOT( modifyAnnotation() ) ); connect( mActionLabeling, SIGNAL( triggered() ), this, SLOT( labeling() ) ); @@ -1354,6 +1358,7 @@ void QgisApp::createToolBars() bt->setPopupMode( QToolButton::MenuButtonPopup ); bt->addAction( mActionTextAnnotation ); bt->addAction( mActionFormAnnotation ); + bt->addAction( mActionHtmlAnnotation ); bt->addAction( mActionAnnotation ); QAction* defAnnotationAction = mActionTextAnnotation; @@ -1362,6 +1367,7 @@ void QgisApp::createToolBars() case 0: defAnnotationAction = mActionTextAnnotation; break; case 1: defAnnotationAction = mActionFormAnnotation; break; case 2: defAnnotationAction = mActionAnnotation; break; + case 3: defAnnotationAction = mActionHtmlAnnotation; break; } bt->setDefaultAction( defAnnotationAction ); QAction* annotationAction = mAttributesToolBar->addWidget( bt ); @@ -1665,6 +1671,7 @@ void QgisApp::setTheme( QString theThemeName ) mActionAddToOverview->setIcon( QgsApplication::getThemeIcon( "/mActionInOverview.png" ) ); mActionAnnotation->setIcon( QgsApplication::getThemeIcon( "/mActionAnnotation.png" ) ); mActionFormAnnotation->setIcon( QgsApplication::getThemeIcon( "/mActionFormAnnotation.png" ) ); + mActionHtmlAnnotation->setIcon( QgsApplication::getThemeIcon( "/mActionFormAnnotation.png" ) ); mActionTextAnnotation->setIcon( QgsApplication::getThemeIcon( "/mActionTextAnnotation.png" ) ); mActionLabeling->setIcon( QgsApplication::getThemeIcon( "/mActionLabeling.png" ) ); mActionShowPinnedLabels->setIcon( QgsApplication::getThemeIcon( "/mActionShowPinnedLabels.svg" ) ); @@ -1793,6 +1800,8 @@ void QgisApp::createCanvasTools() mMapTools.mTextAnnotation->setAction( mActionTextAnnotation ); mMapTools.mFormAnnotation = new QgsMapToolFormAnnotation( mMapCanvas ); mMapTools.mFormAnnotation->setAction( mActionFormAnnotation ); + mMapTools.mHtmlAnnotation = new QgsMapToolHtmlAnnotation( mMapCanvas ); + mMapTools.mHtmlAnnotation->setAction( mActionHtmlAnnotation ); mMapTools.mAnnotation = new QgsMapToolAnnotation( mMapCanvas ); mMapTools.mAnnotation->setAction( mActionAnnotation ); mMapTools.mAddFeature = new QgsMapToolAddFeature( mMapCanvas ); @@ -3904,6 +3913,11 @@ void QgisApp::addFormAnnotation() mMapCanvas->setMapTool( mMapTools.mFormAnnotation ); } +void QgisApp::addHtmlAnnotation() +{ + mMapCanvas->setMapTool( mMapTools.mHtmlAnnotation ); +} + void QgisApp::addTextAnnotation() { mMapCanvas->setMapTool( mMapTools.mTextAnnotation ); @@ -4431,6 +4445,13 @@ bool QgisApp::loadAnnotationItemsFromProject( const QDomDocument& doc ) QgsFormAnnotationItem* newFormItem = new QgsFormAnnotationItem( mMapCanvas ); newFormItem->readXML( doc, formItemList.at( i ).toElement() ); } + + QDomNodeList htmlItemList = doc.elementsByTagName( "HtmlAnnotationItem" ); + for ( int i = 0; i < htmlItemList.size(); ++i ) + { + QgsHtmlAnnotationItem* newHtmlItem = new QgsHtmlAnnotationItem( mMapCanvas ); + newHtmlItem->readXML( doc, htmlItemList.at( i ).toElement() ); + } return true; } @@ -7945,6 +7966,8 @@ void QgisApp::toolButtonActionTriggered( QAction *action ) settings.setValue( "/UI/annotationTool", 1 ); else if ( action == mActionAnnotation ) settings.setValue( "/UI/annotationTool", 2 ); + else if ( action == mActionHtmlAnnotation ) + settings.setValue( "/UI/annotationTool", 3 ); bt->setDefaultAction( action ); } diff --git a/src/app/qgisapp.h b/src/app/qgisapp.h index 612587020591..4bb6a5cc098a 100644 --- a/src/app/qgisapp.h +++ b/src/app/qgisapp.h @@ -816,6 +816,7 @@ class QgisApp : public QMainWindow, private Ui::MainWindow //annotations void addFormAnnotation(); void addTextAnnotation(); + void addHtmlAnnotation(); void modifyAnnotation(); //! shows label settings dialog (for labeling-ng) @@ -1084,6 +1085,7 @@ class QgisApp : public QMainWindow, private Ui::MainWindow QgsMapTool* mRotatePointSymbolsTool; QgsMapTool* mAnnotation; QgsMapTool* mFormAnnotation; + QgsMapTool* mHtmlAnnotation; QgsMapTool* mTextAnnotation; QgsMapTool* mPinLabels; QgsMapTool* mShowHideLabels; diff --git a/src/app/qgshtmlannotationdialog.cpp b/src/app/qgshtmlannotationdialog.cpp new file mode 100644 index 000000000000..e17ebfa8d55b --- /dev/null +++ b/src/app/qgshtmlannotationdialog.cpp @@ -0,0 +1,90 @@ +/*************************************************************************** + QgsHTMLAnnotationDialog.cpp + --------------------- + begin : March 2010 + copyright : (C) 2010 by Marco Hugentobler + email : marco dot hugentobler at sourcepole dot ch + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#include "qgshtmlannotationdialog.h" +#include "qgsannotationwidget.h" +#include "qgsvectorlayer.h" +#include +#include +#include + +QgsHtmlAnnotationDialog::QgsHtmlAnnotationDialog( QgsHtmlAnnotationItem* item, QWidget * parent, Qt::WindowFlags f ) + : QDialog( parent, f ), mItem( item ), mEmbeddedWidget( 0 ) +{ + setupUi( this ); + mEmbeddedWidget = new QgsAnnotationWidget( mItem ); + mEmbeddedWidget->show(); + mStackedWidget->addWidget( mEmbeddedWidget ); + mStackedWidget->setCurrentWidget( mEmbeddedWidget ); + + if ( item ) + { + mFileLineEdit->setText( item->htmlPage() ); + } + + QObject::connect( mButtonBox, SIGNAL( accepted() ), this, SLOT( applySettingsToItem() ) ); + QPushButton* deleteButton = new QPushButton( tr( "Delete" ) ); + QObject::connect( deleteButton, SIGNAL( clicked() ), this, SLOT( deleteItem() ) ); + mButtonBox->addButton( deleteButton, QDialogButtonBox::RejectRole ); +} + +QgsHtmlAnnotationDialog::~QgsHtmlAnnotationDialog() +{ + +} + +void QgsHtmlAnnotationDialog::applySettingsToItem() +{ + //apply settings from embedded item widget + if ( mEmbeddedWidget ) + { + mEmbeddedWidget->apply(); + } + + if ( mItem ) + { + mItem->setHTMLPage( mFileLineEdit->text() ); + QgsVectorLayer* layer = mItem->vectorLayer(); + if ( layer ) + { + //set last used annotation form as default for the layer + //layer->setAnnotationForm( mFileLineEdit->text() ); + } + mItem->update(); + } +} + +void QgsHtmlAnnotationDialog::on_mBrowseToolButton_clicked() +{ + QString directory; + QFileInfo fi( mFileLineEdit->text() ); + if ( fi.exists() ) + { + directory = fi.absolutePath(); + } + QString filename = QFileDialog::getOpenFileName( 0, tr( "html" ), directory, "*.html" ); + mFileLineEdit->setText( filename ); +} + +void QgsHtmlAnnotationDialog::deleteItem() +{ + QGraphicsScene* scene = mItem->scene(); + if ( scene ) + { + scene->removeItem( mItem ); + } + delete mItem; + mItem = 0; +} + diff --git a/src/app/qgshtmlannotationdialog.h b/src/app/qgshtmlannotationdialog.h new file mode 100644 index 000000000000..4f41c30d8768 --- /dev/null +++ b/src/app/qgshtmlannotationdialog.h @@ -0,0 +1,40 @@ +/*************************************************************************** + qgsformannotationdialog.h + --------------------- + begin : March 2010 + copyright : (C) 2010 by Marco Hugentobler + email : marco dot hugentobler at sourcepole dot ch + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef QgsHTMLAnnotationDialog_H +#define QgsHTMLAnnotationDialog_H + +#include "ui_qgsformannotationdialogbase.h" +#include "qgshtmlannotationitem.h" + +class QgsAnnotationWidget; + +class QgsHtmlAnnotationDialog: public QDialog, private Ui::QgsFormAnnotationDialogBase +{ + Q_OBJECT + public: + QgsHtmlAnnotationDialog( QgsHtmlAnnotationItem* item, QWidget * parent = 0, Qt::WindowFlags f = 0 ); + ~QgsHtmlAnnotationDialog(); + + private: + QgsHtmlAnnotationItem* mItem; + QgsAnnotationWidget* mEmbeddedWidget; + + private slots: + void applySettingsToItem(); + void on_mBrowseToolButton_clicked(); + void deleteItem(); +}; + +#endif // QgsHTMLAnnotationDialog_H diff --git a/src/app/qgsmaptoolannotation.cpp b/src/app/qgsmaptoolannotation.cpp index 829a9e8c6cf2..d39949966323 100644 --- a/src/app/qgsmaptoolannotation.cpp +++ b/src/app/qgsmaptoolannotation.cpp @@ -18,6 +18,8 @@ #include "qgsmaptoolannotation.h" #include "qgsformannotationdialog.h" #include "qgsformannotationitem.h" +#include "qgshtmlannotationitem.h" +#include "qgshtmlannotationdialog.h" #include "qgslogger.h" #include "qgsmapcanvas.h" #include "qgstextannotationdialog.h" @@ -60,6 +62,12 @@ QDialog* QgsMapToolAnnotation::createItemEditor( QgsAnnotationItem *item ) return new QgsFormAnnotationDialog( fItem ); } + QgsHtmlAnnotationItem* hItem = dynamic_cast( item ); + if ( hItem ) + { + return new QgsHtmlAnnotationDialog( hItem ); + } + return 0; } diff --git a/src/app/qgsmaptoolhtmlannotation.cpp b/src/app/qgsmaptoolhtmlannotation.cpp new file mode 100644 index 000000000000..0a7fb4a453b5 --- /dev/null +++ b/src/app/qgsmaptoolhtmlannotation.cpp @@ -0,0 +1,53 @@ +/*************************************************************************** + qgsmaptoolformannotation.cpp + ------------------------------- + begin : February 9, 2010 + copyright : (C) 2010 by Marco Hugentobler + email : marco dot hugentobler at hugis dot net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "qgsmaptoolhtmlannotation.h" +#include "qgshtmlannotationitem.h" +#include "qgsmapcanvas.h" +#include "qgsvectorlayer.h" +#include + +QgsMapToolHtmlAnnotation::QgsMapToolHtmlAnnotation( QgsMapCanvas* canvas ): QgsMapToolAnnotation( canvas ) +{ + +} + +QgsMapToolHtmlAnnotation::~QgsMapToolHtmlAnnotation() +{ + +} + +QgsAnnotationItem* QgsMapToolHtmlAnnotation::createItem( QMouseEvent* e ) +{ + //try to associate the current vector layer and a feature to the form item + QgsVectorLayer* currentVectorLayer = 0; + if ( mCanvas ) + { + QgsMapLayer* mLayer = mCanvas->currentLayer(); + if ( mLayer ) + { + currentVectorLayer = dynamic_cast( mLayer ); + } + } + + QgsHtmlAnnotationItem* formItem = new QgsHtmlAnnotationItem( mCanvas, currentVectorLayer ); + formItem->setMapPosition( toMapCoordinates( e->pos() ) ); + formItem->setSelected( true ); + formItem->setFrameSize( QSizeF( 200, 100 ) ); + return formItem; +} + diff --git a/src/app/qgsmaptoolhtmlannotation.h b/src/app/qgsmaptoolhtmlannotation.h new file mode 100644 index 000000000000..16fbd80fdb13 --- /dev/null +++ b/src/app/qgsmaptoolhtmlannotation.h @@ -0,0 +1,33 @@ +/*************************************************************************** + QgsMapToolHtmlAnnotation.h + ----------------------------- + begin : February 9, 2010 + copyright : (C) 2010 by Marco Hugentobler + email : marco dot hugentobler at hugis dot net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGSMAPTOOLHTMLANNOTATION_H +#define QGSMAPTOOLHTMLANNOTATION_H + +#include "qgsmaptoolannotation.h" + +class QgsMapToolHtmlAnnotation: public QgsMapToolAnnotation +{ + public: + QgsMapToolHtmlAnnotation( QgsMapCanvas* canvas ); + ~QgsMapToolHtmlAnnotation(); + + protected: + QgsAnnotationItem* createItem( QMouseEvent* e ); +}; + +#endif // QgsMapToolHtmlAnnotation_H diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 0a85ae72d98b..96e08064c555 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -59,6 +59,7 @@ qgsencodingfiledialog.cpp qgsfiledropedit.cpp qgsfieldvalidator.cpp qgsformannotationitem.cpp +qgshtmlannotationitem.cpp qgsgenericprojectionselector.cpp qgsmanageconnectionsdialog.cpp qgsmapcanvas.cpp @@ -156,6 +157,7 @@ qgisinterface.h qgsencodingfiledialog.h qgsfieldvalidator.h qgsformannotationitem.h +qgshtmlannotationitem.h qgsgenericprojectionselector.h qgsmanageconnectionsdialog.h qgsmapcanvas.h diff --git a/src/gui/qgshtmlannotationitem.cpp b/src/gui/qgshtmlannotationitem.cpp new file mode 100644 index 000000000000..f837688f293b --- /dev/null +++ b/src/gui/qgshtmlannotationitem.cpp @@ -0,0 +1,278 @@ +/*************************************************************************** + qgshtmlannotationitem.h + ------------------------ + begin : February 26, 2010 + copyright : (C) 2010 by Marco Hugentobler + email : marco dot hugentobler at hugis dot net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "qgshtmlannotationitem.h" +#include "qgsattributeeditor.h" +#include "qgsfeature.h" +#include "qgslogger.h" +#include "qgsmapcanvas.h" +#include "qgsmaplayerregistry.h" +#include "qgsvectorlayer.h" +#include "qgsexpression.h" + +#include +#include +#include +#include +#include +#include +#include +#include + + +QgsHtmlAnnotationItem::QgsHtmlAnnotationItem( QgsMapCanvas* canvas, QgsVectorLayer* vlayer, bool hasFeature, int feature ) + : QgsAnnotationItem( canvas ), mWidgetContainer( 0 ), mWebView( 0 ), mVectorLayer( vlayer ), + mHasAssociatedFeature( hasFeature ), mFeatureId( feature ) +{ + mWebView = new QWebView(); + mWidgetContainer = new QGraphicsProxyWidget( this ); + mWidgetContainer->setWidget( mWebView ); + + QObject::connect( mWebView->page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(javascript())); + + if ( mVectorLayer && mMapCanvas ) + { + QObject::connect( mVectorLayer, SIGNAL( layerModified( bool ) ), this, SLOT( setFeatureForMapPosition() ) ); + QObject::connect( mMapCanvas, SIGNAL( renderComplete( QPainter* ) ), this, SLOT( setFeatureForMapPosition() ) ); + QObject::connect( mMapCanvas, SIGNAL( layersChanged() ), this, SLOT( updateVisibility() ) ); + } + + setFeatureForMapPosition(); +} + +QgsHtmlAnnotationItem::~QgsHtmlAnnotationItem() +{ + delete mWebView; +} + +void QgsHtmlAnnotationItem::setHTMLPage( const QString& htmlFile ) +{ + QFile file( htmlFile ); + mHtmlFile = htmlFile; + if ( !file.open( QIODevice::ReadOnly | QIODevice::Text ) ) + { + mHtmlSource = ""; + } + else + { + QTextStream in( &file ); + in.setCodec( "UTF-8" ); + mHtmlSource = in.readAll(); + } + + file.close(); + setFeatureForMapPosition(); +} + +void QgsHtmlAnnotationItem::setMapPosition( const QgsPoint& pos ) +{ + QgsAnnotationItem::setMapPosition( pos ); + setFeatureForMapPosition(); +} + +void QgsHtmlAnnotationItem::paint( QPainter * painter ) +{ + Q_UNUSED( painter ); +} + +void QgsHtmlAnnotationItem::paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget ) +{ + Q_UNUSED( option ); + Q_UNUSED( widget ); + if ( !painter || !mWidgetContainer ) + { + return; + } + + drawFrame( painter ); + if ( mMapPositionFixed ) + { + drawMarkerSymbol( painter ); + } + + mWidgetContainer->setGeometry( QRectF( mOffsetFromReferencePoint.x() + mFrameBorderWidth / 2.0, mOffsetFromReferencePoint.y() + + mFrameBorderWidth / 2.0, mFrameSize.width() - mFrameBorderWidth, mFrameSize.height() + - mFrameBorderWidth ) ); + if (data(1).toString() == "composer") + { + mWidgetContainer->widget()->render( painter, mOffsetFromReferencePoint.toPoint()); + } + + if ( isSelected() ) + { + drawSelectionBoxes( painter ); + } +} + +QSizeF QgsHtmlAnnotationItem::minimumFrameSize() const +{ + if ( mWebView ) + { + QSizeF widgetMinSize = mWebView->minimumSize(); + return QSizeF( 2 * mFrameBorderWidth + widgetMinSize.width(), 2 * mFrameBorderWidth + widgetMinSize.height() ); + } + else + { + return QSizeF( 0, 0 ); + } +} + +void QgsHtmlAnnotationItem::writeXML( QDomDocument& doc ) const +{ + QDomElement documentElem = doc.documentElement(); + if ( documentElem.isNull() ) + { + return; + } + + QDomElement formAnnotationElem = doc.createElement( "HtmlAnnotationItem" ); + if ( mVectorLayer ) + { + formAnnotationElem.setAttribute( "vectorLayer", mVectorLayer->id() ); + } + formAnnotationElem.setAttribute( "hasFeature", mHasAssociatedFeature ); + formAnnotationElem.setAttribute( "feature", mFeatureId ); + formAnnotationElem.setAttribute( "htmlfile", htmlPage() ); + + _writeXML( doc, formAnnotationElem ); + documentElem.appendChild( formAnnotationElem ); +} + +void QgsHtmlAnnotationItem::readXML( const QDomDocument& doc, const QDomElement& itemElem ) +{ + mVectorLayer = 0; + if ( itemElem.hasAttribute( "vectorLayer" ) ) + { + mVectorLayer = dynamic_cast( QgsMapLayerRegistry::instance()->mapLayer( itemElem.attribute( "vectorLayer", "" ) ) ); + if ( mVectorLayer ) + { + QObject::connect( mVectorLayer, SIGNAL( layerModified( bool ) ), this, SLOT( setFeatureForMapPosition() ) ); + QObject::connect( mMapCanvas, SIGNAL( renderComplete( QPainter* ) ), this, SLOT( setFeatureForMapPosition() ) ); + QObject::connect( mMapCanvas, SIGNAL( layersChanged() ), this, SLOT( updateVisibility() ) ); + } + } + mHasAssociatedFeature = itemElem.attribute( "hasFeature", "0" ).toInt(); + mFeatureId = itemElem.attribute( "feature", "0" ).toInt(); + mHtmlFile = itemElem.attribute( "htmlfile", ""); + QDomElement annotationElem = itemElem.firstChildElement( "AnnotationItem" ); + if ( !annotationElem.isNull() ) + { + _readXML( doc, annotationElem ); + } + + if ( mWebView ) + { + setHTMLPage( mHtmlFile ); + } + updateVisibility(); +} + +void QgsHtmlAnnotationItem::setFeatureForMapPosition() +{ + if ( !mVectorLayer || !mMapCanvas ) + { + return; + } + + QSettings settings; + double identifyValue = settings.value( "/Map/identifyRadius", QGis::DEFAULT_IDENTIFY_RADIUS ).toDouble(); + double halfIdentifyWidth = mMapCanvas->extent().width() / 100 / 2 * identifyValue; + QgsRectangle searchRect( mMapPosition.x() - halfIdentifyWidth, mMapPosition.y() - halfIdentifyWidth, + mMapPosition.x() + halfIdentifyWidth, mMapPosition.y() + halfIdentifyWidth ); + mVectorLayer->select( mVectorLayer->pendingAllAttributesList() , searchRect, false, true ); + + QgsFeature currentFeature; + QgsFeatureId currentFeatureId = 0; + bool featureFound = false; + + while ( mVectorLayer->nextFeature( currentFeature ) ) + { + currentFeatureId = currentFeature.id(); + featureFound = true; + break; + } + + mHasAssociatedFeature = featureFound; + mFeatureId = currentFeatureId; + mFeature = currentFeature; + + QString newtext = replaceText( mHtmlSource, vectorLayer(), mFeature ); + mWebView->setHtml( newtext ); + +} + +void QgsHtmlAnnotationItem::updateVisibility() +{ + bool visible = true; + if ( mVectorLayer && mMapCanvas ) + { + visible = mMapCanvas->layers().contains( mVectorLayer ); + } + setVisible( visible ); +} + +void QgsHtmlAnnotationItem::javascript() +{ + QWebFrame *frame = mWebView->page()->mainFrame(); + frame->addToJavaScriptWindowObject("canvas", mMapCanvas ); +} + +QString QgsHtmlAnnotationItem::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; +} + + + diff --git a/src/gui/qgshtmlannotationitem.h b/src/gui/qgshtmlannotationitem.h new file mode 100644 index 000000000000..bb1fe8f2312b --- /dev/null +++ b/src/gui/qgshtmlannotationitem.h @@ -0,0 +1,79 @@ +/*************************************************************************** + qgshtmlannotationitem.h + ------------------------ + begin : February 9, 2010 + copyright : (C) 2010 by Marco Hugentobler + email : marco dot hugentobler at hugis dot net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGSHTMLANNOTATIONITEM_H +#define QGSHTMLANNOTATIONITEM_H + +#include "qgsannotationitem.h" +#include "qgsfeature.h" +#include +#include +#include + +class QGraphicsProxyWidget; + +/**An annotation item that embedds a designer form showing the feature attribute*/ +class GUI_EXPORT QgsHtmlAnnotationItem: public QObject, public QgsAnnotationItem +{ + Q_OBJECT + public: + QgsHtmlAnnotationItem( QgsMapCanvas* canvas, QgsVectorLayer* vlayer = 0, bool hasFeature = false, int feature = 0 ); + ~QgsHtmlAnnotationItem(); + + void paint( QPainter * painter ); + + //! paint function called by map canvas + void paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0 ); + + QSizeF minimumFrameSize() const; + + /**Reimplemented from QgsAnnotationItem*/ + void setMapPosition( const QgsPoint& pos ); + + void setHTMLPage( const QString& htmlFile ); + QString htmlPage() const { return mHtmlFile; } + + void writeXML( QDomDocument& doc ) const; + void readXML( const QDomDocument& doc, const QDomElement& itemElem ); + + QgsVectorLayer* vectorLayer() const { return mVectorLayer; } + + private slots: + /**Sets a feature for the current map position and updates the dialog*/ + void setFeatureForMapPosition(); + /**Sets visibility status based on mVectorLayer visibility*/ + void updateVisibility(); + + void javascript(); + + private: + QGraphicsProxyWidget* mWidgetContainer; + QWebView* mWebView; + /**Associated vectorlayer (or 0 if attributes are not supposed to be replaced)*/ + QgsVectorLayer* mVectorLayer; + /**True if the item is related to a vector feature*/ + bool mHasAssociatedFeature; + /**Associated feature*/ + QgsFeatureId mFeatureId; + QgsFeature mFeature; + QString mHtmlFile; + QString mHtmlSource; + + QString replaceText( QString displayText, QgsVectorLayer *layer, QgsFeature &feat ); +}; + +#endif // QGSHTMLANNOTATIONITEM_H diff --git a/src/ui/qgisapp.ui b/src/ui/qgisapp.ui index 933f3d1ba666..fb654d527efd 100644 --- a/src/ui/qgisapp.ui +++ b/src/ui/qgisapp.ui @@ -1788,7 +1788,7 @@ Acts on all editable layers - + true @@ -1803,6 +1803,19 @@ Acts on all editable layers Click or marquee on feature to show label Shift+click or marquee on label to hide it Acts on currently active editable layer + + + + + + :/images/themes/default/mActionFormAnnotation.png:/images/themes/default/mActionFormAnnotation.png + + + + Html Annotation + + + Html Annotation