Quantum GIS API Documentation  master-ce49b66
src/gui/qgshtmlannotationitem.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002                               qgshtmlannotationitem.h
00003                               ------------------------
00004   begin                : February 26, 2010
00005   copyright            : (C) 2010 by Marco Hugentobler
00006   email                : marco dot hugentobler at hugis dot net
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00018 #include "qgshtmlannotationitem.h"
00019 #include "qgsattributeeditor.h"
00020 #include "qgsfeature.h"
00021 #include "qgslogger.h"
00022 #include "qgsmapcanvas.h"
00023 #include "qgsmaplayerregistry.h"
00024 #include "qgsvectorlayer.h"
00025 #include "qgsexpression.h"
00026 
00027 #include <QDomElement>
00028 #include <QDir>
00029 #include <QFile>
00030 #include <QFileInfo>
00031 #include <QGraphicsProxyWidget>
00032 #include <QPainter>
00033 #include <QSettings>
00034 #include <QWidget>
00035 
00036 
00037 QgsHtmlAnnotationItem::QgsHtmlAnnotationItem( QgsMapCanvas* canvas, QgsVectorLayer* vlayer, bool hasFeature, int feature )
00038     : QgsAnnotationItem( canvas ), mWidgetContainer( 0 ), mWebView( 0 ), mVectorLayer( vlayer ),
00039     mHasAssociatedFeature( hasFeature ), mFeatureId( feature )
00040 {
00041   mWebView = new QWebView();
00042   mWidgetContainer = new QGraphicsProxyWidget( this );
00043   mWidgetContainer->setWidget( mWebView );
00044 
00045   QObject::connect( mWebView->page()->mainFrame(), SIGNAL( javaScriptWindowObjectCleared() ), this, SLOT( javascript() ) );
00046 
00047   if ( mVectorLayer && mMapCanvas )
00048   {
00049     QObject::connect( mVectorLayer, SIGNAL( layerModified() ), this, SLOT( setFeatureForMapPosition() ) );
00050     QObject::connect( mMapCanvas, SIGNAL( renderComplete( QPainter* ) ), this, SLOT( setFeatureForMapPosition() ) );
00051     QObject::connect( mMapCanvas, SIGNAL( layersChanged() ), this, SLOT( updateVisibility() ) );
00052   }
00053 
00054   setFeatureForMapPosition();
00055 }
00056 
00057 QgsHtmlAnnotationItem::~QgsHtmlAnnotationItem()
00058 {
00059   delete mWebView;
00060 }
00061 
00062 void QgsHtmlAnnotationItem::setHTMLPage( const QString& htmlFile )
00063 {
00064   QFile file( htmlFile );
00065   mHtmlFile = htmlFile;
00066   if ( !file.open( QIODevice::ReadOnly | QIODevice::Text ) )
00067   {
00068     mHtmlSource = "";
00069   }
00070   else
00071   {
00072     QTextStream in( &file );
00073     in.setCodec( "UTF-8" );
00074     mHtmlSource = in.readAll();
00075   }
00076 
00077   file.close();
00078   setFeatureForMapPosition();
00079 }
00080 
00081 void QgsHtmlAnnotationItem::setMapPosition( const QgsPoint& pos )
00082 {
00083   QgsAnnotationItem::setMapPosition( pos );
00084   setFeatureForMapPosition();
00085 }
00086 
00087 void QgsHtmlAnnotationItem::paint( QPainter * painter )
00088 {
00089   Q_UNUSED( painter );
00090 }
00091 
00092 void QgsHtmlAnnotationItem::paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget )
00093 {
00094   Q_UNUSED( option );
00095   Q_UNUSED( widget );
00096   if ( !painter || !mWidgetContainer )
00097   {
00098     return;
00099   }
00100 
00101   drawFrame( painter );
00102   if ( mMapPositionFixed )
00103   {
00104     drawMarkerSymbol( painter );
00105   }
00106 
00107   mWidgetContainer->setGeometry( QRectF( mOffsetFromReferencePoint.x() + mFrameBorderWidth / 2.0, mOffsetFromReferencePoint.y()
00108                                          + mFrameBorderWidth / 2.0, mFrameSize.width() - mFrameBorderWidth, mFrameSize.height()
00109                                          - mFrameBorderWidth ) );
00110   if ( data( 1 ).toString() == "composer" )
00111   {
00112     mWidgetContainer->widget()->render( painter, mOffsetFromReferencePoint.toPoint() );
00113   }
00114 
00115   if ( isSelected() )
00116   {
00117     drawSelectionBoxes( painter );
00118   }
00119 }
00120 
00121 QSizeF QgsHtmlAnnotationItem::minimumFrameSize() const
00122 {
00123   if ( mWebView )
00124   {
00125     QSizeF widgetMinSize = mWebView->minimumSize();
00126     return QSizeF( 2 * mFrameBorderWidth + widgetMinSize.width(), 2 * mFrameBorderWidth + widgetMinSize.height() );
00127   }
00128   else
00129   {
00130     return QSizeF( 0, 0 );
00131   }
00132 }
00133 
00134 void QgsHtmlAnnotationItem::writeXML( QDomDocument& doc ) const
00135 {
00136   QDomElement documentElem = doc.documentElement();
00137   if ( documentElem.isNull() )
00138   {
00139     return;
00140   }
00141 
00142   QDomElement formAnnotationElem = doc.createElement( "HtmlAnnotationItem" );
00143   if ( mVectorLayer )
00144   {
00145     formAnnotationElem.setAttribute( "vectorLayer", mVectorLayer->id() );
00146   }
00147   formAnnotationElem.setAttribute( "hasFeature", mHasAssociatedFeature );
00148   formAnnotationElem.setAttribute( "feature", mFeatureId );
00149   formAnnotationElem.setAttribute( "htmlfile", htmlPage() );
00150 
00151   _writeXML( doc, formAnnotationElem );
00152   documentElem.appendChild( formAnnotationElem );
00153 }
00154 
00155 void QgsHtmlAnnotationItem::readXML( const QDomDocument& doc, const QDomElement& itemElem )
00156 {
00157   mVectorLayer = 0;
00158   if ( itemElem.hasAttribute( "vectorLayer" ) )
00159   {
00160     mVectorLayer = dynamic_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( itemElem.attribute( "vectorLayer", "" ) ) );
00161     if ( mVectorLayer )
00162     {
00163       QObject::connect( mVectorLayer, SIGNAL( layerModified() ), this, SLOT( setFeatureForMapPosition() ) );
00164       QObject::connect( mMapCanvas, SIGNAL( renderComplete( QPainter* ) ), this, SLOT( setFeatureForMapPosition() ) );
00165       QObject::connect( mMapCanvas, SIGNAL( layersChanged() ), this, SLOT( updateVisibility() ) );
00166     }
00167   }
00168   mHasAssociatedFeature = itemElem.attribute( "hasFeature", "0" ).toInt();
00169   mFeatureId = itemElem.attribute( "feature", "0" ).toInt();
00170   mHtmlFile = itemElem.attribute( "htmlfile", "" );
00171   QDomElement annotationElem = itemElem.firstChildElement( "AnnotationItem" );
00172   if ( !annotationElem.isNull() )
00173   {
00174     _readXML( doc, annotationElem );
00175   }
00176 
00177   if ( mWebView )
00178   {
00179     setHTMLPage( mHtmlFile );
00180   }
00181   updateVisibility();
00182 }
00183 
00184 void QgsHtmlAnnotationItem::setFeatureForMapPosition()
00185 {
00186   if ( !mVectorLayer || !mMapCanvas )
00187   {
00188     return;
00189   }
00190 
00191   QSettings settings;
00192   double identifyValue = settings.value( "/Map/identifyRadius", QGis::DEFAULT_IDENTIFY_RADIUS ).toDouble();
00193   double halfIdentifyWidth = mMapCanvas->extent().width() / 100 / 2 * identifyValue;
00194   QgsRectangle searchRect( mMapPosition.x() - halfIdentifyWidth, mMapPosition.y() - halfIdentifyWidth,
00195                            mMapPosition.x() + halfIdentifyWidth, mMapPosition.y() + halfIdentifyWidth );
00196 
00197   QgsFeatureIterator fit = mVectorLayer->getFeatures( QgsFeatureRequest().setFilterRect( searchRect ).setFlags( QgsFeatureRequest::NoGeometry | QgsFeatureRequest::ExactIntersect ) );
00198 
00199   QgsFeature currentFeature;
00200   QgsFeatureId currentFeatureId = 0;
00201   bool featureFound = false;
00202 
00203   while ( fit.nextFeature( currentFeature ) )
00204   {
00205     currentFeatureId = currentFeature.id();
00206     featureFound = true;
00207     break;
00208   }
00209 
00210   mHasAssociatedFeature = featureFound;
00211   mFeatureId = currentFeatureId;
00212   mFeature = currentFeature;
00213 
00214   QString newtext = QgsExpression::replaceExpressionText( mHtmlSource, mFeature, vectorLayer() );
00215   mWebView->setHtml( newtext );
00216 }
00217 
00218 void QgsHtmlAnnotationItem::updateVisibility()
00219 {
00220   bool visible = true;
00221   if ( mVectorLayer && mMapCanvas )
00222   {
00223     visible = mMapCanvas->layers().contains( mVectorLayer );
00224   }
00225   setVisible( visible );
00226 }
00227 
00228 void QgsHtmlAnnotationItem::javascript()
00229 {
00230   QWebFrame *frame = mWebView->page()->mainFrame();
00231   frame->addToJavaScriptWindowObject( "canvas", mMapCanvas );
00232   frame->addToJavaScriptWindowObject( "layer", mVectorLayer );
00233 }
00234 
00235 
00236 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines