Skip to content

Commit e5ca63d

Browse files
committed
Refactored the python init function selector
Do not rely on the presence of a dot to load a module. Loading a module can now be achieved through the code editor in the dialog. * added an option to load from environment * added a file selector to specify the file * changed tooltips accordingly
1 parent de3ce15 commit e5ca63d

9 files changed

+342
-164
lines changed

python/core/qgseditformconfig.sip

+32-13
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,18 @@ class QgsEditFormConfig : QObject
5757
SuppressOff = 2 //!< Do not suppress feature form
5858
};
5959

60+
/**
61+
* The python init code source options.
62+
*/
63+
enum PythonInitCodeSource
64+
{
65+
CodeSourceNone = 0, //!< Do not use python code at all
66+
CodeSourceFile = 1, //!< Load the python code from a file
67+
CodeSourceDialog = 2, //!< Use the python code provided in the dialog
68+
CodeSourceEnvironment = 3 //!< Use the python code available in the python environment
69+
};
70+
71+
6072
/**
6173
* This is only useful in combination with EditorLayout::TabLayout.
6274
*
@@ -208,15 +220,6 @@ class QgsEditFormConfig : QObject
208220
void setLabelOnTop( int idx, bool onTop );
209221

210222

211-
212-
213-
214-
215-
216-
217-
218-
219-
220223
// Python stuff
221224

222225

@@ -237,22 +240,38 @@ class QgsEditFormConfig : QObject
237240
void setInitFunction( const QString& function );
238241

239242
/**
240-
* Get python code for edit form initialization.
243+
* Get python code for edit form initialization from the configuration dialog.
241244
*/
242245
QString initCode() const;
243246

247+
/**
248+
* Get python external file path for edit form initialization.
249+
*/
250+
QString initFilePath() const;
251+
252+
/**
253+
* Set python external file path for edit form initialization.
254+
* Make sure that you also set the appropriate function name in
255+
* @link setInitFunction @endlink
256+
*/
257+
void setInitFilePath( const QString& filePath );
258+
244259
/**
245260
* Get python code for edit form initialization.
246261
* Make sure that you also set the appropriate function name in
247262
* @link setInitFunction @endlink
248263
*/
249264
void setInitCode( const QString& code );
250265

251-
/** Return if python code shall be loaded for edit form initialization */
252-
bool useInitCode() const;
266+
/** Return python code source for edit form initialization
267+
* (if it shall be loaded from a file, read from the
268+
* provided dialog editor or just read from the environment
269+
*/
270+
PythonInitCodeSource initCodeSource() const;
253271

254272
/** Set if python code shall be used for edit form initialization */
255-
void setUseInitCode( const bool useCode );
273+
void setInitCodeSource( const PythonInitCodeSource initCodeSource );
274+
256275

257276
/** Type of feature form pop-up suppression after feature creation (overrides app setting) */
258277
FeatureFormSuppress suppress() const;

src/app/qgsfieldsproperties.cpp

