|
Quantum GIS API Documentation
master-ce49b66
|
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