Skip to content

Commit f982c84

Browse files
committed
Merge pull request #2420 from elpaso/bugfix-13410
[FEATURE] Bugfix 13410
2 parents 700fc04 + cf4693e commit f982c84

10 files changed

+234
-24
lines changed

python/core/qgspythonrunner.sip

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class QgsPythonRunner
1313
static bool run( const QString& command, const QString& messageOnError = QString() );
1414

1515
/** Eval a python statement */
16-
static bool eval( const QString& command, QString& result );
16+
static bool eval( const QString& command, QString& result /Out/ );
1717

1818
/** Assign an instance of python runner so that run() can be used.
1919
This method should be called during app initialization.

python/core/qgsvectorlayer.sip

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1095,6 +1095,18 @@ class QgsVectorLayer : QgsMapLayer
10951095
/** Set python function for edit form initialization */
10961096
void setEditFormInit( const QString& function );
10971097

1098+
/** Get python code for edit form initialization */
1099+
QString editFormInitCode();
1100+
1101+
/** Reeturn if python code has to be loaded for edit form initialization */
1102+
bool editFormInitUseCode();
1103+
1104+
/** Set python code for edit form initialization */
1105+
void setEditFormInitCode( const QString& code );
1106+
1107+
/** Set python code for edit form initialization */
1108+
void setEditFormInitUseCode( const bool useCode );
1109+
10981110
/**
10991111
* Access value map
11001112
* @deprecated Use editorWidgetV2Config() instead

src/app/qgsfieldsproperties.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,33 @@ QgsFieldsProperties::QgsFieldsProperties( QgsVectorLayer *layer, QWidget* parent
115115
mRelationsList->setHorizontalHeaderItem( RelFieldCol, new QTableWidgetItem( tr( "Field" ) ) );
116116
mRelationsList->verticalHeader()->hide();
117117

118+
// Python init function and code
118119
leEditForm->setText( layer->editForm() );
119120
leEditFormInit->setText( layer->editFormInit() );
121+
leEditFormInitUseCode->setChecked( layer->editFormInitUseCode() );
122+
QString code( layer->editFormInitCode() );
123+
if ( code.isEmpty( ) )
124+
{
125+
code.append( tr( "# -*- coding: utf-8 -*-\n\"\"\"\n"
126+
"QGIS forms can have a Python function that is called when the form is\n"
127+
"opened.\n"
128+
"\n"
129+
"Use this function to add extra logic to your forms.\n"
130+
"\n"
131+
"Enter the name of the function in the \"Python Init function\"\n"
132+
"field.\n"
133+
"An example follows:\n"
134+
"\"\"\"\n"
135+
"from PyQt4.QtGui import QWidget\n\n"
136+
"def my_form_open(dialog, layer, feature):\n"
137+
"\tgeom = feature.geometry()\n"
138+
"\tcontrol = dialog.findChild(QWidget, \"MyLineEdit\")\n" ) );
139+
140+
}
141+
leEditFormInitCode->setText( code );
142+
// Show or hide as needed
143+
mPythonInitCodeGroupBox->setVisible( layer->editFormInitUseCode() );
144+
connect( leEditFormInitUseCode, SIGNAL( toggled( bool ) ), this, SLOT( on_leEditFormInitUseCodeToggled( bool ) ) );
120145

121146
loadRelations();
122147

@@ -186,6 +211,15 @@ QTreeWidgetItem *QgsFieldsProperties::loadAttributeEditorTreeItem( QgsAttributeE
186211
return newWidget;
187212
}
188213

214+
void QgsFieldsProperties::setEditFormInit( const QString &editForm, const QString &editFormInit, const QString &editFormInitCode, const bool editFormInitUseCode )
215+
{
216+
leEditForm->setText( editForm );
217+
leEditFormInit->setText( editFormInit );
218+
leEditFormInitCode->setText( editFormInitCode );
219+
leEditFormInitUseCode->setChecked( editFormInitUseCode );
220+
}
221+
222+
189223
void QgsFieldsProperties::loadAttributeEditorTree()
190224
{
191225
// tabs and groups info
@@ -424,6 +458,11 @@ void QgsFieldsProperties::on_mMoveUpItem_clicked()
424458
}
425459
}
426460

461+
void QgsFieldsProperties::on_leEditFormInitUseCodeToggled( bool checked )
462+
{
463+
mPythonInitCodeGroupBox->setVisible( checked );
464+
}
465+
427466
void QgsFieldsProperties::attributeTypeDialog()
428467
{
429468
QPushButton *pb = qobject_cast<QPushButton *>( sender() );
@@ -843,6 +882,8 @@ void QgsFieldsProperties::apply()
843882
if ( mEditorLayoutComboBox->currentIndex() == QgsVectorLayer::UiFileLayout )
844883
mLayer->setEditForm( leEditForm->text() );
845884
mLayer->setEditFormInit( leEditFormInit->text() );
885+
mLayer->setEditFormInitUseCode( leEditFormInitUseCode->isChecked() );
886+
mLayer->setEditFormInitCode( leEditFormInitCode->text() );
846887
mLayer->setFeatureFormSuppress(( QgsVectorLayer::FeatureFormSuppress )mFormSuppressCmbBx->currentIndex() );
847888

848889
mLayer->setExcludeAttributesWMS( excludeAttributesWMS );

src/app/qgsfieldsproperties.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,15 @@ class APP_EXPORT QgsFieldsProperties : public QWidget, private Ui_QgsFieldsPrope
160160
void loadAttributeEditorTree();
161161
QTreeWidgetItem *loadAttributeEditorTreeItem( QgsAttributeEditorElement* const widgetDef, QTreeWidgetItem* parent );
162162

163+
/**
164+
* @brief setEditFormInit set the private ui fields
165+
* @param editForm
166+
* @param editFormInit
167+
* @param editFormInitCode
168+
* @param editFormInitUseCode
169+
*/
170+
void setEditFormInit( const QString &editForm, const QString &editFormInit, const QString &editFormInitCode, const bool editFormInitUseCode );
171+
163172
signals:
164173
void toggleEditing();
165174