+48-15
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,12 @@ QgsFieldsProperties::QgsFieldsProperties( QgsVectorLayer *layer, QWidget* parent
115115
mRelationsList->setHorizontalHeaderItem( RelFieldCol, new QTableWidgetItem( tr( "Field" ) ) );
116116
mRelationsList->verticalHeader()->hide();
117117

118+
// Init function stuff
119+
mInitCodeSourceComboBox->addItem( tr( "" ) );
120+
mInitCodeSourceComboBox->addItem( tr( "Load from external file" ) );
121+
mInitCodeSourceComboBox->addItem( tr( "Provide code in this dialog" ) );
122+
mInitCodeSourceComboBox->addItem( tr( "Load from the environment" ) );
123+
118124
loadRelations();
119125

120126
updateButtons();
@@ -183,11 +189,15 @@ QTreeWidgetItem *QgsFieldsProperties::loadAttributeEditorTreeItem( QgsAttributeE
183189
return newWidget;
184190
}
185191

186-
void QgsFieldsProperties::setEditFormInit( const QString &editForm, const QString &editFormInit, const QString &editFormInitCode, const bool editFormInitUseCode )
192+
void QgsFieldsProperties::setEditFormInit( const QString &editForm,
193+
const QString &initFunction,
194+
const QString &initCode,
195+
const QString &initFilePath,
196+
const QgsEditFormConfig::PythonInitCodeSource &codeSource )
187197
{
188198

189199
// Python init function and code
190-
QString code( editFormInitCode );
200+
QString code( initCode );
191201
if ( code.isEmpty( ) )
192202
{
193203
code.append( tr( "# -*- coding: utf-8 -*-\n\"\"\"\n"
@@ -206,12 +216,11 @@ void QgsFieldsProperties::setEditFormInit( const QString &editForm, const QStrin
206216
"\tcontrol = dialog.findChild(QWidget, \"MyLineEdit\")\n" ) );
207217

208218
}
209-
leEditForm->setText( editForm );
210-
leEditFormInitCode->setText( code );
211-
leEditFormInit->setText( editFormInit );
212-
leEditFormInitUseCode->setChecked( editFormInitUseCode );
213-
// Show or hide as needed
214-
mPythonInitCodeGroupBox->setVisible( editFormInitUseCode );
219+
mEditFormLineEdit->setText( editForm );
220+
mInitFilePathLineEdit->setText( initFilePath );
221+
mInitCodeEditorPython->setText( code );
222+
mInitFunctionLineEdit->setText( initFunction );
223+
mInitCodeSourceComboBox->setCurrentIndex( codeSource );
215224
}
216225

217226

@@ -453,9 +462,13 @@ void QgsFieldsProperties::on_mMoveUpItem_clicked()
453462
}
454463
}
455464

456-
void QgsFieldsProperties::on_leEditFormInitUseCode_toggled( bool checked )
465+
void QgsFieldsProperties::on_mInitCodeSourceComboBox_currentIndexChanged( int codeSource )
457466
{
458-
mPythonInitCodeGroupBox->setVisible( checked );
467+
// Show or hide ui elements as needed
468+
mInitFunctionContainer->setVisible( codeSource != QgsEditFormConfig::PythonInitCodeSource::CodeSourceNone );
469+
mPythonInitCodeGroupBox->setVisible( codeSource == QgsEditFormConfig::PythonInitCodeSource::CodeSourceDialog );
470+
mInitFilePathLineEdit->setVisible( codeSource == QgsEditFormConfig::PythonInitCodeSource::CodeSourceFile );
471+
mInitFilePathLabel->setVisible( codeSource == QgsEditFormConfig::PythonInitCodeSource::CodeSourceFile );
459472
}
460473

461474
void QgsFieldsProperties::attributeTypeDialog()
@@ -805,6 +818,22 @@ QgsAttributeEditorElement* QgsFieldsProperties::createAttributeEditorWidget( QTr
805818
return widgetDef;
806819
}
807820

821+
822+
void QgsFieldsProperties::on_pbtnSelectInitFilePath_clicked()
823+
{
824+
QSettings myQSettings;
825+
QString lastUsedDir = myQSettings.value( "style/lastUIDir", "." ).toString();
826+
QString pyfilename = QFileDialog::getOpenFileName( this, tr( "Select Python file" ), lastUsedDir, tr( "Python file" ) + " (*.py)" );
827+
828+
if ( pyfilename.isNull() )
829+
return;
830+
831+
QFileInfo fi( pyfilename );
832+
myQSettings.setValue( "style/lastUIDir", fi.path() );
833+
mInitFilePathLineEdit->setText( pyfilename );
834+
}
835+
836+
808837
void QgsFieldsProperties::on_pbnSelectEditForm_clicked()
809838
{
810839
QSettings myQSettings;
@@ -816,7 +845,7 @@ void QgsFieldsProperties::on_pbnSelectEditForm_clicked()
816845

817846
QFileInfo fi( uifilename );
818847
myQSettings.setValue( "style/lastUIDir", fi.path() );
819-
leEditForm->setText( uifilename );
848+
mEditFormLineEdit->setText( uifilename );
820849
}
821850

