|
QGIS API Documentation
master-3f58142
|
00001 /*************************************************************************** 00002 qgsformannotationitem.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 "qgsformannotationitem.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 <QDomElement> 00026 #include <QDir> 00027 #include <QFile> 00028 #include <QFileInfo> 00029 #include <QGraphicsProxyWidget> 00030 #include <QPainter> 00031 #include <QSettings> 00032 #include <QUiLoader> 00033 #include <QWidget> 00034 00035 QgsFormAnnotationItem::QgsFormAnnotationItem( QgsMapCanvas* canvas, QgsVectorLayer* vlayer, bool hasFeature, int feature ) 00036 : QgsAnnotationItem( canvas ), mWidgetContainer( 0 ), mDesignerWidget( 0 ), mVectorLayer( vlayer ), 00037 mHasAssociatedFeature( hasFeature ), mFeature( feature ) 00038 { 00039 mWidgetContainer = new QGraphicsProxyWidget( this ); 00040 if ( mVectorLayer && mMapCanvas ) //default to the layers edit form 00041 { 00042 mDesignerForm = mVectorLayer->annotationForm(); 00043 QObject::connect( mVectorLayer, SIGNAL( layerModified() ), this, SLOT( setFeatureForMapPosition() ) ); 00044 QObject::connect( mMapCanvas, SIGNAL( renderComplete( QPainter* ) ), this, SLOT( setFeatureForMapPosition() ) ); 00045 QObject::connect( mMapCanvas, SIGNAL( layersChanged() ), this, SLOT( updateVisibility() ) ); 00046 } 00047 00048 setFeatureForMapPosition(); 00049 } 00050 00051 QgsFormAnnotationItem::~QgsFormAnnotationItem() 00052 { 00053 delete mDesignerWidget; 00054 } 00055 00056 void QgsFormAnnotationItem::setDesignerForm( const QString& uiFile ) 00057 { 00058 mDesignerForm = uiFile; 00059 mWidgetContainer->setWidget( 0 ); 00060 delete mDesignerWidget; 00061 mDesignerWidget = createDesignerWidget( uiFile ); 00062 if ( mDesignerWidget ) 00063 { 00064 mFrameBackgroundColor = mDesignerWidget->palette().color( QPalette::Window ); 00065 mWidgetContainer->setWidget( mDesignerWidget ); 00066 setFrameSize( preferredFrameSize() ); 00067 } 00068 } 00069 00070 QWidget* QgsFormAnnotationItem::createDesignerWidget( const QString& filePath ) 00071 { 00072 QFile file( filePath ); 00073 if ( !file.open( QFile::ReadOnly ) ) 00074 { 00075 return 0; 00076 } 00077 00078 QUiLoader loader; 00079 QFileInfo fi( file ); 00080 loader.setWorkingDirectory( fi.dir() ); 00081 QWidget* widget = loader.load( &file, 0 ); 00082 file.close(); 00083 00084 //get feature and set attribute information 00085 if ( mVectorLayer && mHasAssociatedFeature ) 00086 { 00087 QgsFeature f; 00088 if ( mVectorLayer->getFeatures( QgsFeatureRequest().setFilterFid( mFeature ).setFlags( QgsFeatureRequest::NoGeometry ) ).nextFeature( f ) ) 00089 { 00090 const QgsFields& fields = mVectorLayer->pendingFields(); 00091 const QgsAttributes& attrs = f.attributes(); 00092 for ( int i = 0; i < attrs.count(); ++i ) 00093 { 00094 if ( i < fields.count() ) 00095 { 00096 QWidget* attWidget = widget->findChild<QWidget*>( fields[i].name() ); 00097 if ( attWidget ) 00098 { 00099 QgsAttributeEditor::createAttributeEditor( widget, attWidget, mVectorLayer, i, attrs[i] ); 00100 } 00101 } 00102 } 00103 } 00104 } 00105 return widget; 00106 } 00107 00108 void QgsFormAnnotationItem::setMapPosition( const QgsPoint& pos ) 00109 { 00110 QgsAnnotationItem::setMapPosition( pos ); 00111 setFeatureForMapPosition(); 00112 } 00113 00114 void QgsFormAnnotationItem::paint( QPainter * painter ) 00115 { 00116 Q_UNUSED( painter ); 00117 } 00118 00119 void QgsFormAnnotationItem::paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget ) 00120 { 00121 Q_UNUSED( option ); 00122 Q_UNUSED( widget ); 00123 if ( !painter || !mWidgetContainer ) 00124 { 00125 return; 00126 } 00127 00128 drawFrame( painter ); 00129 if ( mMapPositionFixed ) 00130 { 00131 drawMarkerSymbol( painter ); 00132 } 00133 00134 mWidgetContainer->setGeometry( QRectF( mOffsetFromReferencePoint.x() + mFrameBorderWidth / 2.0, mOffsetFromReferencePoint.y() 00135 + mFrameBorderWidth / 2.0, mFrameSize.width() - mFrameBorderWidth, mFrameSize.height() 00136 - mFrameBorderWidth ) ); 00137 00138 if ( isSelected() ) 00139 { 00140 drawSelectionBoxes( painter ); 00141 } 00142 } 00143 00144 QSizeF QgsFormAnnotationItem::minimumFrameSize() const 00145 { 00146 if ( mDesignerWidget ) 00147 { 00148 QSizeF widgetMinSize = mDesignerWidget->minimumSize(); 00149 return QSizeF( 2 * mFrameBorderWidth + widgetMinSize.width(), 2 * mFrameBorderWidth + widgetMinSize.height() ); 00150 } 00151 else 00152 { 00153 return QSizeF( 0, 0 ); 00154 } 00155 } 00156 00157 QSizeF QgsFormAnnotationItem::preferredFrameSize() const 00158 { 00159 if ( mDesignerWidget ) 00160 { 00161 return mDesignerWidget->sizeHint(); 00162 } 00163 else 00164 { 00165 return QSizeF( 0, 0 ); 00166 } 00167 } 00168 00169 void QgsFormAnnotationItem::writeXML( QDomDocument& doc ) const 00170 { 00171 QDomElement documentElem = doc.documentElement(); 00172 if ( documentElem.isNull() ) 00173 { 00174 return; 00175 } 00176 00177 QDomElement formAnnotationElem = doc.createElement( "FormAnnotationItem" ); 00178 if ( mVectorLayer ) 00179 { 00180 formAnnotationElem.setAttribute( "vectorLayer", mVectorLayer->id() ); 00181 } 00182 formAnnotationElem.setAttribute( "hasFeature", mHasAssociatedFeature ); 00183 formAnnotationElem.setAttribute( "feature", mFeature ); 00184 formAnnotationElem.setAttribute( "designerForm", mDesignerForm ); 00185 _writeXML( doc, formAnnotationElem ); 00186 documentElem.appendChild( formAnnotationElem ); 00187 } 00188 00189 void QgsFormAnnotationItem::readXML( const QDomDocument& doc, const QDomElement& itemElem ) 00190 { 00191 mVectorLayer = 0; 00192 if ( itemElem.hasAttribute( "vectorLayer" ) ) 00193 { 00194 mVectorLayer = dynamic_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( itemElem.attribute( "vectorLayer", "" ) ) ); 00195 if ( mVectorLayer ) 00196 { 00197 QObject::connect( mVectorLayer, SIGNAL( layerModified() ), this, SLOT( setFeatureForMapPosition() ) ); 00198 QObject::connect( mMapCanvas, SIGNAL( renderComplete( QPainter* ) ), this, SLOT( setFeatureForMapPosition() ) ); 00199 QObject::connect( mMapCanvas, SIGNAL( layersChanged() ), this, SLOT( updateVisibility() ) ); 00200 } 00201 } 00202 mHasAssociatedFeature = itemElem.attribute( "hasFeature", "0" ).toInt(); 00203 mFeature = itemElem.attribute( "feature", "0" ).toInt(); 00204 mDesignerForm = itemElem.attribute( "designerForm", "" ); 00205 QDomElement annotationElem = itemElem.firstChildElement( "AnnotationItem" ); 00206 if ( !annotationElem.isNull() ) 00207 { 00208 _readXML( doc, annotationElem ); 00209 } 00210 00211 mDesignerWidget = createDesignerWidget( mDesignerForm ); 00212 if ( mDesignerWidget ) 00213 { 00214 mFrameBackgroundColor = mDesignerWidget->palette().color( QPalette::Window ); 00215 mWidgetContainer->setWidget( mDesignerWidget ); 00216 } 00217 updateVisibility(); 00218 } 00219 00220 void QgsFormAnnotationItem::setFeatureForMapPosition() 00221 { 00222 if ( !mVectorLayer || !mMapCanvas ) 00223 { 00224 return; 00225 } 00226 00227 QSettings settings; 00228 double identifyValue = settings.value( "/Map/identifyRadius", QGis::DEFAULT_IDENTIFY_RADIUS ).toDouble(); 00229 double halfIdentifyWidth = mMapCanvas->extent().width() / 100 / 2 * identifyValue; 00230 QgsRectangle searchRect( mMapPosition.x() - halfIdentifyWidth, mMapPosition.y() - halfIdentifyWidth, 00231 mMapPosition.x() + halfIdentifyWidth, mMapPosition.y() + halfIdentifyWidth ); 00232 00233 QgsFeatureIterator fit = mVectorLayer->getFeatures( QgsFeatureRequest().setFilterRect( searchRect ).setFlags( QgsFeatureRequest::NoGeometry | QgsFeatureRequest::ExactIntersect ).setSubsetOfAttributes( QgsAttributeList() ) ); 00234 00235 QgsFeature currentFeature; 00236 QgsFeatureId currentFeatureId = 0; 00237 bool featureFound = false; 00238 00239 while ( fit.nextFeature( currentFeature ) ) 00240 { 00241 currentFeatureId = currentFeature.id(); 00242 featureFound = true; 00243 break; 00244 } 00245 00246 mHasAssociatedFeature = featureFound; 00247 mFeature = currentFeatureId; 00248 00249 //create new embedded widget 00250 mWidgetContainer->setWidget( 0 ); 00251 delete mDesignerWidget; 00252 mDesignerWidget = createDesignerWidget( mDesignerForm ); 00253 if ( mDesignerWidget ) 00254 { 00255 mFrameBackgroundColor = mDesignerWidget->palette().color( QPalette::Window ); 00256 mWidgetContainer->setWidget( mDesignerWidget ); 00257 } 00258 } 00259 00260 void QgsFormAnnotationItem::updateVisibility() 00261 { 00262 bool visible = true; 00263 if ( mVectorLayer && mMapCanvas ) 00264 { 00265 visible = mMapCanvas->layers().contains( mVectorLayer ); 00266 } 00267 setVisible( visible ); 00268 } 00269 00270 00271