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
This commit is contained in:
elpaso 2015-11-24 11:47:56 +01:00
parent de3ce1560c
commit e5ca63deed
9 changed files with 342 additions and 164 deletions

View File

@ -57,6 +57,18 @@ class QgsEditFormConfig : QObject
SuppressOff = 2 //!< Do not suppress feature form
};
/**
* The python init code source options.
*/
enum PythonInitCodeSource
{
CodeSourceNone = 0, //!< Do not use python code at all
CodeSourceFile = 1, //!< Load the python code from a file
CodeSourceDialog = 2, //!< Use the python code provided in the dialog
CodeSourceEnvironment = 3 //!< Use the python code available in the python environment
};
/**
* This is only useful in combination with EditorLayout::TabLayout.
*
@ -208,15 +220,6 @@ class QgsEditFormConfig : QObject
void setLabelOnTop( int idx, bool onTop );
// Python stuff
@ -237,10 +240,22 @@ class QgsEditFormConfig : QObject
void setInitFunction( const QString& function );
/**
* Get python code for edit form initialization.
* Get python code for edit form initialization from the configuration dialog.
*/
QString initCode() const;
/**
* Get python external file path for edit form initialization.
*/
QString initFilePath() const;
/**
* Set python external file path for edit form initialization.
* Make sure that you also set the appropriate function name in
* @link setInitFunction @endlink
*/
void setInitFilePath( const QString& filePath );
/**
* Get python code for edit form initialization.
* Make sure that you also set the appropriate function name in
@ -248,11 +263,15 @@ class QgsEditFormConfig : QObject
*/
void setInitCode( const QString& code );
/** Return if python code shall be loaded for edit form initialization */
bool useInitCode() const;
/** Return python code source for edit form initialization
* (if it shall be loaded from a file, read from the
* provided dialog editor or just read from the environment
*/
PythonInitCodeSource initCodeSource() const;
/** Set if python code shall be used for edit form initialization */
void setUseInitCode( const bool useCode );
void setInitCodeSource( const PythonInitCodeSource initCodeSource );
/** Type of feature form pop-up suppression after feature creation (overrides app setting) */
FeatureFormSuppress suppress() const;

View File

@ -115,6 +115,12 @@ QgsFieldsProperties::QgsFieldsProperties( QgsVectorLayer *layer, QWidget* parent
mRelationsList->setHorizontalHeaderItem( RelFieldCol, new QTableWidgetItem( tr( "Field" ) ) );
mRelationsList->verticalHeader()->hide();
// Init function stuff
mInitCodeSourceComboBox->addItem( tr( "" ) );
mInitCodeSourceComboBox->addItem( tr( "Load from external file" ) );
mInitCodeSourceComboBox->addItem( tr( "Provide code in this dialog" ) );
mInitCodeSourceComboBox->addItem( tr( "Load from the environment" ) );
loadRelations();
updateButtons();
@ -183,11 +189,15 @@ QTreeWidgetItem *QgsFieldsProperties::loadAttributeEditorTreeItem( QgsAttributeE
return newWidget;
}
void QgsFieldsProperties::setEditFormInit( const QString &editForm, const QString &editFormInit, const QString &editFormInitCode, const bool editFormInitUseCode )
void QgsFieldsProperties::setEditFormInit( const QString &editForm,
const QString &initFunction,
const QString &initCode,
const QString &initFilePath,
const QgsEditFormConfig::PythonInitCodeSource &codeSource )
{
// Python init function and code
QString code( editFormInitCode );
QString code( initCode );
if ( code.isEmpty( ) )
{
code.append( tr( "# -*- coding: utf-8 -*-\n\"\"\"\n"
@ -206,12 +216,11 @@ void QgsFieldsProperties::setEditFormInit( const QString &editForm, const QStrin
"\tcontrol = dialog.findChild(QWidget, \"MyLineEdit\")\n" ) );
}
leEditForm->setText( editForm );
leEditFormInitCode->setText( code );
leEditFormInit->setText( editFormInit );
leEditFormInitUseCode->setChecked( editFormInitUseCode );
// Show or hide as needed
mPythonInitCodeGroupBox->setVisible( editFormInitUseCode );
mEditFormLineEdit->setText( editForm );
mInitFilePathLineEdit->setText( initFilePath );
mInitCodeEditorPython->setText( code );
mInitFunctionLineEdit->setText( initFunction );
mInitCodeSourceComboBox->setCurrentIndex( codeSource );
}
@ -453,9 +462,13 @@ void QgsFieldsProperties::on_mMoveUpItem_clicked()
}
}
void QgsFieldsProperties::on_leEditFormInitUseCode_toggled( bool checked )
void QgsFieldsProperties::on_mInitCodeSourceComboBox_currentIndexChanged( int codeSource )
{
mPythonInitCodeGroupBox->setVisible( checked );
// Show or hide ui elements as needed
mInitFunctionContainer->setVisible( codeSource != QgsEditFormConfig::PythonInitCodeSource::CodeSourceNone );
mPythonInitCodeGroupBox->setVisible( codeSource == QgsEditFormConfig::PythonInitCodeSource::CodeSourceDialog );
mInitFilePathLineEdit->setVisible( codeSource == QgsEditFormConfig::PythonInitCodeSource::CodeSourceFile );
mInitFilePathLabel->setVisible( codeSource == QgsEditFormConfig::PythonInitCodeSource::CodeSourceFile );
}
void QgsFieldsProperties::attributeTypeDialog()
@ -805,6 +818,22 @@ QgsAttributeEditorElement* QgsFieldsProperties::createAttributeEditorWidget( QTr
return widgetDef;
}
void QgsFieldsProperties::on_pbtnSelectInitFilePath_clicked()
{
QSettings myQSettings;
QString lastUsedDir = myQSettings.value( "style/lastUIDir", "." ).toString();
QString pyfilename = QFileDialog::getOpenFileName( this, tr( "Select Python file" ), lastUsedDir, tr( "Python file" ) + " (*.py)" );
if ( pyfilename.isNull() )
return;
QFileInfo fi( pyfilename );
myQSettings.setValue( "style/lastUIDir", fi.path() );
mInitFilePathLineEdit->setText( pyfilename );
}
void QgsFieldsProperties::on_pbnSelectEditForm_clicked()
{
QSettings myQSettings;
@ -816,7 +845,7 @@ void QgsFieldsProperties::on_pbnSelectEditForm_clicked()
QFileInfo fi( uifilename );
myQSettings.setValue( "style/lastUIDir", fi.path() );
leEditForm->setText( uifilename );
mEditFormLineEdit->setText( uifilename );
}
void QgsFieldsProperties::on_mEditorLayoutComboBox_currentIndexChanged( int index )
@ -875,10 +904,14 @@ void QgsFieldsProperties::apply()
mLayer->editFormConfig()->setLayout(( QgsEditFormConfig::EditorLayout ) mEditorLayoutComboBox->currentIndex() );
if ( mEditorLayoutComboBox->currentIndex() == QgsEditFormConfig::UiFileLayout )
mLayer->editFormConfig()->setUiForm( leEditForm->text() );
mLayer->editFormConfig()->setInitFunction( leEditFormInit->text() );
mLayer->editFormConfig()->setUseInitCode( leEditFormInitUseCode->isChecked() );
mLayer->editFormConfig()->setInitCode( leEditFormInitCode->text() );
mLayer->editFormConfig()->setUiForm( mEditFormLineEdit->text() );
// Init function configuration
mLayer->editFormConfig()->setInitFunction( mInitFunctionLineEdit->text( ) );
mLayer->editFormConfig()->setInitCode( mInitCodeEditorPython->text( ) );
mLayer->editFormConfig()->setInitFilePath( mInitFilePathLineEdit->text( ) );
mLayer->editFormConfig()->setInitCodeSource(( QgsEditFormConfig::PythonInitCodeSource )mInitCodeSourceComboBox->currentIndex() );
mLayer->editFormConfig()->setSuppress(( QgsEditFormConfig::FeatureFormSuppress )mFormSuppressCmbBx->currentIndex() );
mLayer->setExcludeAttributesWMS( excludeAttributesWMS );

View File

@ -163,11 +163,16 @@ class APP_EXPORT QgsFieldsProperties : public QWidget, private Ui_QgsFieldsPrope
/**
* @brief setEditFormInit set the private ui fields
* @param editForm
* @param editFormInit
* @param editFormInitCode
* @param editFormInitUseCode
* @param initFunction
* @param initCode
* @param initFilePath
* @param codeSource
*/
void setEditFormInit( const QString &editForm, const QString &editFormInit, const QString &editFormInitCode, const bool editFormInitUseCode );
void setEditFormInit( const QString &editForm,
const QString &initFunction,
const QString &initCode,
const QString &initFilePath,
const QgsEditFormConfig::PythonInitCodeSource &codeSource );
signals:
void toggleEditing();
@ -177,9 +182,10 @@ class APP_EXPORT QgsFieldsProperties : public QWidget, private Ui_QgsFieldsPrope
void on_mDeleteAttributeButton_clicked();
void on_mCalculateFieldButton_clicked();
void onAttributeSelectionChanged();
void on_pbtnSelectInitFilePath_clicked();
void on_pbnSelectEditForm_clicked();
void on_mEditorLayoutComboBox_currentIndexChanged( int index );
void on_leEditFormInitUseCode_toggled( bool checked );
void on_mInitCodeSourceComboBox_currentIndexChanged( int codeSource );
void attributeAdded( int idx );
void attributeDeleted( int idx );
void attributeTypeDialog();

