QGIS API Documentation 3.99.0-Master (d270888f95f)
Loading...
Searching...
No Matches
qgstextwidgetwrapper.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgstextwidgetwrapper.h
3
4 ---------------------
5 begin : 28.12.2022
6 copyright : (C) 2022 by Alessandro Pasotti
7 email : elpaso at itopen dot it
8 ***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
16
18
19#include "qgsattributeform.h"
22
23#include <QScreen>
24#include <QString>
25
26#include "moc_qgstextwidgetwrapper.cpp"
27
28using namespace Qt::StringLiterals;
29
31 : QgsWidgetWrapper( layer, editor, parent )
32{
33 connect( this, &QgsWidgetWrapper::contextChanged, this, &QgsTextWidgetWrapper::updateTextContext );
34}
35
37{
38 return true;
39}
40
41QWidget *QgsTextWidgetWrapper::createWidget( QWidget *parent )
42{
43 QgsAttributeForm *form = qobject_cast<QgsAttributeForm *>( parent );
44
45 if ( form )
46 {
47 mFormFeature = form->feature();
48 connect( form, &QgsAttributeForm::widgetValueChanged, this, [this]( const QString &attribute, const QVariant &newValue, bool attributeChanged ) {
49 if ( attributeChanged )
50 {
51 if ( mRequiresFormScope )
52 {
53 mFormFeature.setAttribute( attribute, newValue );
54 updateTextContext();
55 }
56 }
57 } );
58 }
59 QLabel *widget = new QLabel( parent );
60 widget->setWordWrap( widget );
61 return widget;
62}
63
64void QgsTextWidgetWrapper::initWidget( QWidget *editor )
65{
66 mWidget = qobject_cast<QLabel *>( editor );
67
68 if ( !mWidget )
69 return;
70
71 mWidget->setText( QgsExpression::replaceExpressionText( mText, &mTextContext ) );
72 mWidget->setOpenExternalLinks( true );
73
74 const thread_local QRegularExpression sRegEx { u"\\[%(.*?)%\\]"_s, QRegularExpression::MultilineOption | QRegularExpression::DotMatchesEverythingOption };
75
76 mNeedsGeometry = false;
77 QRegularExpressionMatchIterator matchIt { sRegEx.globalMatch( mText ) };
78 while ( !mNeedsGeometry && matchIt.hasNext() )
79 {
80 const QRegularExpressionMatch match { matchIt.next() };
81 const QgsExpression exp { match.captured( 1 ) };
82 mNeedsGeometry = exp.needsGeometry();
83 }
84}
85
87{
88 if ( !mWidget )
89 return;
90
91 initWidget( mWidget );
92}
93
94
95void QgsTextWidgetWrapper::setText( const QString &text )
96{
97 mText = text;
98
99 bool ok = false;
100 const thread_local QRegularExpression sRegEx( u"\\[%(.*?)%\\]"_s, QRegularExpression::MultilineOption | QRegularExpression::DotMatchesEverythingOption );
101 QRegularExpressionMatchIterator matchIt = sRegEx.globalMatch( mText );
102 while ( !ok && matchIt.hasNext() )
103 {
104 const QRegularExpressionMatch match = matchIt.next();
105 const QgsExpression exp = match.captured( 1 );
107 }
108 mRequiresFormScope = ok;
109
110 reinitWidget();
111}
112
114{
115 return mNeedsGeometry;
116}
117
118void QgsTextWidgetWrapper::updateTextContext()
119{
120 if ( !mWidget )
121 return;
122
123 const QgsAttributeEditorContext attributeContext = context();
124 mTextContext = layer()->createExpressionContext();
125 mTextContext << QgsExpressionContextUtils::formScope( mFormFeature, attributeContext.attributeFormModeString() );
126 if ( attributeContext.parentFormFeature().isValid() )
127 {
128 mTextContext << QgsExpressionContextUtils::parentFormScope( attributeContext.parentFormFeature() );
129 }
130 mTextContext.setFeature( mFeature );
131 mWidget->setText( QgsExpression::replaceExpressionText( mText, &mTextContext ) );
132}
133
135{
136 if ( !mWidget )
137 return;
138
139 mFeature = feature;
140 mFormFeature = feature;
141
142 updateTextContext();
143}
Contains context information for attribute editor widgets.
QString attributeFormModeString() const
Returns given attributeFormMode as string.
QgsFeature parentFormFeature() const
Returns the feature of the currently edited parent form in its actual state.
The attribute form widget for vector layer features.
void widgetValueChanged(const QString &attribute, const QVariant &value, bool attributeChanged)
Notifies about changes of attributes.
const QgsFeature & feature() const
Returns feature of attribute form.
static QgsExpressionContextScope * parentFormScope(const QgsFeature &formFeature=QgsFeature(), const QString &formMode=QString())
Creates a new scope which contains functions and variables from the current parent attribute form/tab...
static QgsExpressionContextScope * formScope(const QgsFeature &formFeature=QgsFeature(), const QString &formMode=QString())
Creates a new scope which contains functions and variables from the current attribute form/table form...
Handles parsing and evaluation of expressions (formerly called "search strings").
static QString replaceExpressionText(const QString &action, const QgsExpressionContext *context, const QgsDistanceArea *distanceArea=nullptr)
This function replaces each expression between [% and %] in the string with the result of its evaluat...
bool needsGeometry() const
Returns true if the expression uses feature geometry for some computation.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:60
bool isValid() const
Returns the validity of this feature.
bool needsGeometry() const
Returns true if the widget needs feature geometry.
bool valid() const override
Returns true if the widget has been properly initialized.
QWidget * createWidget(QWidget *parent) override
This method should create a new widget with the provided parent.
void setText(const QString &text)
Sets the text code to htmlCode.
QgsTextWidgetWrapper(QgsVectorLayer *layer, QWidget *editor, QWidget *parent)
Create a text widget wrapper.
void reinitWidget()
Clears the content and makes new initialization.
void setFeature(const QgsFeature &feature) override
void initWidget(QWidget *editor) override
This method should initialize the editor widget with runtime data.
static bool expressionRequiresFormScope(const QString &expression)
Check if the expression requires a form scope (i.e.
Represents a vector layer which manages a vector based dataset.
QgsExpressionContext createExpressionContext() const final
This method needs to be reimplemented in all classes which implement this interface and return an exp...
QWidget * widget()
Access the widget managed by this wrapper.
void contextChanged()
Signal when QgsAttributeEditorContext mContext changed.
QgsWidgetWrapper(QgsVectorLayer *vl, QWidget *editor=nullptr, QWidget *parent=nullptr)
Create a new widget wrapper.
const QgsAttributeEditorContext & context() const
Returns information about the context in which this widget is shown.
QgsVectorLayer * layer() const
Returns the vector layer associated with the widget.