QGIS API Documentation  3.6.0-Noosa (5873452)
qgsformannotation.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsformannotation.cpp
3  ------------------------
4  begin : February 26, 2010
5  copyright : (C) 2010 by Marco Hugentobler
6  email : marco dot hugentobler at hugis dot net
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include "qgsformannotation.h"
21 #include "qgseditorwidgetwrapper.h"
22 #include "qgsfeature.h"
23 #include "qgsfeatureiterator.h"
24 #include "qgslogger.h"
25 #include "qgsmapcanvas.h"
26 #include "qgsproject.h"
27 #include "qgsmaptool.h"
28 #include "qgsvectorlayer.h"
29 #include "qgsgui.h"
30 #include <QDomElement>
31 #include <QDir>
32 #include <QFile>
33 #include <QFileInfo>
34 #include <QGraphicsProxyWidget>
35 #include <QPainter>
36 #include <QSettings>
37 #include <QUiLoader>
38 #include <QWidget>
39 
41  : QgsAnnotation( parent )
42 {}
43 
45 {
46  std::unique_ptr< QgsFormAnnotation > c( new QgsFormAnnotation() );
47  copyCommonProperties( c.get() );
48  c->setDesignerForm( mDesignerForm );
49  return c.release();
50 }
51 
52 void QgsFormAnnotation::setDesignerForm( const QString &uiFile )
53 {
54  mDesignerForm = uiFile;
55  mDesignerWidget.reset( createDesignerWidget( uiFile ) );
56  if ( mDesignerWidget )
57  {
58  mMinimumSize = mDesignerWidget->minimumSize();
59  if ( fillSymbol() )
60  {
61  QgsFillSymbol *newFill = fillSymbol()->clone();
62  newFill->setColor( mDesignerWidget->palette().color( QPalette::Window ) );
63  setFillSymbol( newFill );
64  }
66  }
67  emit appearanceChanged();
68 }
69 
70 QWidget *QgsFormAnnotation::createDesignerWidget( const QString &filePath )
71 {
72  QFile file( filePath );
73  if ( !file.open( QFile::ReadOnly ) )
74  {
75  return nullptr;
76  }
77 
78  QUiLoader loader;
79  QFileInfo fi( file );
80  loader.setWorkingDirectory( fi.dir() );
81  QWidget *widget = loader.load( &file, nullptr );
82  file.close();
83 
84  //get feature and set attribute information
86  QgsVectorLayer *vectorLayer = qobject_cast< QgsVectorLayer * >( mapLayer() );
87  if ( vectorLayer && associatedFeature().isValid() )
88  {
89  QgsFields fields = vectorLayer->fields();
91  for ( int i = 0; i < attrs.count(); ++i )
92  {
93  if ( i < fields.count() )
94  {
95  QWidget *attWidget = widget->findChild<QWidget *>( fields.at( i ).name() );
96  if ( attWidget )
97  {
98  QgsEditorWidgetWrapper *eww = QgsGui::editorWidgetRegistry()->create( vectorLayer, i, attWidget, widget, context );
99  if ( eww )
100  {
101  eww->setValue( attrs.at( i ) );
102  }
103  }
104  }
105  }
106  }
107  return widget;
108 }
109 
110 void QgsFormAnnotation::renderAnnotation( QgsRenderContext &context, QSizeF size ) const
111 {
112  if ( !mDesignerWidget )
113  return;
114 
115  mDesignerWidget->setFixedSize( size.toSize() );
116  context.painter()->setBrush( Qt::NoBrush );
117  context.painter()->setPen( Qt::NoPen );
118  mDesignerWidget->render( context.painter(), QPoint( 0, 0 ) );
119 }
120 
122 {
123  if ( mDesignerWidget )
124  {
125  QSizeF widgetMinSize = mMinimumSize;
126  return QSizeF( contentsMargin().left() + contentsMargin().right() + widgetMinSize.width(),
127  contentsMargin().top() + contentsMargin().bottom() + widgetMinSize.height() );
128  }
129  else
130  {
131  return QSizeF( 0, 0 );
132  }
133 }
134 
136 {
137  if ( mDesignerWidget )
138  {
139  return mDesignerWidget->sizeHint();
140  }
141  else
142  {
143  return QSizeF( 0, 0 );
144  }
145 }
146 
147 void QgsFormAnnotation::writeXml( QDomElement &elem, QDomDocument &doc, const QgsReadWriteContext &context ) const
148 {
149  QDomElement formAnnotationElem = doc.createElement( QStringLiteral( "FormAnnotationItem" ) );
150  formAnnotationElem.setAttribute( QStringLiteral( "designerForm" ), mDesignerForm );
151  _writeXml( formAnnotationElem, doc, context );
152  elem.appendChild( formAnnotationElem );
153 }
154 
155 void QgsFormAnnotation::readXml( const QDomElement &itemElem, const QgsReadWriteContext &context )
156 {
157  mDesignerForm = itemElem.attribute( QStringLiteral( "designerForm" ), QString() );
158  QDomElement annotationElem = itemElem.firstChildElement( QStringLiteral( "AnnotationItem" ) );
159  if ( !annotationElem.isNull() )
160  {
161  _readXml( annotationElem, context );
162  }
163  // upgrade old layer
164  if ( !mapLayer() && itemElem.hasAttribute( QStringLiteral( "vectorLayer" ) ) )
165  {
166  setMapLayer( QgsProject::instance()->mapLayer( itemElem.attribute( QStringLiteral( "vectorLayer" ) ) ) );
167  }
168 
169  mDesignerWidget.reset( createDesignerWidget( mDesignerForm ) );
170  if ( mDesignerWidget && fillSymbol() )
171  {
172  QgsFillSymbol *newFill = fillSymbol()->clone();
173  newFill->setColor( mDesignerWidget->palette().color( QPalette::Window ) );
174  setFillSymbol( newFill );
175  }
176 }
177 
179 {
181 
182  //create new embedded widget
183  mDesignerWidget.reset( createDesignerWidget( mDesignerForm ) );
184  if ( mDesignerWidget && fillSymbol() )
185  {
186  QgsFillSymbol *newFill = fillSymbol()->clone();
187  newFill->setColor( mDesignerWidget->palette().color( QPalette::Window ) );
188  setFillSymbol( newFill );
189  }
190  emit appearanceChanged();
191 }
192 
193 
194 
void writeXml(QDomElement &elem, QDomDocument &doc, const QgsReadWriteContext &context) const override
Writes the annotation state to a DOM element.
bool isValid() const
Returns the validity of this feature.
Definition: qgsfeature.cpp:183
The class is used as a container of context for various read/write operations on other objects...
void appearanceChanged()
Emitted whenever the annotation&#39;s appearance changes.
void setDesignerForm(const QString &uiFile)
Sets the path to the Qt Designer UI file to show in the annotation.
void _writeXml(QDomElement &itemElem, QDomDocument &doc, const QgsReadWriteContext &context) const
Writes common annotation properties to a DOM element.
QString name
Definition: qgsfield.h:58
void setMapLayer(QgsMapLayer *layer)
Sets the map layer associated with the annotation.
QgsFormAnnotation * clone() const override
Clones the annotation, returning a new copy of the annotation reflecting the annotation&#39;s current sta...
QSizeF minimumFrameSize() const override
Returns the minimum frame size for the annotation.
This class contains context information for attribute editor widgets.
Manages an editor widget Widget and wrapper share the same parent.
void readXml(const QDomElement &itemElem, const QgsReadWriteContext &context) override
Restores the annotation&#39;s state from a DOM element.
Container of fields for a vector layer.
Definition: qgsfields.h:42
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:55
void copyCommonProperties(QgsAnnotation *target) const
Copies common annotation properties to the targe annotation.
int count() const
Returns number of items.
Definition: qgsfields.cpp:133
Abstract base class for annotation items which are drawn over a map.
Definition: qgsannotation.h:49
QgsField at(int i) const
Gets field at particular index (must be in range 0..N-1)
Definition: qgsfields.cpp:163
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
QgsFields fields() const FINAL
Returns the list of fields of this layer.
QgsMargins contentsMargin() const
Returns the margins (in millimeters) between the outside of the frame and the annotation content...
QgsFillSymbol * clone() const override
Returns a deep copy of this symbol.
Definition: qgssymbol.cpp:1941
void setAssociatedFeature(const QgsFeature &feature) override
Sets the feature associated with the annotation.
double bottom() const
Returns the bottom margin.
Definition: qgsmargins.h:90
static QgsEditorWidgetRegistry * editorWidgetRegistry()
Returns the global editor widget registry, used for managing all known edit widget factories...
Definition: qgsgui.cpp:59
QgsFormAnnotation(QObject *parent=nullptr)
Constructor for QgsFormAnnotation.
double top() const
Returns the top margin.
Definition: qgsmargins.h:78
virtual void setValue(const QVariant &value)=0
Is called, when the value of the widget needs to be changed.
void _readXml(const QDomElement &annotationElem, const QgsReadWriteContext &context)
Reads common annotation properties from a DOM element.
QgsEditorWidgetWrapper * create(const QString &widgetId, QgsVectorLayer *vl, int fieldIdx, const QVariantMap &config, QWidget *editor, QWidget *parent, const QgsAttributeEditorContext &context=QgsAttributeEditorContext())
Create an attribute editor widget wrapper of a given type for a given field.
void setFrameSize(QSizeF size)
Sets the size of the annotation&#39;s frame (the main area in which the annotation&#39;s content is drawn)...
QgsMapLayer * mapLayer() const
Returns the map layer associated with the annotation.
Contains information about the context of a rendering operation.
QPainter * painter()
Returns the destination QPainter for the render operation.
void renderAnnotation(QgsRenderContext &context, QSizeF size) const override
Renders the annotation&#39;s contents to a target /a context at the specified /a size.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:430
QSizeF preferredFrameSize() const
Returns the optimal frame size.
QgsFeature associatedFeature() const
Returns the feature associated with the annotation, or an invalid feature if none has been set...
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
Definition: qgssymbol.h:1003
void setFillSymbol(QgsFillSymbol *symbol)
Sets the fill symbol used for rendering the annotation frame.
A vector of attributes.
Definition: qgsattributes.h:57
Represents a vector layer which manages a vector based data sets.
virtual void setAssociatedFeature(const QgsFeature &feature)
Sets the feature associated with the annotation.
An annotation item that embeds a designer form showing the feature attribute.
QgsFillSymbol * fillSymbol() const
Returns the symbol that is used for rendering the annotation frame.
QgsAttributes attributes
Definition: qgsfeature.h:65
void setColor(const QColor &color)
Sets the color for the symbol.
Definition: qgssymbol.cpp:452