View File

@ -1317,5 +1317,5 @@ void QgsVectorLayerProperties::updateVariableEditor()
void QgsVectorLayerProperties::updateFieldsPropertiesDialog()
{
QgsEditFormConfig* cfg = layer->editFormConfig();
mFieldsPropertiesDialog->setEditFormInit( cfg->uiForm(), cfg->initFunction(), cfg->initCode(), cfg->useInitCode() );
mFieldsPropertiesDialog->setEditFormInit( cfg->uiForm(), cfg->initFunction(), cfg->initCode(), cfg->initFilePath(), cfg->initCodeSource() );
}

View File

@ -4,8 +4,8 @@
QgsEditFormConfig::QgsEditFormConfig( QObject* parent )
: QObject( parent )
, mEditorLayout( GeneratedLayout )
, mInitCodeSource( QgsEditFormConfig::PythonInitCodeSource::CodeSourceNone )
, mFeatureFormSuppress( SuppressDefault )
, mUseInitCode( false )
{
connect( QgsProject::instance()->relationManager(), SIGNAL( relationsLoaded() ), this, SLOT( onRelationsLoaded() ) );
}

View File

@ -271,6 +271,7 @@ class CORE_EXPORT QgsEditFormConfig : public QObject
Q_OBJECT
public:
/** The different types to layout the attribute editor. */
enum EditorLayout
{
@ -308,6 +309,17 @@ class CORE_EXPORT QgsEditFormConfig : public QObject
SuppressOff = 2 //!< Do not suppress feature form
};
/**
* The python init code source options.
*/
enum PythonInitCodeSource
{
CodeSourceNone = 0, //!< Do not use python code at all
CodeSourceFile = 1, //!< Load the python code from an external file
CodeSourceDialog = 2, //!< Use the python code provided in the dialog
CodeSourceEnvironment = 3 //!< Use the python code available in the python environment
};
/**
* This is only useful in combination with EditorLayout::TabLayout.
*
@ -459,17 +471,7 @@ class CORE_EXPORT QgsEditFormConfig : public QObject
void setLabelOnTop( int idx, bool onTop );
// Python stuff
// Python form init function stuff
/**
* Get python function for edit form initialization.
@ -490,20 +492,35 @@ class CORE_EXPORT QgsEditFormConfig : public QObject
/**
* Get python code for edit form initialization.
*/
QString initCode() const { return mEditFormInitCode; }
QString initCode() const { return mInitCode; }
/**
* Get python code for edit form initialization.
* Set python code for edit form initialization.
* Make sure that you also set the appropriate function name in
* @link setInitFunction @endlink
*/
void setInitCode( const QString& code ) { mEditFormInitCode = code; }
void setInitCode( const QString& code ) { mInitCode = code; }
/** Return if python code shall be loaded for edit form initialization */
bool useInitCode() const { return mUseInitCode; }
/**
* Get python external file path for edit form initialization.
*/
QString initFilePath() const { return mInitFilePath; }
/** Set if python code shall be used for edit form initialization */
void setUseInitCode( const bool useCode ) { mUseInitCode = useCode; }
/**
* Set python external file path for edit form initialization.
* Make sure that you also set the appropriate function name in
* @link setInitFunction @endlink
*/
void setInitFilePath( const QString& filePath ) { mInitFilePath = filePath; }
/** Return python code source for edit form initialization
* (if it shall be loaded from a file, read from the
* provided dialog editor or inherited from the environment)
*/
PythonInitCodeSource initCodeSource() const { return mInitCodeSource; }
/** Set if python code shall be used for edit form initialization and its origin */
void setInitCodeSource( const PythonInitCodeSource initCodeSource ) { mInitCodeSource = initCodeSource; }
/** Type of feature form pop-up suppression after feature creation (overrides app setting) */
FeatureFormSuppress suppress() const { return mFeatureFormSuppress; }
@ -547,9 +564,16 @@ class CORE_EXPORT QgsEditFormConfig : public QObject
/** Defines the default layout to use for the attribute editor (Drag and drop, UI File, Generated) */
EditorLayout mEditorLayout;
/** Init form instance */
QString mEditForm;
/** Name of the python form init function */
QString mInitFunction;
QString mEditFormInitCode;
/** Path of the python external file to be loaded */
QString mInitFilePath;
/** Choose the source of the init founction */
PythonInitCodeSource mInitCodeSource;
/** Python init code provided in the dialog */
QString mInitCode;
/** Type of feature form suppression after feature creation */
FeatureFormSuppress mFeatureFormSuppress;

View File

@ -1786,10 +1786,16 @@ bool QgsVectorLayer::readSymbology( const QDomNode& node, QString& errorMessage
mEditFormConfig->setInitCode( editFormInitCodeNode.toElement().text() );
}
QDomNode editFormInitUseCodeNode = node.namedItem( "editforminitusecode" );
if ( !editFormInitCodeNode.isNull() || ( !editFormInitNode.isNull() && !editFormInitNode.toElement().text().isEmpty() ) )
QDomNode editFormInitCodeSourceNode = node.namedItem( "editforminitcodesource" );
if ( !editFormInitCodeSourceNode.isNull() || ( !editFormInitCodeSourceNode.isNull() && !editFormInitCodeSourceNode.toElement().text().isEmpty() ) )
{
mEditFormConfig->setUseInitCode( editFormInitUseCodeNode.toElement().text().toInt() );
mEditFormConfig->setInitCodeSource(( QgsEditFormConfig::PythonInitCodeSource ) editFormInitCodeSourceNode.toElement().text().toInt() );
}
QDomNode editFormInitFilePathNode = node.namedItem( "editforminitfilepath" );
if ( !editFormInitFilePathNode.isNull() || ( !editFormInitFilePathNode.isNull() && !editFormInitFilePathNode.toElement().text().isEmpty() ) )
{
mEditFormConfig->setInitFilePath( editFormInitFilePathNode.toElement().text() );
}
QDomNode fFSuppNode = node.namedItem( "featformsuppress" );
@ -2054,9 +2060,14 @@ bool QgsVectorLayer::writeSymbology( QDomNode& node, QDomDocument& doc, QString&
efiField.appendChild( doc.createTextNode( mEditFormConfig->initFunction() ) );
node.appendChild( efiField );
QDomElement efiucField = doc.createElement( "editforminitusecode" );
efiucField.appendChild( doc.createTextNode( mEditFormConfig->useInitCode() ? "1" : "0" ) );
node.appendChild( efiucField );
QDomElement eficsField = doc.createElement( "editforminitcodesource" );
eficsField.appendChild( doc.createTextNode( QString::number( mEditFormConfig->initCodeSource() ) ) );
node.appendChild( eficsField );
QDomElement efifpField = doc.createElement( "editforminitfilepath" );
efifpField.appendChild( doc.createTextNode( mEditFormConfig->initFilePath() ) );
node.appendChild( efifpField );
QDomElement eficField = doc.createElement( "editforminitcode" );
eficField.appendChild( doc.createCDATASection( mEditFormConfig->initCode() ) );

View File

@ -25,7 +25,9 @@
#include "qgsvectordataprovider.h"
#include <QDir>
#include <QTextStream>
#include <QFileInfo>
#include <QFile>
#include <QFormLayout>
#include <QGridLayout>
#include <QGroupBox>
@ -575,36 +577,63 @@ void QgsAttributeForm::initPython()
cleanPython();
// Init Python
if ( !mLayer->editFormConfig()->initFunction().isEmpty() )
if ( !mLayer->editFormConfig()->initFunction().isEmpty()
&& mLayer->editFormConfig()->initCodeSource() != QgsEditFormConfig::PythonInitCodeSource::CodeSourceNone )
{
QString module = mLayer->editFormConfig()->initFunction();
int pos = module.lastIndexOf( '.' );
QString initFunction = mLayer->editFormConfig()->initFunction();
QString initFilePath = mLayer->editFormConfig()->initFilePath();
QString initCode;
if ( pos >= 0 ) // It's a module
switch ( mLayer->editFormConfig()->initCodeSource() )
{
QgsPythonRunner::run( QString( "import %1" ).arg( module.left( pos ) ) );
/* Reload the module if the DEBUGMODE switch has been set in the module.
If set to False you have to reload QGIS to reset it to True due to Python
module caching */
QString reload = QString( "if hasattr(%1,'DEBUGMODE') and %1.DEBUGMODE:"
" reload(%1)" ).arg( module.left( pos ) );
case QgsEditFormConfig::PythonInitCodeSource::CodeSourceFile:
if ( ! initFilePath.isEmpty() )
{
QFile inputFile( initFilePath );
QgsPythonRunner::run( reload );
}
else if ( mLayer->editFormConfig()->useInitCode() ) // Must be supplied code
{
QgsPythonRunner::run( mLayer->editFormConfig()->initCode() );
}
else
{
QgsDebugMsg( "No dot in editFormInit and no custom python code provided! There is nothing to run." );
if ( inputFile.open( QFile::ReadOnly ) )
{
// Read it into a string
QTextStream inf( &inputFile );
initCode = inf.readAll();
inputFile.close();
}
else // The file couldn't be opened
{
QgsLogger::warning( QString( "The external python file path %1 could not be opened!" ).arg( initFilePath ) );
}
}
else
{
QgsLogger::warning( QString( "The external python file path is empty!" ) );
}
break;
case( QgsEditFormConfig::PythonInitCodeSource::CodeSourceDialog ):
initCode = mLayer->editFormConfig()->initCode();
if ( initCode.isEmpty() )
{
QgsLogger::warning( QString( "The python code provided in the dialog is empty!" ) );
}
break;
case( QgsEditFormConfig::PythonInitCodeSource::CodeSourceEnvironment ):
case( QgsEditFormConfig::PythonInitCodeSource::CodeSourceNone ):
default:
// Nothing to do
break;
}
// If we have a function code, run it
if ( ! initCode.isEmpty() )
{
QgsPythonRunner::run( initCode );
}
QgsPythonRunner::run( "import inspect" );
QString numArgs;
QgsPythonRunner::eval( QString( "len(inspect.getargspec(%1)[0])" ).arg( module ), numArgs );
QgsPythonRunner::eval( QString( "len(inspect.getargspec(%1)[0])" ).arg( initFunction ), numArgs );
static int sFormId = 0;
mPyFormVarName = QString( "_qgis_featureform_%1_%2" ).arg( mFormNr ).arg( sFormId++ );
@ -620,7 +649,7 @@ void QgsAttributeForm::initPython()
// Legacy
if ( numArgs == "3" )
{
addInterface( new QgsAttributeFormLegacyInterface( module, mPyFormVarName, this ) );
addInterface( new QgsAttributeFormLegacyInterface( initFunction, mPyFormVarName, this ) );
}
else
{

View File

@ -6,12 +6,12 @@
<rect>
<x>0</x>
<y>0</y>
<width>965</width>
<height>634</height>
<width>614</width>
<height>423</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_6">
<item row="1" column="0" colspan="7">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_2">
@ -66,16 +66,21 @@
<property name="toolTip">
<string>QGIS forms can have a Python function that is called when the form is opened.
Use this function to add extra logic to your forms.
The function code of the function can be loaded from the source code entered
in this dialog, from an external python file or from the environment (for example
from a plugin or from startup.py).
An example is (in module MyForms.py):
An example is:
def open(dialog, layer, feature):
from PyQt4.QtGui import QWidget
def my_form_open(dialog, layer, feature):
geom = feature.geometry()
control = dialog.findChild(QWidget,&quot;MyLineEdit&quot;)
Reference in Python Init Function like so: MyForms.open
Reference in function name: my_form_open
MyForms.py must live on PYTHONPATH, .qgis/python, or inside the project folder.</string>
</string>
</property>
<property name="text">
<string>Python Init function</string>
@ -83,54 +88,92 @@ MyForms.py must live on PYTHONPATH, .qgis/python, or inside the project folder.<
</widget>
</item>
<item>
<widget class="QLineEdit" name="leEditFormInit">
<widget class="QComboBox" name="mInitCodeSourceComboBox">
<property name="toolTip">
<string>QGIS forms can have a Python function that is called when the form is opened.
Use this function to add extra logic to your forms. You can either provide the python
code directly in this dialog or run the code from an external file (that must live on
PYTHONPATH, .qgis/python, or inside the project folder).
Use this function to add extra logic to your forms.
The function code of the function can be loaded from the source code entered
in this dialog, from an external python file or from the environment (for example
from a plugin or from startup.py).
An example is (in module MyForms.py):
An example is:
def open(dialog, layer, feature):
from PyQt4.QtGui import QWidget
def my_form_open(dialog, layer, feature):
geom = feature.geometry()
control = dialog.findChild(QWidget,&quot;MyLineEdit&quot;)
Reference in Python Init Function like so: &quot;MyForms.open&quot; or just &quot;open&quot; if provided
directly in this dialog.
Reference in function name: my_form_open
</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<widget class="QLabel" name="mFormSuppressLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="sizeHint" stdset="0">
<property name="minimumSize">
<size>
<width>40</width>
<height>20</height>
<width>150</width>
<height>0</height>
</size>
</property>
</spacer>
<property name="text">
<string>Suppress attribute form pop-up after feature creation</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="leEditFormInitUseCode">
<property name="toolTip">
<string>Check this box to provide python init function code here instead of using an external file.</string>
</property>
<property name="text">
<string>Use provided code</string>
<widget class="QComboBox" name="mFormSuppressCmbBx">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>Default</string>
</property>
</item>
<item>
<property name="text">
<string>On</string>
</property>
</item>
<item>
<property name="text">
<string>Off</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item row="2" column="0" colspan="7">
<item row="2" column="0">
<widget class="QSplitter" name="mSplitter">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
@ -164,7 +207,7 @@ directly in this dialog.
</property>
<property name="icon">
<iconset>
<normaloff>.designer/xpm/delete_attribute.png</normaloff>.designer/xpm/delete_attribute.png</iconset>
<normaloff>../../../../.designer/backup/.designer/xpm/delete_attribute.png</normaloff>../../../../.designer/backup/.designer/xpm/delete_attribute.png</iconset>
</property>
<property name="shortcut">
<string>Ctrl+X</string>
@ -219,7 +262,7 @@ directly in this dialog.
</property>
<property name="icon">
<iconset>
<normaloff>.designer/xpm/new_attribute.png</normaloff>.designer/xpm/new_attribute.png</iconset>
<normaloff>../../../../.designer/backup/.designer/xpm/new_attribute.png</normaloff>../../../../.designer/backup/.designer/xpm/new_attribute.png</iconset>
</property>
<property name="shortcut">
<string>Ctrl+N</string>
@ -264,7 +307,7 @@ directly in this dialog.
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QgsCodeEditorPython" name="leEditFormInitCode" native="true"/>
<widget class="QgsCodeEditorPython" name="mInitCodeEditorPython" native="true"/>
</item>
</layout>
</widget>
@ -293,7 +336,7 @@ directly in this dialog.
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLineEdit" name="leEditForm"/>
<widget class="QLineEdit" name="mEditFormLineEdit"/>
</item>
<item>
<widget class="QToolButton" name="pbnSelectEditForm">
@ -486,59 +529,73 @@ directly in this dialog.
</widget>
</widget>
</item>
<item row="3" column="0" colspan="7">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="mFormSuppressLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Suppress attribute form pop-up after feature creation</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="mFormSuppressCmbBx">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<item row="1" column="0">
<widget class="QWidget" name="mInitFunctionContainer" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="mInitFunctionLabel">
<property name="text">
<string>Default</string>
<string>Function name</string>
</property>
</item>
<item>
</widget>
</item>
<item>
<widget class="QLineEdit" name="mInitFunctionLineEdit">
<property name="toolTip">
<string>Enter the name of the form init function.</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="mInitFilePathLabel">
<property name="text">
<string>On</string>
<string>External file</string>
</property>
</item>
<item>
</widget>
</item>
<item>
<widget class="QLineEdit" name="mInitFilePathLineEdit"/>
</item>
<item>
<widget class="QToolButton" name="pbtnSelectInitFilePath">
<property name="text">
<string>Off</string>
<string>...</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
@ -558,12 +615,11 @@ directly in this dialog.
</customwidgets>
<tabstops>
<tabstop>mEditorLayoutComboBox</tabstop>
<tabstop>leEditFormInit</tabstop>
<tabstop>mAddAttributeButton</tabstop>
<tabstop>mDeleteAttributeButton</tabstop>
<tabstop>mToggleEditingButton</tabstop>
<tabstop>mCalculateFieldButton</tabstop>
<tabstop>leEditForm</tabstop>
<tabstop>mEditFormLineEdit</tabstop>
<tabstop>pbnSelectEditForm</tabstop>
<tabstop>mAddTabOrGroupButton</tabstop>
<tabstop>mRemoveTabGroupItemButton</tabstop>