QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
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 ( auto *lFillSymbol = fillSymbol() )
60  {
61  QgsFillSymbol *newFill = lFillSymbol->clone();
62  newFill->setColor( mDesignerWidget->palette().color( QPalette::Window ) );
63  setFillSymbol( newFill );
64  }
65  // convert from size in pixels at 96 dpi to mm
66  setFrameSizeMm( preferredFrameSize() / 3.7795275 );
67  }
68  emit appearanceChanged();
69 }
70 
71 QWidget *QgsFormAnnotation::createDesignerWidget( const QString &filePath )
72 {
73  QFile file( filePath );
74  if ( !file.open( QFile::ReadOnly ) )
75  {
76  return nullptr;
77  }
78 
79  QUiLoader loader;
80  QFileInfo fi( file );
81  loader.setWorkingDirectory( fi.dir() );
82  QWidget *widget = loader.load( &file, nullptr );
83  file.close();
84 
85  //get feature and set attribute information
87  QgsVectorLayer *vectorLayer = qobject_cast< QgsVectorLayer * >( mapLayer() );
88  if ( vectorLayer && associatedFeature().isValid() )
89  {
90  QgsFields fields = vectorLayer->fields();
92  for ( int i = 0; i < attrs.count(); ++i )
93  {
94  if ( i < fields.count() )
95  {
96  QWidget *attWidget = widget->findChild<QWidget *>( fields.at( i ).name() );
97  if ( attWidget )
98  {
99  QgsEditorWidgetWrapper *eww = QgsGui::editorWidgetRegistry()->create( vectorLayer, i, attWidget, widget, context );
100  if ( eww )
101  {
102  const QStringList additionalFields = eww->additionalFields();
103  QVariantList additionalFieldValues;
104  for ( const QString &additionalField : additionalFields )
105  {
106  int index = vectorLayer->fields().indexFromName( additionalField );
107  additionalFieldValues.insert( index, attrs.at( index ) );
108  }
109  eww->setValues( attrs.at( i ), additionalFieldValues );
110  }
111  }
112  }
113  }
114  }
115  return widget;
116 }
117 
118 void QgsFormAnnotation::renderAnnotation( QgsRenderContext &context, QSizeF size ) const
119 {
120  if ( !mDesignerWidget )
121  return;
122 
123  // scale painter back to 96 dpi, so that forms look good even in layout prints
124  QgsScopedQPainterState painterState( context.painter() );
125  const double scaleFactor = context.painter()->device()->logicalDpiX() / 96.0;
126  context.painter()->scale( scaleFactor, scaleFactor );
127  size /= scaleFactor;
128 
129  mDesignerWidget->setFixedSize( size.toSize() );
130  context.painter()->setBrush( Qt::NoBrush );
131  context.painter()->setPen( Qt::NoPen );
132  mDesignerWidget->render( context.painter(), QPoint( 0, 0 ) );
133 }
134 
136 {
137  if ( mDesignerWidget )
138  {
139  QSizeF widgetMinSize = mMinimumSize;
140  return QSizeF( contentsMargin().left() + contentsMargin().right() + widgetMinSize.width(),
141  contentsMargin().top() + contentsMargin().bottom() + widgetMinSize.height() );
142  }
143  else
144  {
145  return QSizeF( 0, 0 );
146  }
147 }
148 
150 {
151  if ( mDesignerWidget )
152  {
153  return mDesignerWidget->sizeHint();
154  }
155  else
156  {
157  return QSizeF( 0, 0 );
158  }
159 }
160 
161 void QgsFormAnnotation::writeXml( QDomElement &elem, QDomDocument &doc, const QgsReadWriteContext &context ) const
162 {
163  QDomElement formAnnotationElem = doc.createElement( QStringLiteral( "FormAnnotationItem" ) );
164  formAnnotationElem.setAttribute( QStringLiteral( "designerForm" ), mDesignerForm );
165  _writeXml( formAnnotationElem, doc, context );
166  elem.appendChild( formAnnotationElem );
167 }
168 
169 void QgsFormAnnotation::readXml( const QDomElement &itemElem, const QgsReadWriteContext &context )
170 {
171  mDesignerForm = itemElem.attribute( QStringLiteral( "designerForm" ), QString() );
172  QDomElement annotationElem = itemElem.firstChildElement( QStringLiteral( "AnnotationItem" ) );
173  if ( !annotationElem.isNull() )
174  {
175  _readXml( annotationElem, context );
176  }
177  // upgrade old layer
178  if ( !mapLayer() && itemElem.hasAttribute( QStringLiteral( "vectorLayer" ) ) )
179  {
180  setMapLayer( QgsProject::instance()->mapLayer( itemElem.attribute( QStringLiteral( "vectorLayer" ) ) ) );
181  }
182 
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 }
191 
193 {
195 
196  //create new embedded widget
197  mDesignerWidget.reset( createDesignerWidget( mDesignerForm ) );
198  if ( mDesignerWidget && fillSymbol() )
199  {
200  QgsFillSymbol *newFill = fillSymbol()->clone();
201  newFill->setColor( mDesignerWidget->palette().color( QPalette::Window ) );
202  setFillSymbol( newFill );
203  }
204  emit appearanceChanged();
205 }
206 
207 
208 
QgsFormAnnotation::readXml
void readXml(const QDomElement &itemElem, const QgsReadWriteContext &context) override
Restores the annotation's state from a DOM element.
Definition: qgsformannotation.cpp:169
QgsGui::editorWidgetRegistry
static QgsEditorWidgetRegistry * editorWidgetRegistry()
Returns the global editor widget registry, used for managing all known edit widget factories.
Definition: qgsgui.cpp:74
qgseditorwidgetwrapper.h
QgsEditorWidgetWrapper::setValues
void setValues(const QVariant &value, const QVariantList &additionalValues)
Is called when the value of the widget or additional field values needs to be changed.
Definition: qgseditorwidgetwrapper.cpp:86
QgsFormAnnotation::clone
QgsFormAnnotation * clone() const override
Clones the annotation, returning a new copy of the annotation reflecting the annotation's current sta...
Definition: qgsformannotation.cpp:44
QgsAnnotation::_readXml
void _readXml(const QDomElement &annotationElem, const QgsReadWriteContext &context)
Reads common annotation properties from a DOM element.
Definition: qgsannotation.cpp:444
QgsAnnotation::contentsMargin
QgsMargins contentsMargin() const
Returns the margins (in millimeters) between the outside of the frame and the annotation content.
Definition: qgsannotation.h:231
QgsReadWriteContext
The class is used as a container of context for various read/write operations on other objects.
Definition: qgsreadwritecontext.h:35
qgsmapcanvas.h
qgsgui.h
QgsFormAnnotation::writeXml
void writeXml(QDomElement &elem, QDomDocument &doc, const QgsReadWriteContext &context) const override
Writes the annotation state to a DOM element.
Definition: qgsformannotation.cpp:161
qgsfeatureiterator.h
QgsFields::count
int count() const
Returns number of items.
Definition: qgsfields.cpp:133
QgsFields
Container of fields for a vector layer.
Definition: qgsfields.h:45
qgsfeature.h
QgsRenderContext
Contains information about the context of a rendering operation.
Definition: qgsrendercontext.h:58
QgsProject::instance
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:468
QgsFormAnnotation
An annotation item that embeds a designer form showing the feature attribute.
Definition: qgsformannotation.h:34
QgsFormAnnotation::setDesignerForm
void setDesignerForm(const QString &uiFile)
Sets the path to the Qt Designer UI file to show in the annotation.
Definition: qgsformannotation.cpp:52
QgsEditorWidgetWrapper::additionalFields
virtual QStringList additionalFields() const
Returns the list of additional fields which the editor handles.
Definition: qgseditorwidgetwrapper.h:92
QgsField::name
QString name
Definition: qgsfield.h:59
QgsFormAnnotation::QgsFormAnnotation
QgsFormAnnotation(QObject *parent=nullptr)
Constructor for QgsFormAnnotation.
Definition: qgsformannotation.cpp:40
QgsAnnotation::mapLayer
QgsMapLayer * mapLayer() const
Returns the map layer associated with the annotation.
Definition: qgsannotation.h:286
QgsEditorWidgetWrapper
Manages an editor widget Widget and wrapper share the same parent.
Definition: qgseditorwidgetwrapper.h:48
QgsVectorLayer::fields
QgsFields fields() const FINAL
Returns the list of fields of this layer.
Definition: qgsvectorlayer.cpp:3283
QgsAnnotation
Abstract base class for annotation items which are drawn over a map.
Definition: qgsannotation.h:50
QgsAnnotation::fillSymbol
QgsFillSymbol * fillSymbol() const
Returns the symbol that is used for rendering the annotation frame.
Definition: qgsannotation.h:244
QgsAnnotation::associatedFeature
QgsFeature associatedFeature() const
Returns the feature associated with the annotation, or an invalid feature if none has been set.
Definition: qgsannotation.h:301
qgsmaptool.h
QgsAnnotation::_writeXml
void _writeXml(QDomElement &itemElem, QDomDocument &doc, const QgsReadWriteContext &context) const
Writes common annotation properties to a DOM element.
Definition: qgsannotation.cpp:399
qgsattributeeditorcontext.h
QgsFormAnnotation::renderAnnotation
void renderAnnotation(QgsRenderContext &context, QSizeF size) const override
Renders the annotation's contents to a target /a context at the specified /a size.
Definition: qgsformannotation.cpp:118
QgsScopedQPainterState
Scoped object for saving and restoring a QPainter object's state.
Definition: qgsrendercontext.h:1120
QgsFormAnnotation::setAssociatedFeature
void setAssociatedFeature(const QgsFeature &feature) override
Sets the feature associated with the annotation.
Definition: qgsformannotation.cpp:192
QgsAnnotation::setAssociatedFeature
virtual void setAssociatedFeature(const QgsFeature &feature)
Sets the feature associated with the annotation.
Definition: qgsannotation.cpp:181
QgsFeature::attributes
QgsAttributes attributes
Definition: qgsfeature.h:65
QgsAnnotation::setFrameSizeMm
void setFrameSizeMm(QSizeF size)
Sets the size (in millimeters) of the annotation's frame (the main area in which the annotation's con...
Definition: qgsannotation.cpp:112
qgsvectorlayer.h
QgsFormAnnotation::preferredFrameSize
QSizeF preferredFrameSize() const
Returns the optimal frame size.
Definition: qgsformannotation.cpp:149
QgsEditorWidgetRegistry::create
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.
Definition: qgseditorwidgetregistry.cpp:97
qgseditorwidgetregistry.h
c
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
Definition: porting_processing.dox:1
QgsSymbol::setColor
void setColor(const QColor &color)
Sets the color for the symbol.
Definition: qgssymbol.cpp:504
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:387
QgsFillSymbol::clone
QgsFillSymbol * clone() const override
Returns a deep copy of this symbol.
Definition: qgssymbol.cpp:2317
QgsFillSymbol
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
Definition: qgssymbol.h:1234
QgsAnnotation::appearanceChanged
void appearanceChanged()
Emitted whenever the annotation's appearance changes.
QgsAnnotation::setFillSymbol
void setFillSymbol(QgsFillSymbol *symbol)
Sets the fill symbol used for rendering the annotation frame.
Definition: qgsannotation.cpp:127
QgsAttributes
A vector of attributes.
Definition: qgsattributes.h:58
QgsFeature
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:56
qgsformannotation.h
qgslogger.h
QgsRenderContext::painter
QPainter * painter()
Returns the destination QPainter for the render operation.
Definition: qgsrendercontext.h:179
QgsFields::at
QgsField at(int i) const
Gets field at particular index (must be in range 0..N-1)
Definition: qgsfields.cpp:163
QgsAttributeEditorContext
This class contains context information for attribute editor widgets.
Definition: qgsattributeeditorcontext.h:41
qgsproject.h
QgsFields::indexFromName
int indexFromName(const QString &fieldName) const
Gets the field index from the field name.
Definition: qgsfields.cpp:202
QgsAnnotation::copyCommonProperties
void copyCommonProperties(QgsAnnotation *target) const
Copies common annotation properties to the targe annotation.
Definition: qgsannotation.cpp:546
QgsFormAnnotation::minimumFrameSize
QSizeF minimumFrameSize() const override
Returns the minimum frame size for the annotation.
Definition: qgsformannotation.cpp:135
QgsAnnotation::setMapLayer
void setMapLayer(QgsMapLayer *layer)
Sets the map layer associated with the annotation.
Definition: qgsannotation.cpp:175