Quantum GIS API Documentation  1.8
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   Q_UNUSED( painter );
00119 }
00120 
00121 void QgsFormAnnotationItem::paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget )
00122 {
00123   Q_UNUSED( option );
00124   Q_UNUSED( widget );
00125   if ( !painter || !mWidgetContainer )
00126   {
00127     return;
00128   }
00129 
00130   drawFrame( painter );
00131   if ( mMapPositionFixed )
00132   {
00133     drawMarkerSymbol( painter );
00134   }
00135 
00136   mWidgetContainer->setGeometry( QRectF( mOffsetFromReferencePoint.x() + mFrameBorderWidth / 2.0, mOffsetFromReferencePoint.y()
00137                                          + mFrameBorderWidth / 2.0, mFrameSize.width() - mFrameBorderWidth, mFrameSize.height()
00138                                          - mFrameBorderWidth ) );
00139 
00140   if ( isSelected() )
00141   {
00142     drawSelectionBoxes( painter );
00143   }
00144 }
00145 
00146 QSizeF QgsFormAnnotationItem::minimumFrameSize() const
00147 {
00148   if ( mDesignerWidget )
00149   {
00150     QSizeF widgetMinSize = mDesignerWidget->minimumSize();
00151     return QSizeF( 2 * mFrameBorderWidth + widgetMinSize.width(), 2 * mFrameBorderWidth + widgetMinSize.height() );
00152   }
00153   else
00154   {
00155     return QSizeF( 0, 0 );
00156   }
00157 }
00158 
00159 QSizeF QgsFormAnnotationItem::preferredFrameSize() const
00160 {
00161   if ( mDesignerWidget )
00162   {
00163     return mDesignerWidget->sizeHint();
00164   }
00165   else
00166   {
00167     return QSizeF( 0, 0 );
00168   }
00169 }
00170 
00171 void QgsFormAnnotationItem::writeXML( QDomDocument& doc ) const
00172 {
00173   QDomElement documentElem = doc.documentElement();
00174   if ( documentElem.isNull() )
00175   {
00176     return;
00177   }
00178 
00179   QDomElement formAnnotationElem = doc.createElement( "FormAnnotationItem" );
00180   if ( mVectorLayer )
00181   {
00182     formAnnotationElem.setAttribute( "vectorLayer", mVectorLayer->id() );
00183   }
00184   formAnnotationElem.setAttribute( "hasFeature", mHasAssociatedFeature );
00185   formAnnotationElem.setAttribute( "feature", mFeature );
00186   formAnnotationElem.setAttribute( "designerForm", mDesignerForm );
00187   _writeXML( doc, formAnnotationElem );
00188   documentElem.appendChild( formAnnotationElem );
00189 }
00190 
00191 void QgsFormAnnotationItem::readXML( const QDomDocument& doc, const QDomElement& itemElem )
00192 {
00193   mVectorLayer = 0;
00194   if ( itemElem.hasAttribute( "vectorLayer" ) )
00195   {
00196     mVectorLayer = dynamic_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( itemElem.attribute( "vectorLayer", "" ) ) );
00197     if ( mVectorLayer )
00198     {
00199       QObject::connect( mVectorLayer, SIGNAL( layerModified( bool ) ), this, SLOT( setFeatureForMapPosition() ) );
00200       QObject::connect( mMapCanvas, SIGNAL( renderComplete( QPainter* ) ), this, SLOT( setFeatureForMapPosition() ) );
00201       QObject::connect( mMapCanvas, SIGNAL( layersChanged() ), this, SLOT( updateVisibility() ) );
00202     }
00203   }
00204   mHasAssociatedFeature = itemElem.attribute( "hasFeature", "0" ).toInt();
00205   mFeature = itemElem.attribute( "feature", "0" ).toInt();
00206   mDesignerForm = itemElem.attribute( "designerForm", "" );
00207   QDomElement annotationElem = itemElem.firstChildElement( "AnnotationItem" );
00208   if ( !annotationElem.isNull() )
00209   {
00210     _readXML( doc, annotationElem );
00211   }
00212 
00213   mDesignerWidget = createDesignerWidget( mDesignerForm );
00214   if ( mDesignerWidget )
00215   {
00216     mFrameBackgroundColor = mDesignerWidget->palette().color( QPalette::Window );
00217     mWidgetContainer->setWidget( mDesignerWidget );
00218   }
00219   updateVisibility();
00220 }
00221 
00222 void QgsFormAnnotationItem::setFeatureForMapPosition()
00223 {
00224   if ( !mVectorLayer || !mMapCanvas )
00225   {
00226     return;
00227   }
00228 
00229   QgsAttributeList noAttributes;
00230   QSettings settings;
00231   double identifyValue = settings.value( "/Map/identifyRadius", QGis::DEFAULT_IDENTIFY_RADIUS ).toDouble();
00232   double halfIdentifyWidth = mMapCanvas->extent().width() / 100 / 2 * identifyValue;
00233   QgsRectangle searchRect( mMapPosition.x() - halfIdentifyWidth, mMapPosition.y() - halfIdentifyWidth,
00234                            mMapPosition.x() + halfIdentifyWidth, mMapPosition.y() + halfIdentifyWidth );
00235   mVectorLayer->select( noAttributes, searchRect, false, true );
00236 
00237   QgsFeature currentFeature;
00238   QgsFeatureId currentFeatureId = 0;
00239   bool featureFound = false;
00240 
00241   while ( mVectorLayer->nextFeature( currentFeature ) )
00242   {
00243     currentFeatureId = currentFeature.id();
00244     featureFound = true;
00245     break;
00246   }
00247 
00248   mHasAssociatedFeature = featureFound;
00249   mFeature = currentFeatureId;
00250 
00251   //create new embedded widget
00252   mWidgetContainer->setWidget( 0 );
00253   delete mDesignerWidget;
00254   mDesignerWidget = createDesignerWidget( mDesignerForm );
00255   if ( mDesignerWidget )
00256   {
00257     mFrameBackgroundColor = mDesignerWidget->palette().color( QPalette::Window );
00258     mWidgetContainer->setWidget( mDesignerWidget );
00259   }
00260 }
00261 
00262 void QgsFormAnnotationItem::updateVisibility()
00263 {
00264   bool visible = true;
00265   if ( mVectorLayer && mMapCanvas )
00266   {
00267     visible = mMapCanvas->layers().contains( mVectorLayer );
00268   }
00269   setVisible( visible );
00270 }
00271 
00272 
00273 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines