mirror of
https://github.com/qgis/QGIS.git
synced 2025-11-03 00:14:12 -05:00
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:
parent
de3ce1560c
commit
e5ca63deed
@ -57,6 +57,18 @@ class QgsEditFormConfig : QObject
|
|||||||
SuppressOff = 2 //!< Do not suppress feature form
|
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.
|
* This is only useful in combination with EditorLayout::TabLayout.
|
||||||
*
|
*
|
||||||
@ -208,15 +220,6 @@ class QgsEditFormConfig : QObject
|
|||||||
void setLabelOnTop( int idx, bool onTop );
|
void setLabelOnTop( int idx, bool onTop );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Python stuff
|
// Python stuff
|
||||||
|
|
||||||
|
|
||||||
@ -237,10 +240,22 @@ class QgsEditFormConfig : QObject
|
|||||||
void setInitFunction( const QString& function );
|
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;
|
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.
|
* Get python code for edit form initialization.
|
||||||
* Make sure that you also set the appropriate function name in
|
* Make sure that you also set the appropriate function name in
|
||||||
@ -248,11 +263,15 @@ class QgsEditFormConfig : QObject
|
|||||||
*/
|
*/
|
||||||
void setInitCode( const QString& code );
|
void setInitCode( const QString& code );
|
||||||
|
|
||||||
/** Return if python code shall be loaded for edit form initialization */
|
/** Return python code source for edit form initialization
|
||||||
bool useInitCode() const;
|
* (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 */
|
/** 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) */
|
/** Type of feature form pop-up suppression after feature creation (overrides app setting) */
|
||||||
FeatureFormSuppress suppress() const;
|
FeatureFormSuppress suppress() const;
|
||||||
|
|||||||
@ -115,6 +115,12 @@ QgsFieldsProperties::QgsFieldsProperties( QgsVectorLayer *layer, QWidget* parent
|
|||||||
mRelationsList->setHorizontalHeaderItem( RelFieldCol, new QTableWidgetItem( tr( "Field" ) ) );
|
mRelationsList->setHorizontalHeaderItem( RelFieldCol, new QTableWidgetItem( tr( "Field" ) ) );
|
||||||
mRelationsList->verticalHeader()->hide();
|
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();
|
loadRelations();
|
||||||
|
|
||||||
updateButtons();
|
updateButtons();
|
||||||
@ -183,11 +189,15 @@ QTreeWidgetItem *QgsFieldsProperties::loadAttributeEditorTreeItem( QgsAttributeE
|
|||||||
return newWidget;
|
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
|
// Python init function and code
|
||||||
QString code( editFormInitCode );
|
QString code( initCode );
|
||||||
if ( code.isEmpty( ) )
|
if ( code.isEmpty( ) )
|
||||||
{
|
{
|
||||||
code.append( tr( "# -*- coding: utf-8 -*-\n\"\"\"\n"
|
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" ) );
|
"\tcontrol = dialog.findChild(QWidget, \"MyLineEdit\")\n" ) );
|
||||||
|
|
||||||
}
|
}
|
||||||
leEditForm->setText( editForm );
|
mEditFormLineEdit->setText( editForm );
|
||||||
leEditFormInitCode->setText( code );
|
mInitFilePathLineEdit->setText( initFilePath );
|
||||||
leEditFormInit->setText( editFormInit );
|
mInitCodeEditorPython->setText( code );
|
||||||
leEditFormInitUseCode->setChecked( editFormInitUseCode );
|
mInitFunctionLineEdit->setText( initFunction );
|
||||||
// Show or hide as needed
|
mInitCodeSourceComboBox->setCurrentIndex( codeSource );
|
||||||
mPythonInitCodeGroupBox->setVisible( editFormInitUseCode );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -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()
|
void QgsFieldsProperties::attributeTypeDialog()
|
||||||
@ -805,6 +818,22 @@ QgsAttributeEditorElement* QgsFieldsProperties::createAttributeEditorWidget( QTr
|
|||||||
return widgetDef;
|
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()
|
void QgsFieldsProperties::on_pbnSelectEditForm_clicked()
|
||||||
{
|
{
|
||||||
QSettings myQSettings;
|
QSettings myQSettings;
|
||||||
@ -816,7 +845,7 @@ void QgsFieldsProperties::on_pbnSelectEditForm_clicked()
|
|||||||
|
|
||||||
QFileInfo fi( uifilename );
|
QFileInfo fi( uifilename );
|
||||||
myQSettings.setValue( "style/lastUIDir", fi.path() );
|
myQSettings.setValue( "style/lastUIDir", fi.path() );
|
||||||
leEditForm->setText( uifilename );
|
mEditFormLineEdit->setText( uifilename );
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsFieldsProperties::on_mEditorLayoutComboBox_currentIndexChanged( int index )
|
void QgsFieldsProperties::on_mEditorLayoutComboBox_currentIndexChanged( int index )
|
||||||
@ -875,10 +904,14 @@ void QgsFieldsProperties::apply()
|
|||||||
|
|
||||||
mLayer->editFormConfig()->setLayout(( QgsEditFormConfig::EditorLayout ) mEditorLayoutComboBox->currentIndex() );
|
mLayer->editFormConfig()->setLayout(( QgsEditFormConfig::EditorLayout ) mEditorLayoutComboBox->currentIndex() );
|
||||||
if ( mEditorLayoutComboBox->currentIndex() == QgsEditFormConfig::UiFileLayout )
|
if ( mEditorLayoutComboBox->currentIndex() == QgsEditFormConfig::UiFileLayout )
|
||||||
mLayer->editFormConfig()->setUiForm( leEditForm->text() );
|
mLayer->editFormConfig()->setUiForm( mEditFormLineEdit->text() );
|
||||||
mLayer->editFormConfig()->setInitFunction( leEditFormInit->text() );
|
|
||||||
mLayer->editFormConfig()->setUseInitCode( leEditFormInitUseCode->isChecked() );
|
// Init function configuration
|
||||||
mLayer->editFormConfig()->setInitCode( leEditFormInitCode->text() );
|
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->editFormConfig()->setSuppress(( QgsEditFormConfig::FeatureFormSuppress )mFormSuppressCmbBx->currentIndex() );
|
||||||
|
|
||||||
mLayer->setExcludeAttributesWMS( excludeAttributesWMS );
|
mLayer->setExcludeAttributesWMS( excludeAttributesWMS );
|
||||||
|
|||||||
@ -163,11 +163,16 @@ class APP_EXPORT QgsFieldsProperties : public QWidget, private Ui_QgsFieldsPrope
|
|||||||
/**
|
/**
|
||||||
* @brief setEditFormInit set the private ui fields
|
* @brief setEditFormInit set the private ui fields
|
||||||
* @param editForm
|
* @param editForm
|
||||||
* @param editFormInit
|
* @param initFunction
|
||||||
* @param editFormInitCode
|
* @param initCode
|
||||||
* @param editFormInitUseCode
|
* @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:
|
signals:
|
||||||
void toggleEditing();
|
void toggleEditing();
|
||||||
@ -177,9 +182,10 @@ class APP_EXPORT QgsFieldsProperties : public QWidget, private Ui_QgsFieldsPrope
|
|||||||
void on_mDeleteAttributeButton_clicked();
|
void on_mDeleteAttributeButton_clicked();
|
||||||
void on_mCalculateFieldButton_clicked();
|
void on_mCalculateFieldButton_clicked();
|
||||||
void onAttributeSelectionChanged();
|
void onAttributeSelectionChanged();
|
||||||
|
void on_pbtnSelectInitFilePath_clicked();
|
||||||
void on_pbnSelectEditForm_clicked();
|
void on_pbnSelectEditForm_clicked();
|
||||||
void on_mEditorLayoutComboBox_currentIndexChanged( int index );
|
void on_mEditorLayoutComboBox_currentIndexChanged( int index );
|
||||||
void on_leEditFormInitUseCode_toggled( bool checked );
|
void on_mInitCodeSourceComboBox_currentIndexChanged( int codeSource );
|
||||||
void attributeAdded( int idx );
|
void attributeAdded( int idx );
|
||||||
void attributeDeleted( int idx );
|
void attributeDeleted( int idx );
|
||||||
void attributeTypeDialog();
|
void attributeTypeDialog();
|
||||||
|
|||||||
@ -1317,5 +1317,5 @@ void QgsVectorLayerProperties::updateVariableEditor()
|
|||||||
void QgsVectorLayerProperties::updateFieldsPropertiesDialog()
|
void QgsVectorLayerProperties::updateFieldsPropertiesDialog()
|
||||||
{
|
{
|
||||||
QgsEditFormConfig* cfg = layer->editFormConfig();
|
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() );
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,8 +4,8 @@
|
|||||||
QgsEditFormConfig::QgsEditFormConfig( QObject* parent )
|
QgsEditFormConfig::QgsEditFormConfig( QObject* parent )
|
||||||
: QObject( parent )
|
: QObject( parent )
|
||||||
, mEditorLayout( GeneratedLayout )
|
, mEditorLayout( GeneratedLayout )
|
||||||
|
, mInitCodeSource( QgsEditFormConfig::PythonInitCodeSource::CodeSourceNone )
|
||||||
, mFeatureFormSuppress( SuppressDefault )
|
, mFeatureFormSuppress( SuppressDefault )
|
||||||
, mUseInitCode( false )
|
|
||||||
{
|
{
|
||||||
connect( QgsProject::instance()->relationManager(), SIGNAL( relationsLoaded() ), this, SLOT( onRelationsLoaded() ) );
|
connect( QgsProject::instance()->relationManager(), SIGNAL( relationsLoaded() ), this, SLOT( onRelationsLoaded() ) );
|
||||||
}
|
}
|
||||||
|
|||||||
@ -271,6 +271,7 @@ class CORE_EXPORT QgsEditFormConfig : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** The different types to layout the attribute editor. */
|
/** The different types to layout the attribute editor. */
|
||||||
enum EditorLayout
|
enum EditorLayout
|
||||||
{
|
{
|
||||||
@ -308,6 +309,17 @@ class CORE_EXPORT QgsEditFormConfig : public QObject
|
|||||||
SuppressOff = 2 //!< Do not suppress feature form
|
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.
|
* 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 );
|
void setLabelOnTop( int idx, bool onTop );
|
||||||
|
|
||||||
|
|
||||||
|
// Python form init function stuff
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Python stuff
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get python function for edit form initialization.
|
* Get python function for edit form initialization.
|
||||||
@ -490,20 +492,35 @@ class CORE_EXPORT QgsEditFormConfig : public QObject
|
|||||||
/**
|
/**
|
||||||
* Get python code for edit form initialization.
|
* 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
|
* Make sure that you also set the appropriate function name in
|
||||||
* @link setInitFunction @endlink
|
* @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) */
|
/** Type of feature form pop-up suppression after feature creation (overrides app setting) */
|
||||||
FeatureFormSuppress suppress() const { return mFeatureFormSuppress; }
|
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) */
|
/** Defines the default layout to use for the attribute editor (Drag and drop, UI File, Generated) */
|
||||||
EditorLayout mEditorLayout;
|
EditorLayout mEditorLayout;
|
||||||
|
|
||||||
|
/** Init form instance */
|
||||||
QString mEditForm;
|
QString mEditForm;
|
||||||
|
/** Name of the python form init function */
|
||||||
QString mInitFunction;
|
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 */
|
/** Type of feature form suppression after feature creation */
|
||||||
FeatureFormSuppress mFeatureFormSuppress;
|
FeatureFormSuppress mFeatureFormSuppress;
|
||||||
|
|||||||
@ -1786,10 +1786,16 @@ bool QgsVectorLayer::readSymbology( const QDomNode& node, QString& errorMessage
|
|||||||
mEditFormConfig->setInitCode( editFormInitCodeNode.toElement().text() );
|
mEditFormConfig->setInitCode( editFormInitCodeNode.toElement().text() );
|
||||||
}
|
}
|
||||||
|
|
||||||
QDomNode editFormInitUseCodeNode = node.namedItem( "editforminitusecode" );
|
QDomNode editFormInitCodeSourceNode = node.namedItem( "editforminitcodesource" );
|
||||||
if ( !editFormInitCodeNode.isNull() || ( !editFormInitNode.isNull() && !editFormInitNode.toElement().text().isEmpty() ) )
|
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" );
|
QDomNode fFSuppNode = node.namedItem( "featformsuppress" );
|
||||||
@ -2054,9 +2060,14 @@ bool QgsVectorLayer::writeSymbology( QDomNode& node, QDomDocument& doc, QString&
|
|||||||
efiField.appendChild( doc.createTextNode( mEditFormConfig->initFunction() ) );
|
efiField.appendChild( doc.createTextNode( mEditFormConfig->initFunction() ) );
|
||||||
node.appendChild( efiField );
|
node.appendChild( efiField );
|
||||||
|
|
||||||
QDomElement efiucField = doc.createElement( "editforminitusecode" );
|
QDomElement eficsField = doc.createElement( "editforminitcodesource" );
|
||||||
efiucField.appendChild( doc.createTextNode( mEditFormConfig->useInitCode() ? "1" : "0" ) );
|
eficsField.appendChild( doc.createTextNode( QString::number( mEditFormConfig->initCodeSource() ) ) );
|
||||||
node.appendChild( efiucField );
|
node.appendChild( eficsField );
|
||||||
|
|
||||||
|
QDomElement efifpField = doc.createElement( "editforminitfilepath" );
|
||||||
|
efifpField.appendChild( doc.createTextNode( mEditFormConfig->initFilePath() ) );
|
||||||
|
node.appendChild( efifpField );
|
||||||
|
|
||||||
|
|
||||||
QDomElement eficField = doc.createElement( "editforminitcode" );
|
QDomElement eficField = doc.createElement( "editforminitcode" );
|
||||||
eficField.appendChild( doc.createCDATASection( mEditFormConfig->initCode() ) );
|
eficField.appendChild( doc.createCDATASection( mEditFormConfig->initCode() ) );
|
||||||
|
|||||||
@ -25,7 +25,9 @@
|
|||||||
#include "qgsvectordataprovider.h"
|
#include "qgsvectordataprovider.h"
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include <QTextStream>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
|
#include <QFile>
|
||||||
#include <QFormLayout>
|
#include <QFormLayout>
|
||||||
#include <QGridLayout>
|
#include <QGridLayout>
|
||||||
#include <QGroupBox>
|
#include <QGroupBox>
|
||||||
@ -575,36 +577,63 @@ void QgsAttributeForm::initPython()
|
|||||||
cleanPython();
|
cleanPython();
|
||||||
|
|
||||||
// Init Python
|
// 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 ) ) );
|
case QgsEditFormConfig::PythonInitCodeSource::CodeSourceFile:
|
||||||
/* Reload the module if the DEBUGMODE switch has been set in the module.
|
if ( ! initFilePath.isEmpty() )
|
||||||
If set to False you have to reload QGIS to reset it to True due to Python
|
{
|
||||||
module caching */
|
QFile inputFile( initFilePath );
|
||||||
QString reload = QString( "if hasattr(%1,'DEBUGMODE') and %1.DEBUGMODE:"
|
|
||||||
" reload(%1)" ).arg( module.left( pos ) );
|
|
||||||
|
|
||||||
QgsPythonRunner::run( reload );
|
if ( inputFile.open( QFile::ReadOnly ) )
|
||||||
}
|
{
|
||||||
else if ( mLayer->editFormConfig()->useInitCode() ) // Must be supplied code
|
// Read it into a string
|
||||||
{
|
QTextStream inf( &inputFile );
|
||||||
QgsPythonRunner::run( mLayer->editFormConfig()->initCode() );
|
initCode = inf.readAll();
|
||||||
}
|
inputFile.close();
|
||||||
else
|
}
|
||||||
{
|
else // The file couldn't be opened
|
||||||
QgsDebugMsg( "No dot in editFormInit and no custom python code provided! There is nothing to run." );
|
{
|
||||||
|
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" );
|
QgsPythonRunner::run( "import inspect" );
|
||||||
QString numArgs;
|
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;
|
static int sFormId = 0;
|
||||||
mPyFormVarName = QString( "_qgis_featureform_%1_%2" ).arg( mFormNr ).arg( sFormId++ );
|
mPyFormVarName = QString( "_qgis_featureform_%1_%2" ).arg( mFormNr ).arg( sFormId++ );
|
||||||
@ -620,7 +649,7 @@ void QgsAttributeForm::initPython()
|
|||||||
// Legacy
|
// Legacy
|
||||||
if ( numArgs == "3" )
|
if ( numArgs == "3" )
|
||||||
{
|
{
|
||||||
addInterface( new QgsAttributeFormLegacyInterface( module, mPyFormVarName, this ) );
|
addInterface( new QgsAttributeFormLegacyInterface( initFunction, mPyFormVarName, this ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@ -6,12 +6,12 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>965</width>
|
<width>614</width>
|
||||||
<height>634</height>
|
<height>423</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_6">
|
<layout class="QGridLayout" name="gridLayout_6">
|
||||||
<item row="1" column="0" colspan="7">
|
<item row="0" column="0">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_2">
|
<widget class="QLabel" name="label_2">
|
||||||
@ -66,16 +66,21 @@
|
|||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>QGIS forms can have a Python function that is called when the form is opened.
|
<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.
|
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()
|
geom = feature.geometry()
|
||||||
control = dialog.findChild(QWidget,"MyLineEdit")
|
control = dialog.findChild(QWidget,"MyLineEdit")
|
||||||
|
|
||||||
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>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Python Init function</string>
|
<string>Python Init function</string>
|
||||||
@ -83,54 +88,92 @@ MyForms.py must live on PYTHONPATH, .qgis/python, or inside the project folder.<
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLineEdit" name="leEditFormInit">
|
<widget class="QComboBox" name="mInitCodeSourceComboBox">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>QGIS forms can have a Python function that is called when the form is opened.
|
<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
|
Use this function to add extra logic to your forms.
|
||||||
code directly in this dialog or run the code from an external file (that must live on
|
The function code of the function can be loaded from the source code entered
|
||||||
PYTHONPATH, .qgis/python, or inside the project folder).
|
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()
|
geom = feature.geometry()
|
||||||
control = dialog.findChild(QWidget,"MyLineEdit")
|
control = dialog.findChild(QWidget,"MyLineEdit")
|
||||||
|
|
||||||
Reference in Python Init Function like so: "MyForms.open" or just "open" if provided
|
Reference in function name: my_form_open
|
||||||
directly in this dialog.
|
|
||||||
|
|
||||||
|
|
||||||
</string>
|
</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer_3">
|
<widget class="QLabel" name="mFormSuppressLabel">
|
||||||
<property name="orientation">
|
<property name="sizePolicy">
|
||||||
<enum>Qt::Horizontal</enum>
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Maximum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeHint" stdset="0">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>40</width>
|
<width>150</width>
|
||||||
<height>20</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</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>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="leEditFormInitUseCode">
|
<widget class="QComboBox" name="mFormSuppressCmbBx">
|
||||||
<property name="toolTip">
|
<property name="sizePolicy">
|
||||||
<string>Check this box to provide python init function code here instead of using an external file.</string>
|
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||||
</property>
|
<horstretch>0</horstretch>
|
||||||
<property name="text">
|
<verstretch>0</verstretch>
|
||||||
<string>Use provided code</string>
|
</sizepolicy>
|
||||||
</property>
|
</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>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0" colspan="7">
|
<item row="2" column="0">
|
||||||
<widget class="QSplitter" name="mSplitter">
|
<widget class="QSplitter" name="mSplitter">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
@ -164,7 +207,7 @@ directly in this dialog.
|
|||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset>
|
<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>
|
||||||
<property name="shortcut">
|
<property name="shortcut">
|
||||||
<string>Ctrl+X</string>
|
<string>Ctrl+X</string>
|
||||||
@ -219,7 +262,7 @@ directly in this dialog.
|
|||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset>
|
<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>
|
||||||
<property name="shortcut">
|
<property name="shortcut">
|
||||||
<string>Ctrl+N</string>
|
<string>Ctrl+N</string>
|
||||||
@ -264,7 +307,7 @@ directly in this dialog.
|
|||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QgsCodeEditorPython" name="leEditFormInitCode" native="true"/>
|
<widget class="QgsCodeEditorPython" name="mInitCodeEditorPython" native="true"/>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
@ -293,7 +336,7 @@ directly in this dialog.
|
|||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLineEdit" name="leEditForm"/>
|
<widget class="QLineEdit" name="mEditFormLineEdit"/>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QToolButton" name="pbnSelectEditForm">
|
<widget class="QToolButton" name="pbnSelectEditForm">
|
||||||
@ -486,59 +529,73 @@ directly in this dialog.
|
|||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0" colspan="7">
|
<item row="1" column="0">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<widget class="QWidget" name="mInitFunctionContainer" native="true">
|
||||||
<item>
|
<property name="sizePolicy">
|
||||||
<widget class="QLabel" name="mFormSuppressLabel">
|
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
|
||||||
<property name="sizePolicy">
|
<horstretch>0</horstretch>
|
||||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Maximum">
|
<verstretch>0</verstretch>
|
||||||
<horstretch>0</horstretch>
|
</sizepolicy>
|
||||||
<verstretch>0</verstretch>
|
</property>
|
||||||
</sizepolicy>
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
</property>
|
<property name="leftMargin">
|
||||||
<property name="minimumSize">
|
<number>0</number>
|
||||||
<size>
|
</property>
|
||||||
<width>150</width>
|
<property name="topMargin">
|
||||||
<height>0</height>
|
<number>0</number>
|
||||||
</size>
|
</property>
|
||||||
</property>
|
<property name="rightMargin">
|
||||||
<property name="text">
|
<number>0</number>
|
||||||
<string>Suppress attribute form pop-up after feature creation</string>
|
</property>
|
||||||
</property>
|
<property name="bottomMargin">
|
||||||
<property name="alignment">
|
<number>0</number>
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
</property>
|
||||||
</property>
|
<item>
|
||||||
<property name="wordWrap">
|
<widget class="QLabel" name="mInitFunctionLabel">
|
||||||
<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>
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Default</string>
|
<string>Function name</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</widget>
|
||||||
<item>
|
</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">
|
<property name="text">
|
||||||
<string>On</string>
|
<string>External file</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</widget>
|
||||||
<item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="mInitFilePathLineEdit"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="pbtnSelectInitFilePath">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Off</string>
|
<string>...</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</widget>
|
||||||
</widget>
|
</item>
|
||||||
</item>
|
<item>
|
||||||
</layout>
|
<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>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
@ -558,12 +615,11 @@ directly in this dialog.
|
|||||||
</customwidgets>
|
</customwidgets>
|
||||||
<tabstops>
|
<tabstops>
|
||||||
<tabstop>mEditorLayoutComboBox</tabstop>
|
<tabstop>mEditorLayoutComboBox</tabstop>
|
||||||
<tabstop>leEditFormInit</tabstop>
|
|
||||||
<tabstop>mAddAttributeButton</tabstop>
|
<tabstop>mAddAttributeButton</tabstop>
|
||||||
<tabstop>mDeleteAttributeButton</tabstop>
|
<tabstop>mDeleteAttributeButton</tabstop>
|
||||||
<tabstop>mToggleEditingButton</tabstop>
|
<tabstop>mToggleEditingButton</tabstop>
|
||||||
<tabstop>mCalculateFieldButton</tabstop>
|
<tabstop>mCalculateFieldButton</tabstop>
|
||||||
<tabstop>leEditForm</tabstop>
|
<tabstop>mEditFormLineEdit</tabstop>
|
||||||
<tabstop>pbnSelectEditForm</tabstop>
|
<tabstop>pbnSelectEditForm</tabstop>
|
||||||
<tabstop>mAddTabOrGroupButton</tabstop>
|
<tabstop>mAddTabOrGroupButton</tabstop>
|
||||||
<tabstop>mRemoveTabGroupItemButton</tabstop>
|
<tabstop>mRemoveTabGroupItemButton</tabstop>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user