822851
void QgsFieldsProperties::on_mEditorLayoutComboBox_currentIndexChanged( int index )
@@ -875,10 +904,14 @@ void QgsFieldsProperties::apply()
875904

876905
mLayer->editFormConfig()->setLayout(( QgsEditFormConfig::EditorLayout ) mEditorLayoutComboBox->currentIndex() );
877906
if ( mEditorLayoutComboBox->currentIndex() == QgsEditFormConfig::UiFileLayout )
878-
mLayer->editFormConfig()->setUiForm( leEditForm->text() );
879-
mLayer->editFormConfig()->setInitFunction( leEditFormInit->text() );
880-
mLayer->editFormConfig()->setUseInitCode( leEditFormInitUseCode->isChecked() );
881-
mLayer->editFormConfig()->setInitCode( leEditFormInitCode->text() );
907+
mLayer->editFormConfig()->setUiForm( mEditFormLineEdit->text() );
908+
909+
// Init function configuration
910+
mLayer->editFormConfig()->setInitFunction( mInitFunctionLineEdit->text( ) );
911+
mLayer->editFormConfig()->setInitCode( mInitCodeEditorPython->text( ) );
912+
mLayer->editFormConfig()->setInitFilePath( mInitFilePathLineEdit->text( ) );
913+
mLayer->editFormConfig()->setInitCodeSource(( QgsEditFormConfig::PythonInitCodeSource )mInitCodeSourceComboBox->currentIndex() );
914+
882915
mLayer->editFormConfig()->setSuppress(( QgsEditFormConfig::FeatureFormSuppress )mFormSuppressCmbBx->currentIndex() );
883916

884917
mLayer->setExcludeAttributesWMS( excludeAttributesWMS );

src/app/qgsfieldsproperties.h

+11-5
Original file line numberDiff line numberDiff line change
@@ -163,11 +163,16 @@ class APP_EXPORT QgsFieldsProperties : public QWidget, private Ui_QgsFieldsPrope
163163
/**
164164
* @brief setEditFormInit set the private ui fields
165165
* @param editForm
166-
* @param editFormInit
167-
* @param editFormInitCode
168-
* @param editFormInitUseCode
166+
* @param initFunction
167+
* @param initCode
168+
* @param initFilePath
169+
* @param codeSource
169170
*/
170-
void setEditFormInit( const QString &editForm, const QString &editFormInit, const QString &editFormInitCode, const bool editFormInitUseCode );
171+
void setEditFormInit( const QString &editForm,
172+
const QString &initFunction,
173+
const QString &initCode,
174+
const QString &initFilePath,
175+
const QgsEditFormConfig::PythonInitCodeSource &codeSource );
171176

172177
signals:
173178
void toggleEditing();
@@ -177,9 +182,10 @@ class APP_EXPORT QgsFieldsProperties : public QWidget, private Ui_QgsFieldsPrope
177182
void on_mDeleteAttributeButton_clicked();
178183
void on_mCalculateFieldButton_clicked();
179184
void onAttributeSelectionChanged();
185+
void on_pbtnSelectInitFilePath_clicked();
180186
void on_pbnSelectEditForm_clicked();
181187
void on_mEditorLayoutComboBox_currentIndexChanged( int index );
182-
void on_leEditFormInitUseCode_toggled( bool checked );
188+
void on_mInitCodeSourceComboBox_currentIndexChanged( int codeSource );
183189
void attributeAdded( int idx );
184190
void attributeDeleted( int idx );
185191
void attributeTypeDialog();

src/app/qgsvectorlayerproperties.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1317,5 +1317,5 @@ void QgsVectorLayerProperties::updateVariableEditor()
13171317
void QgsVectorLayerProperties::updateFieldsPropertiesDialog()
13181318
{
13191319
QgsEditFormConfig* cfg = layer->editFormConfig();
1320-
mFieldsPropertiesDialog->setEditFormInit( cfg->uiForm(), cfg->initFunction(), cfg->initCode(), cfg->useInitCode() );
1320+
mFieldsPropertiesDialog->setEditFormInit( cfg->uiForm(), cfg->initFunction(), cfg->initCode(), cfg->initFilePath(), cfg->initCodeSource() );
13211321
}

src/core/qgseditformconfig.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
QgsEditFormConfig::QgsEditFormConfig( QObject* parent )
55
: QObject( parent )
66
, mEditorLayout( GeneratedLayout )
7+
, mInitCodeSource( QgsEditFormConfig::PythonInitCodeSource::CodeSourceNone )
78
, mFeatureFormSuppress( SuppressDefault )
8-
, mUseInitCode( false )
99
{
1010
connect( QgsProject::instance()->relationManager(), SIGNAL( relationsLoaded() ), this, SLOT( onRelationsLoaded() ) );
1111
}

src/core/qgseditformconfig.h

+43-19
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ class CORE_EXPORT QgsEditFormConfig : public QObject
271271
Q_OBJECT
272272

273273
public:
274+
274275
/** The different types to layout the attribute editor. */
275276
enum EditorLayout
276277
{
@@ -308,6 +309,17 @@ class CORE_EXPORT QgsEditFormConfig : public QObject
308309
SuppressOff = 2 //!< Do not suppress feature form
309310
};
310311

312+
/**
313+
* The python init code source options.
314+
*/
315+
enum PythonInitCodeSource
316+
{
317+
CodeSourceNone = 0, //!< Do not use python code at all
318+
CodeSourceFile = 1, //!< Load the python code from an external file
319+
CodeSourceDialog = 2, //!< Use the python code provided in the dialog
320+
CodeSourceEnvironment = 3 //!< Use the python code available in the python environment
321+
};
322+
311323
/**
312324
* This is only useful in combination with EditorLayout::TabLayout.
313325
*
@@ -459,17 +471,7 @@ class CORE_EXPORT QgsEditFormConfig : public QObject
459471
void setLabelOnTop( int idx, bool onTop );
460472

461473

462-
463-
464-
465-
466-
467-
468-
469-
470-
471-
// Python stuff
472-
474+
// Python form init function stuff
473475

474476
/**
475477
* Get python function for edit form initialization.
@@ -490,20 +492,35 @@ class CORE_EXPORT QgsEditFormConfig : public QObject
490492
/**
491493
* Get python code for edit form initialization.
492494
*/
493-
QString initCode() const { return mEditFormInitCode; }
495+
QString initCode() const { return mInitCode; }
494496

495497
/**
496-
* Get python code for edit form initialization.
498+
* Set python code for edit form initialization.
497499
* Make sure that you also set the appropriate function name in
498500
* @link setInitFunction @endlink
499501
*/
500-
void setInitCode( const QString& code ) { mEditFormInitCode = code; }
502+
void setInitCode( const QString& code ) { mInitCode = code; }
503+
504+
/**
505+
* Get python external file path for edit form initialization.
506+
*/
507+
QString initFilePath() const { return mInitFilePath; }
501508

502-
/** Return if python code shall be loaded for edit form initialization */
503-
bool useInitCode() const { return mUseInitCode; }
509+
/**
510+
* Set python external file path for edit form initialization.
511+
* Make sure that you also set the appropriate function name in
512+
* @link setInitFunction @endlink
513+
*/
514+
void setInitFilePath( const QString& filePath ) { mInitFilePath = filePath; }
515+
516+
/** Return python code source for edit form initialization
517+
* (if it shall be loaded from a file, read from the
518+
* provided dialog editor or inherited from the environment)
519+
*/
520+
PythonInitCodeSource initCodeSource() const { return mInitCodeSource; }
504521

505-
/** Set if python code shall be used for edit form initialization */
506-
void setUseInitCode( const bool useCode ) { mUseInitCode = useCode; }
522+
/** Set if python code shall be used for edit form initialization and its origin */
523+
void setInitCodeSource( const PythonInitCodeSource initCodeSource ) { mInitCodeSource = initCodeSource; }
507524

