QGIS API Documentation  3.27.0-Master (aef1b1ec20)
qgsattributeformlegacyinterface.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsattributeformlegacyinterface.cpp
3  --------------------------------------
4  Date : 13.5.2014
5  Copyright : (C) 2014 Matthias Kuhn
6  Email : matthias at opengis dot ch
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
17 
18 #include "qgspythonrunner.h"
19 #include "qgsattributeform.h"
20 
21 #include <QString>
22 #include <QDateTime>
23 #include <QRegularExpression>
24 
25 QgsAttributeFormLegacyInterface::QgsAttributeFormLegacyInterface( const QString &function, const QString &pyFormName, QgsAttributeForm *form )
27  , mPyFunctionName( function )
28  , mPyFormVarName( pyFormName )
29 {
30  static int sLayerCounter = 0;
31  mPyLayerVarName = QStringLiteral( "_qgis_layer_%1_%2" ).arg( form->layer()->id() ).arg( sLayerCounter++ );
32  const thread_local QRegularExpression reClean( QRegularExpression( "[^a-zA-Z0-9_]" ) );
33  mPyLayerVarName.replace( reClean, QStringLiteral( "_" ) ); // clean identifier
34 
35  const QString initLayer = QStringLiteral( "%1 = sip.wrapinstance( %2, qgis.core.QgsVectorLayer )" )
36  .arg( mPyLayerVarName )
37  .arg( ( quint64 ) form->layer() );
38 
39  QgsPythonRunner::run( initLayer );
40 }
41 
43 {
44  const QString delLayer = QStringLiteral( "del %1" ).arg( mPyLayerVarName );
45  QgsPythonRunner::run( delLayer );
46 }
47 
49 {
50  QDialogButtonBox *buttonBox = form()->findChild<QDialogButtonBox *>();
51  if ( buttonBox )
52  {
53  // If the init function did not call disconnect, we do it here before reconnecting
54  // If it did call disconnect, then the call will just do nothing
55  QObject::disconnect( buttonBox, &QDialogButtonBox::accepted, form(), &QgsAttributeForm::save );
56  QObject::connect( buttonBox, &QDialogButtonBox::accepted, form(), &QgsAttributeForm::save );
57  }
58 
59  // Generate the unique ID of this feature. We used to use feature ID but some providers
60  // return a ID that is an invalid python variable when we have new unsaved features.
61  const QDateTime dt = QDateTime::currentDateTime();
62  const QString pyFeatureVarName = QStringLiteral( "_qgis_feature_%1" ).arg( dt.toString( QStringLiteral( "yyyyMMddhhmmsszzz" ) ) );
63  const QString initFeature = QStringLiteral( "%1 = sip.wrapinstance( %2, qgis.core.QgsFeature )" )
64  .arg( pyFeatureVarName )
65  .arg( ( quint64 ) & form()->feature() );
66 
67  QgsPythonRunner::run( initFeature );
68 
69  const QString expr = QStringLiteral( "%1( %2, %3, %4)" )
70  .arg( mPyFunctionName,
71  mPyFormVarName,
72  mPyLayerVarName,
73  pyFeatureVarName );
74 
75  QgsPythonRunner::run( expr );
76 
77  const QString delFeature = QStringLiteral( "del %1" ).arg( pyFeatureVarName );
78  QgsPythonRunner::run( delFeature );
79 }
QgsAttributeFormLegacyInterface(const QString &function, const QString &pyFormName, QgsAttributeForm *form)
QgsVectorLayer * layer()
Returns the layer for which this form is shown.
bool save()
Save all the values from the editors to the layer.
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
static bool run(const QString &command, const QString &messageOnError=QString())
Execute a Python statement.