QGIS API Documentation  3.14.0-Pi (9f7028fd23)
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  }
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  context.painter()->save();
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  context.painter()->restore();
135 }
136 
138 {
139  if ( mDesignerWidget )
140  {
141  QSizeF widgetMinSize = mMinimumSize;
142  return QSizeF( contentsMargin().left() + contentsMargin().right() + widgetMinSize.width(),
143  contentsMargin().top() + contentsMargin().bottom() + widgetMinSize.height() );
144  }
145  else
146  {
147  return QSizeF( 0, 0 );
148  }
149 }
150 
152 {
153  if ( mDesignerWidget )
154  {
155  return mDesignerWidget->sizeHint();
156  }
157  else
158  {
159  return QSizeF( 0, 0 );
160  }
161 }
162 
163 void QgsFormAnnotation::writeXml( QDomElement &elem, QDomDocument &doc, const QgsReadWriteContext &context ) const
164 {
165  QDomElement formAnnotationElem = doc.createElement( QStringLiteral( "FormAnnotationItem" ) );
166  formAnnotationElem.setAttribute( QStringLiteral( "designerForm" ), mDesignerForm );
167  _writeXml( formAnnotationElem, doc, context );
168  elem.appendChild( formAnnotationElem );
169 }
170 
171 void QgsFormAnnotation::readXml( const QDomElement &itemElem, const QgsReadWriteContext &context )
172 {
173  mDesignerForm = itemElem.attribute( QStringLiteral( "designerForm" ), QString() );
174  QDomElement annotationElem = itemElem.firstChildElement( QStringLiteral( "AnnotationItem" ) );
175  if ( !annotationElem.isNull() )
176  {
177  _readXml( annotationElem, context );
178  }
179  // upgrade old layer
180  if ( !mapLayer() && itemElem.hasAttribute( QStringLiteral( "vectorLayer" ) ) )
181  {
182  setMapLayer( QgsProject::instance()->mapLayer( itemElem.attribute( QStringLiteral( "vectorLayer" ) ) ) );
183  }
184 
185  mDesignerWidget.reset( createDesignerWidget( mDesignerForm ) );
186  if ( mDesignerWidget && fillSymbol() )
187  {
188  QgsFillSymbol *newFill = fillSymbol()->clone();
189  newFill->setColor( mDesignerWidget->palette().color( QPalette::Window ) );
190  setFillSymbol( newFill );
191  }
192 }
193 
195 {
197 
198  //create new embedded widget
199  mDesignerWidget.reset( createDesignerWidget( mDesignerForm ) );
200  if ( mDesignerWidget && fillSymbol() )
201  {
202  QgsFillSymbol *newFill = fillSymbol()->clone();
203  newFill->setColor( mDesignerWidget->palette().color( QPalette::Window ) );
204  setFillSymbol( newFill );
205  }
206  emit appearanceChanged();
207 }
208 
209 
210 
QgsFormAnnotation::readXml
void readXml(const QDomElement &itemElem, const QgsReadWriteContext &context) override
Restores the annotation's state from a DOM element.
Definition: qgsformannotation.cpp:171
QgsGui::editorWidgetRegistry
static QgsEditorWidgetRegistry * editorWidgetRegistry()
Returns the global editor widget registry, used for managing all known edit widget factories.
Definition: qgsgui.cpp:73
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:445
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
Definition: qgsreadwritecontext.h:34
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:163
qgsfeatureiterator.h
QgsFields::count
int count() const
Returns number of items.
Definition: qgsfields.cpp:133
QgsFields
Definition: qgsfields.h:44
qgsfeature.h
QgsRenderContext
Definition: qgsrendercontext.h:57
QgsProject::instance
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:458
QgsFormAnnotation
Definition: qgsformannotation.h:33
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
Definition: qgseditorwidgetwrapper.h:47
QgsVectorLayer::fields
QgsFields fields() const FINAL
Returns the list of fields of this layer.
Definition: qgsvectorlayer.cpp:3280
QgsAnnotation
Abstract base class for annotation items which are drawn over a map.
Definition: qgsannotation.h:49
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:400
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
QgsFormAnnotation::setAssociatedFeature
void setAssociatedFeature(const QgsFeature &feature) override
Sets the feature associated with the annotation.
Definition: qgsformannotation.cpp:194
QgsAnnotation::setAssociatedFeature
virtual void setAssociatedFeature(const QgsFeature &feature)
Sets the feature associated with the annotation.
Definition: qgsannotation.cpp:180
QgsFeature::attributes
QgsAttributes attributes
Definition: qgsfeature.h:69
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:151
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:485
QgsVectorLayer
Definition: qgsvectorlayer.h:385
QgsFillSymbol::clone
QgsFillSymbol * clone() const override
Returns a deep copy of this symbol.
Definition: qgssymbol.cpp:2263
QgsFillSymbol
Definition: qgssymbol.h:1212
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
Definition: qgsattributes.h:57
QgsFeature
Definition: qgsfeature.h:55
qgsformannotation.h
qgslogger.h
QgsRenderContext::painter
QPainter * painter()
Returns the destination QPainter for the render operation.
Definition: qgsrendercontext.h:174
QgsFields::at
QgsField at(int i) const
Gets field at particular index (must be in range 0..N-1)
Definition: qgsfields.cpp:163
QgsAttributeEditorContext
Definition: qgsattributeeditorcontext.h:40
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:547
QgsFormAnnotation::minimumFrameSize
QSizeF minimumFrameSize() const override
Returns the minimum frame size for the annotation.
Definition: qgsformannotation.cpp:137
QgsAnnotation::setMapLayer
void setMapLayer(QgsMapLayer *layer)
Sets the map layer associated with the annotation.
Definition: qgsannotation.cpp:174