@@ -170,7 +179,7 @@ class APP_EXPORT QgsFieldsProperties : public QWidget, private Ui_QgsFieldsPrope
170179
void onAttributeSelectionChanged();
171180
void on_pbnSelectEditForm_clicked();
172181
void on_mEditorLayoutComboBox_currentIndexChanged( int index );
173-
182+
void on_leEditFormInitUseCodeToggled( bool checked );
174183
void attributeAdded( int idx );
175184
void attributeDeleted( int idx );
176185
void attributeTypeDialog();

src/app/qgsvectorlayerproperties.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,10 @@ void QgsVectorLayerProperties::syncToLayer( void )
505505

506506
// set initial state for variable editor
507507
updateVariableEditor();
508+
509+
// updates the init python code and ui
510+
updateFieldsPropertiesDialog();
511+
508512
} // syncToLayer()
509513

510514

@@ -1299,3 +1303,8 @@ void QgsVectorLayerProperties::updateVariableEditor()
12991303
mVariableEditor->reloadContext();
13001304
mVariableEditor->setEditableScopeIndex( 2 );
13011305
}
1306+
1307+
void QgsVectorLayerProperties::updateFieldsPropertiesDialog()
1308+
{
1309+
mFieldsPropertiesDialog->setEditFormInit( layer->editForm(), layer->editFormInit(), layer->editFormInitCode(), layer->editFormInitUseCode() );
1310+
}

src/app/qgsvectorlayerproperties.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,11 @@ class APP_EXPORT QgsVectorLayerProperties : public QgsOptionsDialogBase, private
145145
*/
146146
void updateVariableEditor();
147147

148+
/**
149+
* @brief updates the FieldsPropertiesDialog when syncing the layer properties
150+
*/
151+
void updateFieldsPropertiesDialog();
152+
148153
protected:
149154

150155
void saveStyleAs( StyleType styleType );

src/core/qgsvectorlayer.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ QgsVectorLayer::QgsVectorLayer( const QString& vectorLayerPath,
138138
, mLayerTransparency( 0 )
139139
, mVertexMarkerOnlyForSelection( false )
140140
, mEditorLayout( GeneratedLayout )
141+
, mEditFormInitUseCode( false )
141142
, mFeatureFormSuppress( SuppressDefault )
142143
, mCache( new QgsGeometryCache() )
143144
, mEditBuffer( 0 )
@@ -149,6 +150,7 @@ QgsVectorLayer::QgsVectorLayer( const QString& vectorLayerPath,
149150
, mLazyExtent( true )
150151
, mSymbolFeatureCounted( false )
151152
, mEditCommandActive( false )
153+
152154
{
153155
mActions = new QgsAttributeAction( this );
154156
mConditionalStyles = new QgsConditionalLayerStyles();
@@ -1632,6 +1634,7 @@ bool QgsVectorLayer::writeXml( QDomNode & layer_node,
16321634
return writeSymbology( layer_node, document, errorMsg );
16331635
} // bool QgsVectorLayer::writeXml
16341636

1637+
16351638
bool QgsVectorLayer::readSymbology( const QDomNode& node, QString& errorMessage )
16361639
{
16371640
emit readCustomSymbology( node.toElement(), errorMessage );
@@ -1780,6 +1783,18 @@ bool QgsVectorLayer::readSymbology( const QDomNode& node, QString& errorMessage
17801783
mEditFormInit = editFormInitNode.toElement().text();
17811784
}
17821785

1786+
QDomNode editFormInitCodeNode = node.namedItem( "editforminitcode" );
1787+
if ( !editFormInitCodeNode.isNull() )
1788+
{
1789+
mEditFormInitCode = editFormInitCodeNode.toElement().text();
1790+
}
1791+
1792+
QDomNode editFormInitUseCodeNode = node.namedItem( "editforminitusecode" );
1793+
if ( !editFormInitCodeNode.isNull() )
1794+
{
1795+
mEditFormInitUseCode = ( bool ) editFormInitUseCodeNode.toElement().text().toInt();
1796+
}
1797+
17831798
QDomNode fFSuppNode = node.namedItem( "featformsuppress" );
17841799
if ( fFSuppNode.isNull() )
17851800
{
@@ -2042,6 +2057,14 @@ bool QgsVectorLayer::writeSymbology( QDomNode& node, QDomDocument& doc, QString&
20422057
efiField.appendChild( doc.createTextNode( mEditFormInit ) );
20432058
node.appendChild( efiField );
20442059

2060+
QDomElement efiucField = doc.createElement( "editforminitusecode" );
2061+
efiucField.appendChild( doc.createTextNode( mEditFormInitUseCode ? "1" : "0" ) );
2062+
node.appendChild( efiucField );
2063+
2064+
QDomElement eficField = doc.createElement( "editforminitcode" );
2065+
eficField.appendChild( doc.createCDATASection( mEditFormInitCode ) );
2066+
node.appendChild( eficField );
2067+
20452068
QDomElement fFSuppElem = doc.createElement( "featformsuppress" );
20462069
QDomText fFSuppText = doc.createTextNode( QString::number( featureFormSuppress() ) );
20472070
fFSuppElem.appendChild( fFSuppText );
@@ -2825,11 +2848,31 @@ QString QgsVectorLayer::editFormInit()
28252848
return mEditFormInit;
28262849
}
28272850

2851+
QString QgsVectorLayer::editFormInitCode()
2852+
{
2853+
return mEditFormInitCode;
2854+
}
2855+
2856+
bool QgsVectorLayer::editFormInitUseCode()
2857+
{
2858+
return mEditFormInitUseCode;
2859+
}
2860+
28282861
void QgsVectorLayer::setEditFormInit( const QString& function )
28292862
{
28302863
mEditFormInit = function;
28312864
}
28322865

2866+
void QgsVectorLayer::setEditFormInitUseCode( const bool useCode )
2867+
{
2868+
mEditFormInitUseCode = useCode;
2869+
}
2870+
2871+
void QgsVectorLayer::setEditFormInitCode( const QString& code )
2872+
{
2873+
mEditFormInitCode = code;
2874+
}
2875+
28332876
QMap< QString, QVariant > QgsVectorLayer::valueMap( int idx )
28342877
{
28352878
return editorWidgetV2Config( idx );

src/core/qgsvectorlayer.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1628,9 +1628,21 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
16281628
/** Get python function for edit form initialization */
16291629
QString editFormInit();
16301630

1631+
/** Get python code for edit form initialization */
1632+
QString editFormInitCode();
1633+
1634+
/** Reeturn if python code has to be loaded for edit form initialization */
1635+
bool editFormInitUseCode();
1636+
16311637
/** Set python function for edit form initialization */
16321638
void setEditFormInit( const QString& function );
16331639

1640+
/** Set python code for edit form initialization */
1641+
void setEditFormInitCode( const QString& code );
1642+
1643+
/** Set python code for edit form initialization */
1644+
void setEditFormInitUseCode( const bool useCode );
1645+
16341646
/**
16351647
* Access value map
16361648
* @deprecated Use editorWidgetV2Config() instead
@@ -2141,7 +2153,8 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
21412153
/** Defines the default layout to use for the attribute editor (Drag and drop, UI File, Generated) */
21422154
EditorLayout mEditorLayout;
21432155

2144-
QString mEditForm, mEditFormInit;
2156+
QString mEditForm, mEditFormInit, mEditFormInitCode;
2157+
bool mEditFormInitUseCode;
21452158

21462159
/** Type of feature form suppression after feature creation
21472160
* @note added in 2.1 */

src/gui/qgsattributeform.cpp

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -580,18 +580,30 @@ void QgsAttributeForm::initPython()
580580
QString module = mLayer->editFormInit();
581581

582582
int pos = module.lastIndexOf( '.' );
583-
if ( pos >= 0 )
583+
584+
if ( pos >= 0 ) // It's a module
584585
{
585586
QgsPythonRunner::run( QString( "import %1" ).arg( module.left( pos ) ) );
586-
}
587+
/* Reload the module if the DEBUGMODE switch has been set in the module.
588+
If set to False you have to reload QGIS to reset it to True due to Python
589+
module caching */
590+
QString reload = QString( "if hasattr(%1,'DEBUGMODE') and %1.DEBUGMODE:"
591+
" reload(%1)" ).arg( module.left( pos ) );
587592

588-
/* Reload the module if the DEBUGMODE switch has been set in the module.
589-
If set to False you have to reload QGIS to reset it to True due to Python
590-
module caching */
591-
QString reload = QString( "if hasattr(%1,'DEBUGMODE') and %1.DEBUGMODE:"
592-
" reload(%1)" ).arg( module.left( pos ) );
593+
QgsPythonRunner::run( reload );
594+
}
595+
else // Must be supplied code
596+
{
597+
if ( mLayer->editFormInitUseCode() )
598+
{
599+
QgsPythonRunner::run( mLayer->editFormInitCode() );
600+
}
601+
else
602+
{
603+
QgsDebugMsg( "No dot in editFormInit and no custom python code provided! There is nothing to run." );
604+
}
605+
}
593606

594-
QgsPythonRunner::run( reload );
595607

596608
QgsPythonRunner::run( "import inspect" );
597609
QString numArgs;

0 commit comments

Comments
 (0)