508525
/** Type of feature form pop-up suppression after feature creation (overrides app setting) */
509526
FeatureFormSuppress suppress() const { return mFeatureFormSuppress; }
@@ -547,9 +564,16 @@ class CORE_EXPORT QgsEditFormConfig : public QObject
547564
/** Defines the default layout to use for the attribute editor (Drag and drop, UI File, Generated) */
548565
EditorLayout mEditorLayout;
549566

567+
/** Init form instance */
550568
QString mEditForm;
569+
/** Name of the python form init function */
551570
QString mInitFunction;
552-
QString mEditFormInitCode;
571+
/** Path of the python external file to be loaded */
572+
QString mInitFilePath;
573+
/** Choose the source of the init founction */
574+
PythonInitCodeSource mInitCodeSource;
575+
/** Python init code provided in the dialog */
576+
QString mInitCode;
553577

554578
/** Type of feature form suppression after feature creation */
555579
FeatureFormSuppress mFeatureFormSuppress;

src/core/qgsvectorlayer.cpp

+17-6
Original file line numberDiff line numberDiff line change
@@ -1786,10 +1786,16 @@ bool QgsVectorLayer::readSymbology( const QDomNode& node, QString& errorMessage
17861786
mEditFormConfig->setInitCode( editFormInitCodeNode.toElement().text() );
17871787
}
17881788

1789-
QDomNode editFormInitUseCodeNode = node.namedItem( "editforminitusecode" );
1790-
if ( !editFormInitCodeNode.isNull() || ( !editFormInitNode.isNull() && !editFormInitNode.toElement().text().isEmpty() ) )
1789+
QDomNode editFormInitCodeSourceNode = node.namedItem( "editforminitcodesource" );
1790+
if ( !editFormInitCodeSourceNode.isNull() || ( !editFormInitCodeSourceNode.isNull() && !editFormInitCodeSourceNode.toElement().text().isEmpty() ) )
17911791
{
1792-
mEditFormConfig->setUseInitCode( editFormInitUseCodeNode.toElement().text().toInt() );
1792+
mEditFormConfig->setInitCodeSource(( QgsEditFormConfig::PythonInitCodeSource ) editFormInitCodeSourceNode.toElement().text().toInt() );
1793+
}
1794+
1795+
QDomNode editFormInitFilePathNode = node.namedItem( "editforminitfilepath" );
1796+
if ( !editFormInitFilePathNode.isNull() || ( !editFormInitFilePathNode.isNull() && !editFormInitFilePathNode.toElement().text().isEmpty() ) )
1797+
{
1798+
mEditFormConfig->setInitFilePath( editFormInitFilePathNode.toElement().text() );
17931799
}
17941800

17951801
QDomNode fFSuppNode = node.namedItem( "featformsuppress" );
@@ -2054,9 +2060,14 @@ bool QgsVectorLayer::writeSymbology( QDomNode& node, QDomDocument& doc, QString&
20542060
efiField.appendChild( doc.createTextNode( mEditFormConfig->initFunction() ) );
20552061
node.appendChild( efiField );
20562062

2057-
QDomElement efiucField = doc.createElement( "editforminitusecode" );
2058-
efiucField.appendChild( doc.createTextNode( mEditFormConfig->useInitCode() ? "1" : "0" ) );
2059-
node.appendChild( efiucField );
2063+
QDomElement eficsField = doc.createElement( "editforminitcodesource" );
2064+
eficsField.appendChild( doc.createTextNode( QString::number( mEditFormConfig->initCodeSource() ) ) );
2065+
node.appendChild( eficsField );
2066+
2067+
QDomElement efifpField = doc.createElement( "editforminitfilepath" );
2068+
efifpField.appendChild( doc.createTextNode( mEditFormConfig->initFilePath() ) );
2069+
node.appendChild( efifpField );
2070+
20602071

20612072
QDomElement eficField = doc.createElement( "editforminitcode" );
20622073
eficField.appendChild( doc.createCDATASection( mEditFormConfig->initCode() ) );

0 commit comments

Comments
 (0)