Quantum GIS API Documentation  1.7.4
src/gui/qgsformannotationitem.cpp
Go to the documentation of this file.
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( bool ) ), 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->featureAtId( mFeature, f, false, true ) )
00089     {
00090       const QgsFieldMap& fieldMap = mVectorLayer->pendingFields();
00091       QgsAttributeMap attMap = f.attributeMap();
00092       QgsAttributeMap::const_iterator attIt = attMap.constBegin();
00093       for ( ; attIt != attMap.constEnd(); ++attIt )
00094       {
00095         QgsFieldMap::const_iterator fieldIt = fieldMap.find( attIt.key() );
00096         if ( fieldIt != fieldMap.constEnd() )
00097         {
00098           QWidget* attWidget = widget->findChild<QWidget*>( fieldIt->name() );
00099           if ( attWidget )
00100           {
00101             QgsAttributeEditor::createAttributeEditor( widget, attWidget, mVectorLayer, attIt.key(), attIt.value() );
00102           }
00103         }
00104       }
00105     }
00106   }
00107   return widget;
00108 }
00109 
00110 void QgsFormAnnotationItem::setMapPosition( const QgsPoint& pos )
00111 {
00112   QgsAnnotationItem::setMapPosition( pos );
00113   setFeatureForMapPosition();
00114 }
00115 
00116 void QgsFormAnnotationItem::paint( QPainter * painter )
00117 {
00118 
00119 }
00120 
00121 void QgsFormAnnotationItem::paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget )
00122 {
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( bool ) ), 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   QgsAttributeList noAttributes;
00228   QSettings settings;
00229   double identifyValue = settings.value( "/Map/identifyRadius", QGis::DEFAULT_IDENTIFY_RADIUS ).toDouble();
00230   double halfIdentifyWidth = mMapCanvas->extent().width() / 100 / 2 * identifyValue;
00231   QgsRectangle searchRect( mMapPosition.x() - halfIdentifyWidth, mMapPosition.y() - halfIdentifyWidth, \
00232                            mMapPosition.x() + halfIdentifyWidth, mMapPosition.y() + halfIdentifyWidth );
00233   mVectorLayer->select( noAttributes, searchRect, false, true );
00234 
00235   QgsFeature currentFeature;
00236   int currentFeatureId = 0;
00237   bool featureFound = false;
00238 
00239   while ( mVectorLayer->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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines