Merge pull request #5467 from signedav/propertieslayout

Propertieslayout Fields And Forms Redesign
This commit is contained in:
Matthias Kuhn 2017-11-08 17:46:11 +01:00 committed by GitHub
commit 140b9568b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 3336 additions and 2077 deletions

View File

@ -602,6 +602,7 @@
<file>themes/default/mActionRegularPolygonCenterPoint.svg</file>
<file>themes/default/3d.svg</file>
<file>themes/default/mActionResizeSquare.svg</file>
<file>themes/default/mSourceFields.svg</file>
</qresource>
<qresource prefix="/images/tips">
<file alias="symbol_levels.png">qgis_tips/symbol_levels.png</file>

View File

@ -0,0 +1,233 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
height="24"
viewBox="0 0 24 24"
width="24"
version="1.1"
id="svg3885"
sodipodi:docname="mSourceFields.svg"
inkscape:version="0.92.2 (5c3e80d, 2017-08-06)">
<metadata
id="metadata3891">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs3889" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="960"
inkscape:window-height="1163"
id="namedview3887"
showgrid="false"
inkscape:snap-page="true"
inkscape:zoom="19.645833"
inkscape:cx="7.1879225"
inkscape:cy="12.377671"
inkscape:window-x="1920"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg3885" />
<linearGradient
gradientUnits="userSpaceOnUse"
x1="-10"
x2="-10"
y1="15"
y2="21"
id="linearGradient3845">
<stop
offset="0"
stop-color="#555753"
id="stop3841" />
<stop
offset="1"
stop-color="#555753"
stop-opacity="0"
id="stop3843" />
</linearGradient>
<g
transform="translate(0 -8)"
id="g3883">
<path
d="m2.5 15.5h19v14h-19z"
id="path3847"
stroke="#6e97c4"
fill="#e6e6e6" />
<path
d="m2.5 10.5h19v5h-19z"
id="path3849"
stroke="#6e97c4"
fill="#bad9ec" />
<path
d="m5 13h4"
overflow="visible"
id="path3851"
stroke-width="2"
stroke="#6e97c4"
fill="none" />
<path
d="m11 13h7.999999"
id="path3853"
stroke-width="2"
stroke="#6e97c4"
fill="none" />
<path
d="m5 17.5h4"
overflow="visible"
id="path3855"
stroke="#6e97c4"
fill="none" />
<path
d="m11 17.5h7.999999"
id="path3857"
stroke="#6e97c4"
fill="none" />
<path
d="m5 20.5h4"
overflow="visible"
id="path3859"
stroke="#6e97c4"
fill="none" />
<path
d="m11 20.5h7.999999"
id="path3861"
stroke="#6e97c4"
fill="none" />
<path
d="m5 23.5h4"
overflow="visible"
id="path3863"
stroke="#6e97c4"
fill="none" />
<path
d="m11 23.5h7.999999"
id="path3865"
stroke="#6e97c4"
fill="none" />
<path
d="m5 26.5h4"
overflow="visible"
id="path3867"
stroke="#6e97c4"
fill="none" />
<path
d="m11 26.5h7.999999"
id="path3869"
stroke="#6e97c4"
fill="none" />
<g
transform="translate(33 8)"
id="g3877" />
<path
d="m6.5 9.5h5v21h-5z"
style="overflow:visible;fill:#e0ce7c;fill-rule:evenodd;stroke:#c4a000;stroke-width:.99999994;stroke-linecap:round"
id="path3879" />
<path
d="m8 13h2"
overflow="visible"
id="path3881"
stroke-width="2"
stroke="#fff"
fill="none" />
</g>
<path
style="fill:#ffff00;stroke-width:0.02545069"
d="m 7.4888653,23.001064 c 0.8293744,-0.0037 2.1865324,-0.0037 3.0159067,0 0.829374,0.0037 0.150795,0.0068 -1.5079533,0.0068 -1.6587487,0 -2.3373277,-0.003 -1.5079534,-0.0068 z"
id="path3977"
inkscape:connector-curvature="0" />
<path
style="fill:#ffff00;stroke-width:0.02545069;opacity:0.71600022"
d="M 6.019088,12 V 1.0053022 H 9.009544 12 V 12 22.994698 H 9.009544 6.019088 Z m 4.988335,0 V 1.9978791 H 8.9968187 6.9862142 V 12 22.002121 h 2.0106045 2.0106043 z"
id="path3979"
inkscape:connector-curvature="0" />
<path
style="opacity:0;fill:#ffff00;stroke-width:0.02545069"
d="M 7.0116649,12 V 1.9978791 H 8.9968187 10.981972 V 12 22.002121 H 8.9968187 7.0116649 Z M 10.002121,5.0010604 V 3.9957582 H 8.9968187 7.9915164 l -0.00667,0.9797811 c -0.00367,0.5388796 -0.00111,0.9942619 0.00568,1.0119608 0.00972,0.025342 0.2247737,0.030765 1.0119733,0.025521 l 0.9996243,-0.00666 z"
id="path3981"
inkscape:connector-curvature="0" />
<path
id="path3983"
style="opacity:0.65080011;fill:#ffff00;stroke-width:0.02545069"
d="M 6.0195312,1.0058594 V 12 22.994141 H 9.0097656 12 v -3.115235 c -0.02521,-0.07868 -0.05191,-0.149388 -0.07422,-0.246094 -0.04835,-0.209599 -0.03941,-0.427775 -0.05078,-0.642578 -0.01066,-0.201346 -0.02346,-0.404079 -0.01367,-0.605468 0.01975,-0.406137 0.06784,-0.61402 0.138672,-0.861328 V 12 1.0058594 H 9.0097656 Z M 6.9863281,1.9980469 H 8.9960938 11.007812 V 12 22.001953 H 8.9960938 6.9863281 V 12 Z" />
<path
style="opacity:0;fill:#ffff00;stroke-width:0.05090138"
d="M 6.0171907,12.004089 V 1.0348423 H 8.9949214 11.972652 V 12.004089 22.973336 H 8.9949214 6.0171907 Z m 4.9883353,0 V 2.0019685 H 8.9949214 6.9843169 V 12.004089 22.00621 h 2.0106045 2.0106046 z"
id="path4017"
inkscape:connector-curvature="0" />
<path
style="opacity:0;fill:#ffff00;stroke-width:0.05090138"
d="M 6.0171907,12.004089 V 1.0348423 H 8.9949214 11.972652 V 12.004089 22.973336 H 8.9949214 6.0171907 Z m 4.9883353,0 V 2.0019685 H 8.9949214 6.9843169 V 12.004089 22.00621 h 2.0106045 2.0106046 z"
id="path4019"
inkscape:connector-curvature="0" />
<path
style="opacity:0;fill:#ffff00;stroke-width:0.05090138"
d="M 6.0171907,12.004089 V 1.0348423 H 8.9949214 11.972652 V 12.004089 22.973336 H 8.9949214 6.0171907 Z m 4.9883353,0 V 2.0019685 H 8.9949214 6.9843169 V 12.004089 22.00621 h 2.0106045 2.0106046 z"
id="path4021"
inkscape:connector-curvature="0" />
<path
style="opacity:0.268;fill:#ffff0c;stroke-width:0.05090138;fill-opacity:1;"
d="M 6.0171907,12.004089 V 1.0348423 H 8.9949214 11.972652 V 12.004089 22.973336 H 8.9949214 6.0171907 Z m 4.9883353,0 V 2.0019685 H 8.9949214 6.9843169 V 12.004089 22.00621 h 2.0106045 2.0106046 z"
id="path4023"
inkscape:connector-curvature="0" />
<path
style="opacity:0.26800005;fill:#fffffe;fill-opacity:1;stroke-width:0.05090138"
d="M 7.025038,12.004089 V 2.0019685 H 9.0101918 10.995346 V 12.004089 22.00621 H 9.0101918 7.025038 Z M 10.028219,5.0051499 V 3.9871223 H 9.0101918 7.9921642 v 1.0180276 1.0180275 h 1.0180276 1.0180272 z"
id="path5168"
inkscape:connector-curvature="0" />
<path
style="opacity:0.26800005;fill:#fffffe;fill-opacity:1;stroke-width:0.05090138"
d="M 7.025038,12.004089 V 2.0019685 H 9.0101918 10.995346 V 12.004089 22.00621 H 9.0101918 7.025038 Z M 10.002769,5.0051499 V 4.012573 L 8.9974665,3.9987716 7.9921642,3.9849702 v 1.0201797 1.0201796 l 1.0053023,-0.013801 1.0053025,-0.013801 z"
id="path5170"
inkscape:connector-curvature="0" />
<path
style="opacity:0.26800005;fill:#fffffe;fill-opacity:1;stroke-width:0.05090138"
d="M 6.0070105,12.004089 V 1.0348423 l 2.990456,3e-7 2.9904555,3e-7 V 12.00409 22.973337 H 8.9974665 l -2.990456,-1e-6 z m 4.9883355,0 V 2.0019685 H 8.9847411 6.9741367 V 12.004089 22.00621 h 2.0106044 2.0106049 z"
id="path5172"
inkscape:connector-curvature="0" />
<path
style="opacity:0.26800005;fill:#fffffe;fill-opacity:1;stroke-width:0.05090138"
d="M 6.0070105,12.004089 V 1.0348423 H 8.9847411 11.962472 V 12.004089 22.973336 H 8.9847411 6.0070105 Z m 4.9883355,0 V 2.0019685 H 8.9847411 6.9741367 V 12.004089 22.00621 h 2.0106044 2.0106049 z"
id="path5174"
inkscape:connector-curvature="0" />
<path
style="opacity:0.26800005;fill:#fffffe;fill-opacity:1;stroke-width:0.05090138"
d="M 6.0070105,12.004089 V 1.0348423 H 8.9847411 11.962472 V 12.004089 22.973336 H 8.9847411 6.0070105 Z m 4.9883355,0 V 2.0019685 H 8.9847411 6.9741367 V 12.004089 22.00621 h 2.0106044 2.0106049 z"
id="path5176"
inkscape:connector-curvature="0" />
<path
style="opacity:0.26800005;fill:#ffff40;fill-opacity:1;stroke-width:0.05090138"
d="M 6.0070105,12.004089 V 1.0348423 H 8.9847411 11.962472 V 12.004089 22.973336 H 8.9847411 6.0070105 Z m 4.9883355,0 V 2.0019685 H 8.9847411 6.9741367 V 12.004089 22.00621 h 2.0106044 2.0106049 z"
id="path5178"
inkscape:connector-curvature="0" />
<path
style="opacity:0.26800005;fill:#ffff40;fill-opacity:1;stroke-width:0.05090138"
d="M 6.0070105,12.004089 V 1.0348423 H 8.9847411 11.962472 V 12.004089 22.973336 H 8.9847411 6.0070105 Z m 4.9883355,0 V 2.0019685 H 8.9847411 6.9741367 V 12.004089 22.00621 h 2.0106044 2.0106049 z"
id="path5180"
inkscape:connector-curvature="0" />
<path
style="opacity:0.26800005;fill:#ffff3b;fill-opacity:1;stroke-width:0.05090138"
d="M 6.0070105,12.004089 V 1.0348423 H 8.9847411 11.962472 V 12.004089 22.973336 H 8.9847411 6.0070105 Z m 4.9883355,0 V 2.0019685 H 8.9847411 6.9741367 V 12.004089 22.00621 h 2.0106044 2.0106049 z"
id="path5182"
inkscape:connector-curvature="0" />
</svg>

After

Width:  |  Height:  |  Size: 9.3 KiB

View File

@ -15,6 +15,8 @@ SET(QGIS_APP_SRCS
qgsattributeactiondialog.cpp
qgsattributeactionpropertiesdialog.cpp
qgsattributetypedialog.cpp
qgsattributerelationedit.cpp
qgsattributesforminitcode.cpp
qgsattributetabledialog.cpp
qgsbookmarks.cpp
qgsclipboard.cpp
@ -40,7 +42,8 @@ SET(QGIS_APP_SRCS
qgsdiagramproperties.cpp
qgsdisplayangle.cpp
qgsfieldcalculator.cpp
qgsfieldsproperties.cpp
qgssourcefieldsproperties.cpp
qgsattributesformproperties.cpp
qgsidentifyresultsdialog.cpp
qgsfeatureaction.cpp
qgslabelpropertydialog.cpp
@ -228,6 +231,8 @@ SET (QGIS_APP_MOC_HDRS
qgsattributeactiondialog.h
qgsattributeactionpropertiesdialog.h
qgsattributetypedialog.h
qgsattributerelationedit.h
qgsattributesforminitcode.h
qgsattributetabledialog.h
qgsbookmarks.h
qgsclipboard.h
@ -251,7 +256,8 @@ SET (QGIS_APP_MOC_HDRS
qgsdxfexportdialog.h
qgsfeatureaction.h
qgsfieldcalculator.h
qgsfieldsproperties.h
qgssourcefieldsproperties.h
qgsattributesformproperties.h
qgsformannotationdialog.h
qgsguivectorlayertools.h
qgshtmlannotationdialog.h

View File

@ -0,0 +1,31 @@
#include "qgsattributerelationedit.h"
#include "ui_qgsattributerelationedit.h"
QgsAttributeRelationEdit::QgsAttributeRelationEdit( const QString &relationid, QWidget *parent ) :
QWidget( parent ),
mRelationId( relationid )
{
setupUi( this );
}
QgsAttributeRelationEdit::~QgsAttributeRelationEdit()
{
}
void QgsAttributeRelationEdit::setCardinalityCombo( const QString &cardinalityComboItem, const QVariant &auserData )
{
coCardinality->addItem( cardinalityComboItem, auserData );
}
void QgsAttributeRelationEdit::setCardinality( const QString &cardinality )
{
int idx = coCardinality->findText( cardinality );
if ( idx != -1 )
coCardinality->setCurrentIndex( idx );
}
QString QgsAttributeRelationEdit::cardinality()
{
return coCardinality->currentText();
}

View File

@ -0,0 +1,57 @@
/***************************************************************************
qgsattributerelationedit.h
---------------------
begin : October 2017
copyright : (C) 2017 by David Signer
email : david at opengis dot ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSATTRIBUTERELATIONEDIT_H
#define QGSATTRIBUTERELATIONEDIT_H
#include "ui_qgsattributerelationedit.h"
#include "qgseditorconfigwidget.h"
#include "qgsfeature.h"
#include "qgsvectordataprovider.h"
#include "qgshelp.h"
#include "qgis_app.h"
#include <QWidget>
class APP_EXPORT QgsAttributeRelationEdit: public QWidget, private Ui::QgsAttributeRelationEdit
{
Q_OBJECT
public:
explicit QgsAttributeRelationEdit( const QString &relationid, QWidget *parent = 0 );
~QgsAttributeRelationEdit();
/**
* Setter for combo cardinality item
*/
void setCardinalityCombo( const QString &cardinalityComboItem, const QVariant &auserData = QVariant() );
/**
* Setter for combo cardinality
*/
void setCardinality( const QString &cardinality );
/**
* Getter for combo cardinality
*/
QString cardinality();
QString mRelationId;
private:
//Ui::QgsAttributeRelationEdit *ui;
};
#endif // QGSATTRIBUTERELATIONEDIT_H

View File

@ -0,0 +1,99 @@
/***************************************************************************
qgsattributesforminitcode.cpp
---------------------
begin : October 2017
copyright : (C) 2017 by David Signer
email : david at opengis dot ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgsattributesforminitcode.h"
#include "ui_qgsattributesforminitcode.h"
#include "qgssettings.h"
#include <QFileDialog>
QgsAttributesFormInitCode::QgsAttributesFormInitCode()
{
setupUi( this );
// Init function stuff
mInitCodeSourceComboBox->addItem( QString() );
mInitCodeSourceComboBox->addItem( tr( "Load from external file" ) );
mInitCodeSourceComboBox->addItem( tr( "Provide code in this dialog" ) );
mInitCodeSourceComboBox->addItem( tr( "Load from the environment" ) );
connect( mInitCodeSourceComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsAttributesFormInitCode::mInitCodeSourceComboBox_currentIndexChanged );
connect( pbtnSelectInitFilePath, &QToolButton::clicked, this, &QgsAttributesFormInitCode::pbtnSelectInitFilePath_clicked );
}
QgsAttributesFormInitCode::~QgsAttributesFormInitCode()
{
}
void QgsAttributesFormInitCode::setCodeSource( QgsEditFormConfig::PythonInitCodeSource initCodeSource )
{
mInitCodeSourceComboBox->setCurrentIndex( initCodeSource );
mInitCodeSourceComboBox_currentIndexChanged( mInitCodeSourceComboBox->currentIndex() );
}
void QgsAttributesFormInitCode::setInitFunction( const QString &initFunction )
{
mInitFunctionLineEdit->setText( initFunction );
}
void QgsAttributesFormInitCode::setInitFilePath( const QString &initFilePath )
{
mInitFilePathLineEdit->setText( initFilePath );
}
void QgsAttributesFormInitCode::setInitCode( const QString &initCode )
{
mInitCodeEditorPython->setText( initCode );
}
QgsEditFormConfig::PythonInitCodeSource QgsAttributesFormInitCode::codeSource() const
{
return ( QgsEditFormConfig::PythonInitCodeSource )mInitCodeSourceComboBox->currentIndex();
}
QString QgsAttributesFormInitCode::initFunction() const
{
return mInitFunctionLineEdit->text();
}
QString QgsAttributesFormInitCode::initFilePath() const
{
return mInitFilePathLineEdit->text();
}
QString QgsAttributesFormInitCode::initCode() const
{
return mInitCodeEditorPython->text();
}
void QgsAttributesFormInitCode::mInitCodeSourceComboBox_currentIndexChanged( int codeSource )
{
mInitFunctionContainer->setVisible( codeSource != QgsEditFormConfig::CodeSourceNone );
mInitFilePathLineEdit->setVisible( codeSource == QgsEditFormConfig::CodeSourceFile );
mInitFilePathLabel->setVisible( codeSource == QgsEditFormConfig::CodeSourceFile );
pbtnSelectInitFilePath->setVisible( codeSource == QgsEditFormConfig::CodeSourceFile );
mInitCodeEditorPython->setVisible( codeSource == QgsEditFormConfig::CodeSourceDialog );
}
void QgsAttributesFormInitCode::pbtnSelectInitFilePath_clicked( )
{
QgsSettings myQSettings;
QString lastUsedDir = myQSettings.value( QStringLiteral( "style/lastInitFilePathDir" ), "." ).toString();
QString pyfilename = QFileDialog::getOpenFileName( this, tr( "Select Python file" ), lastUsedDir, tr( "Python file" ) + " (*.py)" );
if ( pyfilename.isNull() )
return;
QFileInfo fi( pyfilename );
myQSettings.setValue( QStringLiteral( "style/lastInitFilePathDir" ), fi.path() );
mInitFilePathLineEdit->setText( pyfilename );
}

View File

@ -0,0 +1,56 @@
/***************************************************************************
qgsattributesforminitcode.h
---------------------
begin : October 2017
copyright : (C) 2017 by David Signer
email : david at opengis dot ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSATTRIBUTESFORMINITCODE_H
#define QGSATTRIBUTESFORMINITCODE_H
#include "ui_qgsattributesforminitcode.h"
#include "qgseditorconfigwidget.h"
#include "qgsfeature.h"
#include "qgsvectordataprovider.h"
#include "qgshelp.h"
#include "qgis_app.h"
#include <QWidget>
class QDialog;
class APP_EXPORT QgsAttributesFormInitCode: public QDialog, private Ui::QgsAttributesFormInitCode
{
Q_OBJECT
public:
explicit QgsAttributesFormInitCode();
~QgsAttributesFormInitCode();
void setCodeSource( QgsEditFormConfig::PythonInitCodeSource initCodeSourceComboBoxIndex );
void setInitFunction( const QString &initFunction );
void setInitFilePath( const QString &initFilePath );
void setInitCode( const QString &initCode );
QgsEditFormConfig::PythonInitCodeSource codeSource() const;
QString initFunction() const;
QString initFilePath() const;
QString initCode() const;
private:
//Ui::QgsAttributesFormInitCode *ui;
private slots:
void mInitCodeSourceComboBox_currentIndexChanged( int codeSource );
void pbtnSelectInitFilePath_clicked();
};
#endif // QGSATTRIBUTESFORMINITCODE_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,289 @@
/***************************************************************************
qgsattributesformproperties.h
---------------------
begin : August 2017
copyright : (C) 2017 by David Signer
email : david at opengis dot ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSATTRIBUTESFORMPROPERTIES_H
#define QGSATTRIBUTESFORMPROPERTIES_H
#include <QMimeData>
#include <QPushButton>
#include <QTableWidget>
#include <QTreeWidget>
#include <QWidget>
#include <QSpinBox>
#include <QTreeWidgetItem>
#include <QDropEvent>
#include <QTableWidgetItem>
#include <QMessageBox>
#include <QFileDialog>
#include <QHBoxLayout>
#include <QFormLayout>
#include "qgsvectorlayer.h"
#include "ui_qgsattributesformproperties.h"
#include "qgis_app.h"
#include "qgsaddattrdialog.h"
#include "qgslogger.h"
#include "qgsproject.h"
#include "qgsexpressionbuilderdialog.h"
#include "qgsfieldcalculator.h"
#include "qgsfieldexpressionwidget.h"
#include "qgsaddtaborgroup.h"
#include "qgsattributetypedialog.h"
#include "qgsattributerelationedit.h"
#include "qgsattributesforminitcode.h"
#include "qgsgui.h"
#include "qgseditorwidgetfactory.h"
#include "qgseditorwidgetregistry.h"
#include "qgsrelationmanager.h"
class DnDTree;
class APP_EXPORT QgsAttributesFormProperties : public QWidget, private Ui_QgsAttributesFormProperties
{
Q_OBJECT
public:
enum FieldPropertiesRoles
{
DnDTreeRole = Qt::UserRole,
FieldConfigRole,
RelationConfigRole,
FieldNameRole
};
struct RelationEditorConfiguration
{
RelationEditorConfiguration()
: showLinkButton( true )
, showUnlinkButton( true )
{}
bool showLinkButton;
bool showUnlinkButton;
};
class DnDTreeItemData : public QTreeWidgetItem
{
public:
enum Type
{
Field,
Relation,
Container
};
//do we need that
DnDTreeItemData()
: mType( Field )
, mColumnCount( 1 )
, mShowAsGroupBox( false )
, mShowLabel( true )
{}
DnDTreeItemData( Type type, const QString &name )
: mType( type )
, mName( name )
, mColumnCount( 1 )
, mShowAsGroupBox( false )
, mShowLabel( true )
{}
QString name() const { return mName; }
void setName( const QString &name ) { mName = name; }
Type type() const { return mType; }
void setType( Type type ) { mType = type; }
operator QVariant() { return QVariant::fromValue<DnDTreeItemData>( *this ); }
int columnCount() const { return mColumnCount; }
void setColumnCount( int count ) { mColumnCount = count; }
bool showAsGroupBox() const;
void setShowAsGroupBox( bool showAsGroupBox );
bool showLabel() const;
void setShowLabel( bool showLabel );
QgsOptionalExpression visibilityExpression() const;
void setVisibilityExpression( const QgsOptionalExpression &visibilityExpression );
RelationEditorConfiguration relationEditorConfiguration() const;
void setRelationEditorConfiguration( RelationEditorConfiguration relationEditorConfiguration );
private:
Type mType;
QString mName;
int mColumnCount;
bool mShowAsGroupBox;
bool mShowLabel;
QgsOptionalExpression mVisibilityExpression;
RelationEditorConfiguration mRelationEditorConfiguration;
};
/**
* Holds the configuration for a field
*/
struct FieldConfig
{
FieldConfig();
FieldConfig( QgsVectorLayer *layer, int idx );
bool mEditable;
bool mEditableEnabled;
bool mLabelOnTop;
QgsFieldConstraints mFieldConstraints;
QgsFieldConstraints::Constraints mConstraints;
QHash< QgsFieldConstraints::Constraint, QgsFieldConstraints::ConstraintStrength > mConstraintStrength;
QString mConstraint;
QString mConstraintDescription;
QPushButton *mButton = nullptr;
QString mEditorWidgetType;
QMap<QString, QVariant> mEditorWidgetConfig;
QString mAlias;
QString mComment;
operator QVariant();
};
/**
* Holds the configuration for a relation
*/
struct RelationConfig
{
RelationConfig();
RelationConfig( QgsVectorLayer *layer, const QString &relationId );
QString mCardinality;
operator QVariant();
};
public:
explicit QgsAttributesFormProperties( QgsVectorLayer *layer, QWidget *parent = nullptr );
~QgsAttributesFormProperties();
QgsAttributeEditorElement *createAttributeEditorWidget( QTreeWidgetItem *item, QgsAttributeEditorElement *parent, bool forceGroup = true );
void init();
void apply();
void onAttributeSelectionChanged();
void loadRelations();
void initAvailableWidgetsTree();
void initFormLayoutTree();
void initLayoutConfig();
void initInitPython();
void initSuppressCombo();
protected:
void updateButtons();
RelationConfig configForRelation( const QString &relationName );
//QList<QgsRelation> mRelations;
QgsVectorLayer *mLayer = nullptr;
DnDTree *mAvailableWidgetsTree = nullptr;
DnDTree *mFormLayoutTree = nullptr;
QgsAttributeTypeDialog *mAttributeTypeDialog = nullptr;
QgsAttributeRelationEdit *mAttributeRelationEdit = nullptr;
private:
void loadAttributeTypeDialog();
void storeAttributeTypeDialog( );
void loadAttributeRelationEdit();
void storeAttributeRelationEdit( );
QgsEditFormConfig::PythonInitCodeSource mInitCodeSource;
QString mInitFunction;
QString mInitFilePath;
QString mInitCode;
QTreeWidgetItem *loadAttributeEditorTreeItem( QgsAttributeEditorElement *const widgetDef, QTreeWidgetItem *parent, DnDTree *tree );
private slots:
void addTabOrGroupButton();
void removeTabOrGroupButton();
void mEditorLayoutComboBox_currentIndexChanged( int index );
void pbnSelectEditForm_clicked();
void mTbInitCode_clicked();
};
QDataStream &operator<< ( QDataStream &stream, const QgsAttributesFormProperties::DnDTreeItemData &data );
QDataStream &operator>> ( QDataStream &stream, QgsAttributesFormProperties::DnDTreeItemData &data );
/**
* This class overrides mime type handling to be able to work with
* the drag and drop attribute editor.
*
* The mime type is application/x-qgsattributetablefield
*
* Graphical representation for the attribute editor drag and drop editor
*/
class DnDTree : public QTreeWidget
{
Q_OBJECT
public:
explicit DnDTree( QgsVectorLayer *layer, QWidget *parent = nullptr );
QTreeWidgetItem *addItem( QTreeWidgetItem *parent, QgsAttributesFormProperties::DnDTreeItemData data );
QTreeWidgetItem *addContainer( QTreeWidgetItem *parent, const QString &title, int columnCount );
enum Type
{
Drag,
Drop
};
Type type() const;
void setType( const Type &value );
protected:
virtual void dragMoveEvent( QDragMoveEvent *event ) override;
virtual void dropEvent( QDropEvent *event ) override;
virtual bool dropMimeData( QTreeWidgetItem *parent, int index, const QMimeData *data, Qt::DropAction action ) override;
/* Qt::DropActions supportedDropActions() const;*/
// QTreeWidget interface
protected:
virtual QStringList mimeTypes() const override;
virtual QMimeData *mimeData( const QList<QTreeWidgetItem *> items ) const override;
private slots:
void onItemDoubleClicked( QTreeWidgetItem *item, int column );
private:
QgsVectorLayer *mLayer = nullptr;
Type mType;
};
Q_DECLARE_METATYPE( QgsAttributesFormProperties::FieldConfig )
Q_DECLARE_METATYPE( QgsAttributesFormProperties::RelationConfig )
Q_DECLARE_METATYPE( QgsAttributesFormProperties::DnDTreeItemData )
#endif // QGSATTRIBUTESFORMPROPERTIES_H

View File

@ -39,31 +39,28 @@
#include <climits>
#include <cfloat>
QgsAttributeTypeDialog::QgsAttributeTypeDialog( QgsVectorLayer *vl, int fieldIdx )
: mLayer( vl )
QgsAttributeTypeDialog::QgsAttributeTypeDialog( QgsVectorLayer *vl, int fieldIdx, QWidget *parent )
: QWidget( parent )
, mLayer( vl )
, mFieldIdx( fieldIdx )
{
setupUi( this );
connect( selectionListWidget, &QListWidget::currentRowChanged, this, &QgsAttributeTypeDialog::selectionListWidget_currentRowChanged );
setWindowTitle( tr( "Edit Widget Properties - %1 (%2)" ).arg( vl->fields().at( fieldIdx ).name(), vl->name() ) );
if ( fieldIdx < 0 )
return;
QMapIterator<QString, QgsEditorWidgetFactory *> it( QgsGui::editorWidgetRegistry()->factories() );
QStandardItemModel *widgetTypeModel = qobject_cast<QStandardItemModel *>( mWidgetTypeComboBox->model() );
while ( it.hasNext() )
{
it.next();
QListWidgetItem *item = new QListWidgetItem( selectionListWidget );
item->setText( it.value()->name() );
item->setData( Qt::UserRole, it.key() );
mWidgetTypeComboBox->addItem( it.value()->name(), it.key() );
QStandardItem *item = widgetTypeModel->item( mWidgetTypeComboBox->count() - 1 );
if ( !it.value()->supportsField( vl, fieldIdx ) )
item->setFlags( item->flags() & ~Qt::ItemIsEnabled );
selectionListWidget->addItem( item );
}
// Set required list width based on content + twice the border width
selectionListWidget->setMinimumWidth( selectionListWidget->sizeHintForColumn( 0 )
+ 2 );
selectionListWidget->setMaximumWidth( selectionListWidget->sizeHintForColumn( 0 )
+ 2 );
connect( mWidgetTypeComboBox, static_cast< void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsAttributeTypeDialog::onCurrentWidgetChanged );
if ( vl->fields().fieldOrigin( fieldIdx ) == QgsFields::OriginJoin ||
vl->fields().fieldOrigin( fieldIdx ) == QgsFields::OriginExpression )
@ -93,7 +90,6 @@ QgsAttributeTypeDialog::QgsAttributeTypeDialog( QgsVectorLayer *vl, int fieldIdx
restoreGeometry( settings.value( QStringLiteral( "Windows/QgsAttributeTypeDialog/geometry" ) ).toByteArray() );
constraintExpressionWidget->setLayer( vl );
connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsAttributeTypeDialog::showHelp );
}
QgsAttributeTypeDialog::~QgsAttributeTypeDialog()
@ -106,7 +102,7 @@ QgsAttributeTypeDialog::~QgsAttributeTypeDialog()
const QString QgsAttributeTypeDialog::editorWidgetType()
{
QListWidgetItem *item = selectionListWidget->currentItem();
QStandardItem *item = currentItem();
if ( item )
{
return item->data( Qt::UserRole ).toString();
@ -119,7 +115,7 @@ const QString QgsAttributeTypeDialog::editorWidgetType()
const QString QgsAttributeTypeDialog::editorWidgetText()
{
QListWidgetItem *item = selectionListWidget->currentItem();
QStandardItem *item = currentItem();
if ( item )
{
return item->text();
@ -132,7 +128,7 @@ const QString QgsAttributeTypeDialog::editorWidgetText()
const QVariantMap QgsAttributeTypeDialog::editorWidgetConfig()
{
QListWidgetItem *item = selectionListWidget->currentItem();
QStandardItem *item = currentItem();
if ( item )
{
QString widgetType = item->data( Qt::UserRole ).toString();
@ -148,15 +144,8 @@ const QVariantMap QgsAttributeTypeDialog::editorWidgetConfig()
void QgsAttributeTypeDialog::setEditorWidgetType( const QString &type )
{
for ( int i = 0; i < selectionListWidget->count(); i++ )
{
QListWidgetItem *item = selectionListWidget->item( i );
if ( item->data( Qt::UserRole ).toString() == type )
{
selectionListWidget->setCurrentItem( item );
break;
}
}
mWidgetTypeComboBox->setCurrentIndex( mWidgetTypeComboBox->findData( type ) );
if ( mEditorConfigWidgets.contains( type ) )
{
@ -296,6 +285,12 @@ void QgsAttributeTypeDialog::setDefaultValueExpression( const QString &expressio
mExpressionWidget->setExpression( expression );
}
int QgsAttributeTypeDialog::fieldIdx() const
{
return mFieldIdx;
}
QgsExpressionContext QgsAttributeTypeDialog::createExpressionContext() const
{
QgsExpressionContext context;
@ -308,6 +303,15 @@ QgsExpressionContext QgsAttributeTypeDialog::createExpressionContext() const
return context;
}
void QgsAttributeTypeDialog::onCurrentWidgetChanged( int index )
{
Q_UNUSED( index )
QStandardItem *item = currentItem();
const QString editType = item ? item->data( Qt::UserRole ).toString() : QString();
setEditorWidgetType( editType );
}
bool QgsAttributeTypeDialog::applyDefaultValueOnUpdate() const
{
return mApplyDefaultValueOnUpdateCheckBox->isChecked();
@ -328,18 +332,26 @@ void QgsAttributeTypeDialog::setFieldEditable( bool editable )
isFieldEditableCheckBox->setChecked( editable );
}
void QgsAttributeTypeDialog::setAlias( const QString &alias )
{
leAlias->setText( alias );
}
QString QgsAttributeTypeDialog::alias() const
{
return leAlias->text();
}
void QgsAttributeTypeDialog::setComment( const QString &comment )
{
laComment->setText( comment );
}
void QgsAttributeTypeDialog::setLabelOnTop( bool onTop )
{
labelOnTopCheckBox->setChecked( onTop );
}
void QgsAttributeTypeDialog::selectionListWidget_currentRowChanged( int index )
{
const QString editType = selectionListWidget->item( index )->data( Qt::UserRole ).toString();
setEditorWidgetType( editType );
}
void QgsAttributeTypeDialog::defaultExpressionChanged()
{
QString expression = mExpressionWidget->expression();
@ -383,7 +395,8 @@ void QgsAttributeTypeDialog::defaultExpressionChanged()
mDefaultPreviewLabel->setText( "<i>" + previewText + "</i>" );
}
void QgsAttributeTypeDialog::showHelp()
QStandardItem *QgsAttributeTypeDialog::currentItem() const
{
QgsHelp::openHelp( QStringLiteral( "working_with_vector/vector_properties.html#configure-the-field-behavior" ) );
QStandardItemModel *widgetTypeModel = qobject_cast<QStandardItemModel *>( mWidgetTypeComboBox->model() );
return widgetTypeModel->item( mWidgetTypeComboBox->currentIndex() );
}

View File

@ -25,14 +25,15 @@
#include "qgshelp.h"
#include "qgis_app.h"
class QDialog;
class QWidget;
class QStandardItem;
class APP_EXPORT QgsAttributeTypeDialog: public QDialog, private Ui::QgsAttributeTypeDialog, QgsExpressionContextGenerator
class APP_EXPORT QgsAttributeTypeDialog: public QWidget, private Ui::QgsAttributeTypeDialog, QgsExpressionContextGenerator
{
Q_OBJECT
public:
QgsAttributeTypeDialog( QgsVectorLayer *vl, int fieldIdx );
QgsAttributeTypeDialog( QgsVectorLayer *vl, int fieldIdx, QWidget *parent = nullptr );
~QgsAttributeTypeDialog();
/**
@ -62,6 +63,21 @@ class APP_EXPORT QgsAttributeTypeDialog: public QDialog, private Ui::QgsAttribut
*/
bool labelOnTop() const;
/**
* Setter for lable alias
*/
void setAlias( const QString &alias );
/**
* Getter for lable alias
*/
QString alias() const;
/**
* Setter for lable comment
*/
void setComment( const QString &comment );
/**
* Setter for checkbox for editable state of field
*/
@ -164,6 +180,11 @@ class APP_EXPORT QgsAttributeTypeDialog: public QDialog, private Ui::QgsAttribut
*/
void setDefaultValueExpression( const QString &expression );
/**
* Returns the field id
*/
int fieldIdx() const;
QgsExpressionContext createExpressionContext() const override;
bool applyDefaultValueOnUpdate() const;
@ -175,12 +196,10 @@ class APP_EXPORT QgsAttributeTypeDialog: public QDialog, private Ui::QgsAttribut
* Slot to handle change of index in combobox to select correct page
* \param index index of value in combobox
*/
void selectionListWidget_currentRowChanged( int index );
void onCurrentWidgetChanged( int index );
void defaultExpressionChanged();
void showHelp();
private:
QgsVectorLayer *mLayer = nullptr;
int mFieldIdx;
@ -190,6 +209,8 @@ class APP_EXPORT QgsAttributeTypeDialog: public QDialog, private Ui::QgsAttribut
//! Cached configuration dialog (lazy loaded)
QMap< QString, QgsEditorConfigWidget * > mEditorConfigWidgets;
QStandardItem *currentItem() const;
QgsFeature mPreviewFeature;
};

File diff suppressed because it is too large Load Diff

View File

@ -1,307 +0,0 @@
/***************************************************************************
qgsfieldsproperties.h
---------------------
begin : September 2012
copyright : (C) 2012 by Matthias Kuhn
email : matthias at opengis dot ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSFIELDSPROPERTIES_H
#define QGSFIELDSPROPERTIES_H
#include <QMimeData>
#include <QPushButton>
#include <QTableWidget>
#include <QTreeWidget>
#include <QWidget>
#include <QSpinBox>
#include "qgsvectorlayer.h"
#include "ui_qgsfieldspropertiesbase.h"
#include "qgis_app.h"
class DesignerTree;
class DragList;
class APP_EXPORT QgsFieldsProperties : public QWidget, private Ui_QgsFieldsPropertiesBase
{
Q_OBJECT
public:
enum FieldPropertiesRoles
{
DesignerTreeRole = Qt::UserRole,
FieldConfigRole
};
struct RelationEditorConfiguration
{
RelationEditorConfiguration()
{}
bool showLinkButton = true;
bool showUnlinkButton = true;
};
class DesignerTreeItemData
{
public:
enum Type
{
Field,
Relation,
Container
};
DesignerTreeItemData()
{}
DesignerTreeItemData( Type type, const QString &name )
: mType( type )
, mName( name )
{}
QString name() const { return mName; }
void setName( const QString &name ) { mName = name; }
Type type() const { return mType; }
void setType( Type type ) { mType = type; }
QVariant asQVariant() { return QVariant::fromValue<DesignerTreeItemData>( *this ); }
int columnCount() const { return mColumnCount; }
void setColumnCount( int count ) { mColumnCount = count; }
bool showAsGroupBox() const;
void setShowAsGroupBox( bool showAsGroupBox );
bool showLabel() const;
void setShowLabel( bool showLabel );
QgsOptionalExpression visibilityExpression() const;
void setVisibilityExpression( const QgsOptionalExpression &visibilityExpression );
RelationEditorConfiguration relationEditorConfiguration() const;
void setRelationEditorConfiguration( RelationEditorConfiguration relationEditorConfiguration );
private:
Type mType = Field;
QString mName;
int mColumnCount = 1;
bool mShowAsGroupBox = false;
bool mShowLabel = true;
QgsOptionalExpression mVisibilityExpression;
RelationEditorConfiguration mRelationEditorConfiguration;
};
/**
* Holds the configuration for a field
*/
class FieldConfig
{
public:
FieldConfig();
FieldConfig( QgsVectorLayer *layer, int idx );
bool mEditable = true;
bool mEditableEnabled = true;
bool mLabelOnTop = false;
QgsFieldConstraints::Constraints mConstraints;
QHash< QgsFieldConstraints::Constraint, QgsFieldConstraints::ConstraintStrength > mConstraintStrength;
QString mConstraint;
QString mConstraintDescription;
QPushButton *mButton = nullptr;
QString mEditorWidgetType;
QMap<QString, QVariant> mEditorWidgetConfig;
};
public:
QgsFieldsProperties( QgsVectorLayer *layer, QWidget *parent = nullptr );
~QgsFieldsProperties();
/**
* Adds an attribute to the table (but does not commit it yet)
\param field the field to add
\returns false in case of a name conflict, true in case of success */
bool addAttribute( const QgsField &field );
/**
* Creates the a proper item to save from the tree
* \returns A widget definition. Containing another container or the final field
*/
QgsAttributeEditorElement *createAttributeEditorWidget( QTreeWidgetItem *item, QgsAttributeEditorElement *parent, bool forceGroup = true );
void init();
void apply();
void loadRows();
void setRow( int row, int idx, const QgsField &field );
void loadRelations();
void loadAttributeEditorTree();
QTreeWidgetItem *loadAttributeEditorTreeItem( QgsAttributeEditorElement *const widgetDef, QTreeWidgetItem *parent );
/**
* \brief setEditFormInit set the private ui fields
* \param editForm
* \param initFunction
* \param initCode
* \param initFilePath
* \param codeSource
*/
void setEditFormInit( const QString &editForm,
const QString &initFunction,
const QString &initCode,
const QString &initFilePath,
QgsEditFormConfig::PythonInitCodeSource codeSource );
signals:
void toggleEditing();
private slots:
void mAddAttributeButton_clicked();
void mDeleteAttributeButton_clicked();
void mCalculateFieldButton_clicked();
void onAttributeSelectionChanged();
void pbtnSelectInitFilePath_clicked();
void pbnSelectEditForm_clicked();
void mEditorLayoutComboBox_currentIndexChanged( int index );
void mInitCodeSourceComboBox_currentIndexChanged( int codeSource );
void attributeAdded( int idx );
void attributeDeleted( int idx );
void attributeTypeDialog();
void mAddTabOrGroupButton_clicked();
void mAddItemButton_clicked();
void mRemoveTabGroupItemButton_clicked();
void mMoveDownItem_clicked();
void mMoveUpItem_clicked();
void attributesListCellChanged( int row, int column );
void updateExpression();
//! Editing of layer was toggled
void editingToggled();
protected:
void updateButtons();
FieldConfig configForRow( int row );
void setConfigForRow( int row, const FieldConfig &cfg );
QList<QgsRelation> mRelations;
QgsVectorLayer *mLayer = nullptr;
DesignerTree *mDesignerTree = nullptr;
DragList *mFieldsList = nullptr;
DragList *mRelationsList = nullptr;
// Holds all the first column items (header: id) of the table.
// The index in the list is the fieldIdx, and therefore acts as a mapping
// between fieldIdx and QTableWidgetItem->row()
QList<QTableWidgetItem *> mIndexedWidgets;
enum AttrColumns
{
AttrIdCol = 0,
AttrNameCol,
AttrEditTypeCol,
AttrAliasCol,
AttrTypeCol,
AttrTypeNameCol,
AttrLengthCol,
AttrPrecCol,
AttrCommentCol,
AttrWMSCol,
AttrWFSCol,
AttrColCount,
};
enum RelationColumns
{
RelNameCol = 0,
RelLayerCol,
RelFieldCol,
RelIdCol,
RelNmCol,
RelColCount
};
private:
void updateFieldRenamingStatus();
};
QDataStream &operator<< ( QDataStream &stream, const QgsFieldsProperties::DesignerTreeItemData &data );
QDataStream &operator>> ( QDataStream &stream, QgsFieldsProperties::DesignerTreeItemData &data );
/**
* This class overrides mime type handling to be able to work with
* the drag and drop attribute editor.
*
* The mime type is application/x-qgsattributetablefield
*/
class DragList : public QTableWidget
{
Q_OBJECT
public:
explicit DragList( QWidget *parent = nullptr )
: QTableWidget( parent )
{}
// QTreeWidget interface
protected:
virtual QStringList mimeTypes() const override;
virtual QMimeData *mimeData( const QList<QTableWidgetItem *> items ) const override;
};
/**
* Graphical representation for the attribute editor drag and drop editor
*/
class DesignerTree : public QTreeWidget
{
Q_OBJECT
public:
explicit DesignerTree( QgsVectorLayer *layer, QWidget *parent = nullptr );
QTreeWidgetItem *addItem( QTreeWidgetItem *parent, QgsFieldsProperties::DesignerTreeItemData data );
QTreeWidgetItem *addContainer( QTreeWidgetItem *parent, const QString &title, int columnCount );
protected:
virtual void dragMoveEvent( QDragMoveEvent *event ) override;
virtual void dropEvent( QDropEvent *event ) override;
virtual bool dropMimeData( QTreeWidgetItem *parent, int index, const QMimeData *data, Qt::DropAction action ) override;
/* Qt::DropActions supportedDropActions() const;*/
// QTreeWidget interface
protected:
virtual QStringList mimeTypes() const override;
virtual QMimeData *mimeData( const QList<QTreeWidgetItem *> items ) const override;
private slots:
void onItemDoubleClicked( QTreeWidgetItem *item, int column );
private:
QgsVectorLayer *mLayer = nullptr;
};
Q_DECLARE_METATYPE( QgsFieldsProperties::FieldConfig )
Q_DECLARE_METATYPE( QgsFieldsProperties::DesignerTreeItemData )
#endif // QGSFIELDSPROPERTIES_H

View File

@ -0,0 +1,432 @@
/***************************************************************************
qgssourcefieldsproperties.cpp
---------------------
begin : July 2017
copyright : (C) 2017 by David Signer
email : david at opengis dot ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgssourcefieldsproperties.h"
QgsSourceFieldsProperties::QgsSourceFieldsProperties( QgsVectorLayer *layer, QWidget *parent )
: QWidget( parent )
, mLayer( layer )
{
if ( !layer )
return;
setupUi( this );
//button appearance
mAddAttributeButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionNewAttribute.svg" ) ) );
mDeleteAttributeButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionDeleteAttribute.svg" ) ) );
mToggleEditingButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionToggleEditing.svg" ) ) );
mCalculateFieldButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionCalculateField.svg" ) ) );
//button signals
connect( mToggleEditingButton, &QAbstractButton::clicked, this, &QgsSourceFieldsProperties::toggleEditing );
connect( mAddAttributeButton, &QAbstractButton::clicked, this, &QgsSourceFieldsProperties::addAttributeClicked );
connect( mDeleteAttributeButton, &QAbstractButton::clicked, this, &QgsSourceFieldsProperties::deleteAttributeClicked );
connect( mCalculateFieldButton, &QAbstractButton::clicked, this, &QgsSourceFieldsProperties::calculateFieldClicked );
//slots
connect( mLayer, &QgsVectorLayer::editingStarted, this, &QgsSourceFieldsProperties::editingToggled );
connect( mLayer, &QgsVectorLayer::editingStopped, this, &QgsSourceFieldsProperties::editingToggled );
connect( mLayer, &QgsVectorLayer::attributeAdded, this, &QgsSourceFieldsProperties::attributeAdded );
connect( mLayer, &QgsVectorLayer::attributeDeleted, this, &QgsSourceFieldsProperties::attributeDeleted );
//field list appearance
mFieldsList->setColumnCount( AttrColCount );
mFieldsList->setSelectionBehavior( QAbstractItemView::SelectRows );
mFieldsList->setDragDropMode( QAbstractItemView::DragOnly );
mFieldsList->setHorizontalHeaderItem( AttrIdCol, new QTableWidgetItem( tr( "Id" ) ) );
mFieldsList->setHorizontalHeaderItem( AttrNameCol, new QTableWidgetItem( tr( "Name" ) ) );
mFieldsList->setHorizontalHeaderItem( AttrTypeCol, new QTableWidgetItem( tr( "Type" ) ) );
mFieldsList->setHorizontalHeaderItem( AttrTypeNameCol, new QTableWidgetItem( tr( "Type name" ) ) );
mFieldsList->setHorizontalHeaderItem( AttrLengthCol, new QTableWidgetItem( tr( "Length" ) ) );
mFieldsList->setHorizontalHeaderItem( AttrPrecCol, new QTableWidgetItem( tr( "Precision" ) ) );
mFieldsList->setHorizontalHeaderItem( AttrCommentCol, new QTableWidgetItem( tr( "Comment" ) ) );
mFieldsList->setHorizontalHeaderItem( AttrWMSCol, new QTableWidgetItem( QStringLiteral( "WMS" ) ) );
mFieldsList->setHorizontalHeaderItem( AttrWFSCol, new QTableWidgetItem( QStringLiteral( "WFS" ) ) );
mFieldsList->setHorizontalHeaderItem( AttrAliasCol, new QTableWidgetItem( tr( "Alias" ) ) );
mFieldsList->setSortingEnabled( true );
mFieldsList->sortByColumn( 0, Qt::AscendingOrder );
mFieldsList->setSelectionBehavior( QAbstractItemView::SelectRows );
mFieldsList->setSelectionMode( QAbstractItemView::ExtendedSelection );
mFieldsList->verticalHeader()->hide();
//load buttons and field list
updateButtons();
}
QgsSourceFieldsProperties::~QgsSourceFieldsProperties()
{
}
void QgsSourceFieldsProperties::init()
{
loadRows();
}
void QgsSourceFieldsProperties::loadRows()
{
disconnect( mFieldsList, &QTableWidget::cellChanged, this, &QgsSourceFieldsProperties::attributesListCellChanged );
const QgsFields &fields = mLayer->fields();
mIndexedWidgets.clear();
mFieldsList->setRowCount( 0 );
for ( int i = 0; i < fields.count(); ++i )
attributeAdded( i );
mFieldsList->resizeColumnsToContents();
connect( mFieldsList, &QTableWidget::cellChanged, this, &QgsSourceFieldsProperties::attributesListCellChanged );
updateFieldRenamingStatus();
}
void QgsSourceFieldsProperties::updateFieldRenamingStatus()
{
bool canRenameFields = mLayer->isEditable() && ( mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::RenameAttributes ) && !mLayer->readOnly();
for ( int row = 0; row < mFieldsList->rowCount(); ++row )
{
if ( canRenameFields )
mFieldsList->item( row, AttrNameCol )->setFlags( mFieldsList->item( row, AttrNameCol )->flags() | Qt::ItemIsEditable );
else
mFieldsList->item( row, AttrNameCol )->setFlags( mFieldsList->item( row, AttrNameCol )->flags() & ~Qt::ItemIsEditable );
}
}
void QgsSourceFieldsProperties::updateExpression()
{
QToolButton *btn = qobject_cast<QToolButton *>( sender() );
Q_ASSERT( btn );
int index = btn->property( "Index" ).toInt();
const QString exp = mLayer->expressionField( index );
QgsExpressionContext context;
context << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope( QgsProject::instance() );
QgsExpressionBuilderDialog dlg( mLayer, exp, nullptr, QStringLiteral( "generic" ), context );
if ( dlg.exec() )
{
mLayer->updateExpressionField( index, dlg.expressionText() );
loadRows();
}
}
void QgsSourceFieldsProperties::attributeAdded( int idx )
{
bool sorted = mFieldsList->isSortingEnabled();
if ( sorted )
mFieldsList->setSortingEnabled( false );
const QgsFields &fields = mLayer->fields();
int row = mFieldsList->rowCount();
mFieldsList->insertRow( row );
setRow( row, idx, fields.at( idx ) );
mFieldsList->setCurrentCell( row, idx );
//in case there are rows following, there is increased the id to the correct ones
for ( int i = idx + 1; i < mIndexedWidgets.count(); i++ )
mIndexedWidgets.at( i )->setData( Qt::DisplayRole, i );
if ( sorted )
mFieldsList->setSortingEnabled( true );
for ( int i = 0; i < mFieldsList->columnCount(); i++ )
{
switch ( mLayer->fields().fieldOrigin( idx ) )
{
case QgsFields::OriginExpression:
if ( i == 7 ) continue;
mFieldsList->item( row, i )->setBackgroundColor( QColor( 200, 200, 255 ) );
break;
case QgsFields::OriginJoin:
mFieldsList->item( row, i )->setBackgroundColor( QColor( 200, 255, 200 ) );
break;
default:
mFieldsList->item( row, i )->setBackgroundColor( QColor( 255, 255, 200 ) );
break;
}
}
}
void QgsSourceFieldsProperties::attributeDeleted( int idx )
{
mFieldsList->removeRow( mIndexedWidgets.at( idx )->row() );
mIndexedWidgets.removeAt( idx );
for ( int i = idx; i < mIndexedWidgets.count(); i++ )
{
mIndexedWidgets.at( i )->setData( Qt::DisplayRole, i );
}
}
void QgsSourceFieldsProperties::setRow( int row, int idx, const QgsField &field )
{
QTableWidgetItem *dataItem = new QTableWidgetItem();
dataItem->setData( Qt::DisplayRole, idx );
switch ( mLayer->fields().fieldOrigin( idx ) )
{
case QgsFields::OriginExpression:
dataItem->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mIconExpression.svg" ) ) );
break;
case QgsFields::OriginJoin:
dataItem->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/propertyicons/join.png" ) ) );
break;
default:
dataItem->setIcon( mLayer->fields().iconForField( idx ) );
break;
}
mFieldsList->setItem( row, AttrIdCol, dataItem );
mIndexedWidgets.insert( idx, mFieldsList->item( row, 0 ) );
mFieldsList->setItem( row, AttrNameCol, new QTableWidgetItem( field.name() ) );
mFieldsList->setItem( row, AttrAliasCol, new QTableWidgetItem( field.alias() ) );
mFieldsList->setItem( row, AttrTypeCol, new QTableWidgetItem( QVariant::typeToName( field.type() ) ) );
mFieldsList->setItem( row, AttrTypeNameCol, new QTableWidgetItem( field.typeName() ) );
mFieldsList->setItem( row, AttrLengthCol, new QTableWidgetItem( QString::number( field.length() ) ) );
mFieldsList->setItem( row, AttrPrecCol, new QTableWidgetItem( QString::number( field.precision() ) ) );
if ( mLayer->fields().fieldOrigin( idx ) == QgsFields::OriginExpression )
{
QWidget *expressionWidget = new QWidget;
expressionWidget->setLayout( new QHBoxLayout );
QToolButton *editExpressionButton = new QToolButton;
editExpressionButton->setProperty( "Index", idx );
editExpressionButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mIconExpression.svg" ) ) );
connect( editExpressionButton, &QAbstractButton::clicked, this, &QgsSourceFieldsProperties::updateExpression );
expressionWidget->layout()->setContentsMargins( 0, 0, 0, 0 );
expressionWidget->layout()->addWidget( editExpressionButton );
expressionWidget->layout()->addWidget( new QLabel( mLayer->expressionField( idx ) ) );
expressionWidget->setStyleSheet( "background-color: rgb( 200, 200, 255 )" );
mFieldsList->setCellWidget( row, AttrCommentCol, expressionWidget );
}
else
{
mFieldsList->setItem( row, AttrCommentCol, new QTableWidgetItem( field.comment() ) );
}
QList<int> notEditableCols = QList<int>()
<< AttrIdCol
<< AttrNameCol
<< AttrAliasCol
<< AttrTypeCol
<< AttrTypeNameCol
<< AttrLengthCol
<< AttrPrecCol
<< AttrCommentCol;
Q_FOREACH ( int i, notEditableCols )
{
if ( notEditableCols[i] != AttrCommentCol || mLayer->fields().fieldOrigin( idx ) != QgsFields::OriginExpression )
mFieldsList->item( row, i )->setFlags( mFieldsList->item( row, i )->flags() & ~Qt::ItemIsEditable );
if ( notEditableCols[i] == AttrAliasCol )
mFieldsList->item( row, i )->setToolTip( tr( "Edit alias in the Form config tab" ) );
}
bool canRenameFields = mLayer->isEditable() && ( mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::RenameAttributes ) && !mLayer->readOnly();
if ( canRenameFields )
mFieldsList->item( row, AttrNameCol )->setFlags( mFieldsList->item( row, AttrNameCol )->flags() | Qt::ItemIsEditable );
else
mFieldsList->item( row, AttrNameCol )->setFlags( mFieldsList->item( row, AttrNameCol )->flags() & ~Qt::ItemIsEditable );
//published WMS/WFS attributes
QTableWidgetItem *wmsAttrItem = new QTableWidgetItem();
wmsAttrItem->setCheckState( mLayer->excludeAttributesWms().contains( field.name() ) ? Qt::Unchecked : Qt::Checked );
wmsAttrItem->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable );
mFieldsList->setItem( row, AttrWMSCol, wmsAttrItem );
QTableWidgetItem *wfsAttrItem = new QTableWidgetItem();
wfsAttrItem->setCheckState( mLayer->excludeAttributesWfs().contains( field.name() ) ? Qt::Unchecked : Qt::Checked );
wfsAttrItem->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable );
mFieldsList->setItem( row, AttrWFSCol, wfsAttrItem );
}
bool QgsSourceFieldsProperties::addAttribute( const QgsField &field )
{
QgsDebugMsg( "inserting attribute " + field.name() + " of type " + field.typeName() );
mLayer->beginEditCommand( tr( "Added attribute" ) );
if ( mLayer->addAttribute( field ) )
{
mLayer->endEditCommand();
return true;
}
else
{
mLayer->destroyEditCommand();
QMessageBox::critical( this, tr( "Failed to add field" ), tr( "Failed to add field '%1' of type '%2'. Is the field name unique?" ).arg( field.name(), field.typeName() ) );
return false;
}
}
void QgsSourceFieldsProperties::apply()
{
QSet<QString> excludeAttributesWMS, excludeAttributesWFS;
for ( int i = 0; i < mFieldsList->rowCount(); i++ )
{
if ( mFieldsList->item( i, AttrWMSCol )->checkState() == Qt::Unchecked )
{
excludeAttributesWMS.insert( mFieldsList->item( i, AttrNameCol )->text() );
}
if ( mFieldsList->item( i, AttrWFSCol )->checkState() == Qt::Unchecked )
{
excludeAttributesWFS.insert( mFieldsList->item( i, AttrNameCol )->text() );
}
}
mLayer->setExcludeAttributesWms( excludeAttributesWMS );
mLayer->setExcludeAttributesWfs( excludeAttributesWFS );
}
//SLOTS
void QgsSourceFieldsProperties::editingToggled()
{
updateButtons();
updateFieldRenamingStatus();
}
void QgsSourceFieldsProperties::addAttributeClicked()
{
QgsAddAttrDialog dialog( mLayer, this );
if ( dialog.exec() == QDialog::Accepted )
{
addAttribute( dialog.field() );
loadRows();
}
}
void QgsSourceFieldsProperties::deleteAttributeClicked()
{
QSet<int> providerFields;
QSet<int> expressionFields;
Q_FOREACH ( QTableWidgetItem *item, mFieldsList->selectedItems() )
{
if ( item->column() == 0 )
{
int idx = mIndexedWidgets.indexOf( item );
if ( idx < 0 )
continue;
if ( mLayer->fields().fieldOrigin( idx ) == QgsFields::OriginExpression )
expressionFields << idx;
else
providerFields << idx;
}
}
if ( !expressionFields.isEmpty() )
mLayer->deleteAttributes( expressionFields.toList() );
if ( !providerFields.isEmpty() )
{
mLayer->beginEditCommand( tr( "Deleted attributes" ) );
if ( mLayer->deleteAttributes( providerFields.toList() ) )
mLayer->endEditCommand();
else
mLayer->destroyEditCommand();
}
}
void QgsSourceFieldsProperties::calculateFieldClicked()
{
if ( !mLayer )
{
return;
}
QgsFieldCalculator calc( mLayer, this );
if ( calc.exec() == QDialog::Accepted )
{
loadRows();
}
}
void QgsSourceFieldsProperties::attributesListCellChanged( int row, int column )
{
if ( column == AttrNameCol && mLayer && mLayer->isEditable() )
{
int idx = mIndexedWidgets.indexOf( mFieldsList->item( row, AttrIdCol ) );
QTableWidgetItem *nameItem = mFieldsList->item( row, column );
//avoiding that something will be changed, just because this is triggered by simple re-sorting
if ( !nameItem ||
nameItem->text().isEmpty() ||
!mLayer->fields().exists( idx ) ||
mLayer->fields().at( idx ).name() == nameItem->text()
)
return;
mLayer->beginEditCommand( tr( "Rename attribute" ) );
if ( mLayer->renameAttribute( idx, nameItem->text() ) )
{
mLayer->endEditCommand();
}
else
{
mLayer->destroyEditCommand();
QMessageBox::critical( this, tr( "Failed to rename field" ), tr( "Failed to rename field to '%1'. Is the field name unique?" ).arg( nameItem->text() ) );
}
}
}
//NICE FUNCTIONS
void QgsSourceFieldsProperties::updateButtons()
{
int cap = mLayer->dataProvider()->capabilities();
mToggleEditingButton->setEnabled( ( cap & QgsVectorDataProvider::ChangeAttributeValues ) && !mLayer->readOnly() );
if ( mLayer->isEditable() )
{
mDeleteAttributeButton->setEnabled( cap & QgsVectorDataProvider::DeleteAttributes );
mAddAttributeButton->setEnabled( cap & QgsVectorDataProvider::AddAttributes );
mToggleEditingButton->setChecked( true );
}
else
{
mToggleEditingButton->setChecked( false );
mAddAttributeButton->setEnabled( false );
// Enable delete button if items are selected
mDeleteAttributeButton->setEnabled( !mFieldsList->selectedItems().isEmpty() );
// and only if all selected items have their origin in an expression
Q_FOREACH ( QTableWidgetItem *item, mFieldsList->selectedItems() )
{
if ( item->column() == 0 )
{
int idx = mIndexedWidgets.indexOf( item );
if ( mLayer->fields().fieldOrigin( idx ) != QgsFields::OriginExpression )
{
mDeleteAttributeButton->setEnabled( false );
break;
}
}
}
}
}

View File

@ -0,0 +1,112 @@
/***************************************************************************
qgssourcefieldsproperties.h
---------------------
begin : July 2017
copyright : (C) 2017 by David Signer
email : david at opengis dot ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSSOURCEFIELDSPROPERTIES_H
#define QGSSOURCEFIELDSPROPERTIES_H
#include <QMimeData>
#include <QPushButton>
#include <QTableWidget>
#include <QTreeWidget>
#include <QWidget>
#include <QSpinBox>
#include <QTreeWidgetItem>
#include <QDropEvent>
#include <QTableWidgetItem>
#include <QMessageBox>
#include <QFileDialog>
#include <QHBoxLayout>
#include <QFormLayout>
#include "qgsvectorlayer.h"
#include "ui_qgssourcefieldsproperties.h"
#include "qgis_app.h"
#include "qgsaddattrdialog.h"
#include "qgslogger.h"
#include "qgsproject.h"
#include "qgsexpressionbuilderdialog.h"
#include "qgsfieldcalculator.h"
class APP_EXPORT QgsSourceFieldsProperties : public QWidget, private Ui_QgsSourceFieldsProperties
{
Q_OBJECT
public:
explicit QgsSourceFieldsProperties( QgsVectorLayer *layer, QWidget *parent = nullptr );
~QgsSourceFieldsProperties();
void init();
void apply();
void loadRows();
void setRow( int row, int idx, const QgsField &field );
/**
* Adds an attribute to the table (but does not commit it yet)
\param field the field to add
\returns false in case of a name conflict, true in case of success */
bool addAttribute( const QgsField &field );
protected:
void updateButtons();
QgsVectorLayer *mLayer = nullptr;
// Holds all the first column items (header: id) of the table.
// The index in the list is the fieldIdx, and therefore acts as a mapping
// between fieldIdx and QTableWidgetItem->row()
QList<QTableWidgetItem *> mIndexedWidgets;
enum AttrColumns
{
AttrIdCol = 0,
AttrNameCol,
AttrAliasCol,
AttrTypeCol,
AttrTypeNameCol,
AttrLengthCol,
AttrPrecCol,
AttrCommentCol,
AttrWMSCol,
AttrWFSCol,
AttrColCount,
};
private:
Ui::QgsSourceFieldsProperties *ui;
void updateFieldRenamingStatus();
signals:
void toggleEditing();
private slots:
void updateExpression();
//! Editing of layer was toggled
void editingToggled();
void addAttributeClicked();
void deleteAttributeClicked();
void calculateFieldClicked();
void attributeAdded( int idx );
void attributeDeleted( int idx );
void attributesListCellChanged( int row, int column );
};
#endif // QGSSOURCEFIELDSPROPERTIES_H

View File

@ -30,7 +30,8 @@
#include "qgsdiagramrenderer.h"
#include "qgsexpressionbuilderdialog.h"
#include "qgsfieldcalculator.h"
#include "qgsfieldsproperties.h"
#include "qgssourcefieldsproperties.h"
#include "qgsattributesformproperties.h"
#include "qgslabelingwidget.h"
#include "qgsprojectionselectiondialog.h"
#include "qgslogger.h"
@ -196,16 +197,22 @@ QgsVectorLayerProperties::QgsVectorLayerProperties(
connect( mSaveAsMenu, &QMenu::triggered,
this, &QgsVectorLayerProperties::saveStyleAsMenuTriggered );
mFieldsPropertiesDialog = new QgsFieldsProperties( mLayer, mFieldsFrame );
mFieldsPropertiesDialog->layout()->setMargin( 0 );
mFieldsFrame->setLayout( new QVBoxLayout( mFieldsFrame ) );
mFieldsFrame->layout()->setMargin( 0 );
mFieldsFrame->layout()->addWidget( mFieldsPropertiesDialog );
mSourceFieldsPropertiesDialog = new QgsSourceFieldsProperties( mLayer, mSourceFieldsFrame );
mSourceFieldsPropertiesDialog->layout()->setMargin( 0 );
mSourceFieldsFrame->setLayout( new QVBoxLayout( mSourceFieldsFrame ) );
mSourceFieldsFrame->layout()->setMargin( 0 );
mSourceFieldsFrame->layout()->addWidget( mSourceFieldsPropertiesDialog );
connect( mFieldsPropertiesDialog, &QgsFieldsProperties::toggleEditing, this, static_cast<void ( QgsVectorLayerProperties::* )()>( &QgsVectorLayerProperties::toggleEditing ) );
connect( mSourceFieldsPropertiesDialog, &QgsSourceFieldsProperties::toggleEditing, this, static_cast<void ( QgsVectorLayerProperties::* )()>( &QgsVectorLayerProperties::toggleEditing ) );
connect( this, static_cast<void ( QgsVectorLayerProperties::* )( QgsMapLayer * )>( &QgsVectorLayerProperties::toggleEditing ),
QgisApp::instance(), [ = ]( QgsMapLayer * layer ) { QgisApp::instance()->toggleEditing( layer ); } );
mAttributesFormPropertiesDialog = new QgsAttributesFormProperties( mLayer, mAttributesFormFrame );
mAttributesFormPropertiesDialog->layout()->setMargin( 0 );
mAttributesFormFrame->setLayout( new QVBoxLayout( mAttributesFormFrame ) );
mAttributesFormFrame->layout()->setMargin( 0 );
mAttributesFormFrame->layout()->addWidget( mAttributesFormPropertiesDialog );
syncToLayer();
if ( mLayer->dataProvider() )//enable spatial index button group if supported by provider
@ -514,18 +521,14 @@ void QgsVectorLayerProperties::syncToLayer()
if ( labelingDialog )
labelingDialog->adaptToLayer();
mFieldsPropertiesDialog->init();
mSourceFieldsPropertiesDialog->init();
mAttributesFormPropertiesDialog->init();
// set initial state for variable editor
updateVariableEditor();
// updates the init python code and ui
updateFieldsPropertiesDialog();
} // syncToLayer()
void QgsVectorLayerProperties::apply()
{
if ( labelingDialog )
@ -594,8 +597,8 @@ void QgsVectorLayerProperties::apply()
mLayer->setName( mLayerOrigNameLineEdit->text() );
// Apply fields settings
mFieldsPropertiesDialog->apply();
mAttributesFormPropertiesDialog->apply();
mSourceFieldsPropertiesDialog->apply();
if ( mLayer->renderer() )
{
@ -1190,7 +1193,8 @@ void QgsVectorLayerProperties::mButtonAddJoin_clicked()
mLayer->addJoin( info );
addJoinToTreeWidget( info );
setPbnQueryBuilderEnabled();
mFieldsPropertiesDialog->init();
mSourceFieldsPropertiesDialog->init();
mAttributesFormPropertiesDialog->init();
}
}
@ -1259,7 +1263,8 @@ void QgsVectorLayerProperties::mJoinTreeWidget_itemDoubleClicked( QTreeWidgetIte
addJoinToTreeWidget( info, idx );
setPbnQueryBuilderEnabled();
mFieldsPropertiesDialog->init();
mSourceFieldsPropertiesDialog->init();
mAttributesFormPropertiesDialog->init();
}
}
@ -1386,7 +1391,8 @@ void QgsVectorLayerProperties::mButtonRemoveJoin_clicked()
mLayer->removeJoin( currentJoinItem->data( 0, Qt::UserRole ).toString() );
mJoinTreeWidget->takeTopLevelItem( mJoinTreeWidget->indexOfTopLevelItem( currentJoinItem ) );
setPbnQueryBuilderEnabled();
mFieldsPropertiesDialog->init();
mSourceFieldsPropertiesDialog->init();
mAttributesFormPropertiesDialog->init();
}
@ -1481,15 +1487,16 @@ void QgsVectorLayerProperties::updateVariableEditor()
mVariableEditor->setEditableScopeIndex( 2 );
}
void QgsVectorLayerProperties::updateFieldsPropertiesDialog()
{
QgsEditFormConfig cfg = mLayer->editFormConfig();
mFieldsPropertiesDialog->setEditFormInit( cfg.uiForm(), cfg.initFunction(), cfg.initCode(), cfg.initFilePath(), cfg.initCodeSource() );
}
void QgsVectorLayerProperties::showHelp()
{
QgsHelp::openHelp( QStringLiteral( "working_with_vector/vector_properties.html" ) );
if ( mOptionsListWidget->currentIndex().data().toString() == "Form" )
{
QgsHelp::openHelp( QStringLiteral( "working_with_vector/vector_properties.html#configure-the-field-behavior" ) );
}
else
{
QgsHelp::openHelp( QStringLiteral( "working_with_vector/vector_properties.html" ) );
}
}
void QgsVectorLayerProperties::updateAuxiliaryStoragePage( bool reset )
@ -1710,6 +1717,6 @@ void QgsVectorLayerProperties::deleteAuxiliaryField( int index )
}
updateAuxiliaryStoragePage( true );
mFieldsPropertiesDialog->init();
mSourceFieldsPropertiesDialog->init();
}
}

View File

@ -38,7 +38,8 @@ class QgsApplyDialog;
class QgsVectorLayer;
class QgsLabelingWidget;
class QgsDiagramProperties;
class QgsFieldsProperties;
class QgsSourceFieldsProperties;
class QgsAttributesFormProperties;
class QgsRendererPropertiesDialog;
class QgsMapLayerConfigWidgetFactory;
class QgsMapLayerConfigWidget;
@ -151,11 +152,6 @@ class APP_EXPORT QgsVectorLayerProperties : public QgsOptionsDialogBase, private
*/
void updateVariableEditor();
/**
* \brief updates the FieldsPropertiesDialog when syncing the layer properties
*/
void updateFieldsPropertiesDialog();
void onAuxiliaryLayerNew();
void onAuxiliaryLayerClear();
@ -199,8 +195,10 @@ class APP_EXPORT QgsVectorLayerProperties : public QgsOptionsDialogBase, private
QgsAttributeActionDialog *mActionDialog = nullptr;
//! Diagram dialog. If apply is pressed, options are applied to vector's diagrams
QgsDiagramProperties *diagramPropertiesDialog = nullptr;
//! Fields dialog. If apply is pressed, options are applied to vector's diagrams
QgsFieldsProperties *mFieldsPropertiesDialog = nullptr;
//! SourceFields dialog. If apply is pressed, options are applied to vector's diagrams
QgsSourceFieldsProperties *mSourceFieldsPropertiesDialog = nullptr;
//! AttributesForm dialog. If apply is pressed, options are applied to vector's diagrams
QgsAttributesFormProperties *mAttributesFormPropertiesDialog = nullptr;
//! List of joins of a layer at the time of creation of the dialog. Used to return joins to previous state if dialog is canceled
QList< QgsVectorLayerJoinInfo > mOldJoins;

View File

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QgsAttributeRelationEdit</class>
<widget class="QWidget" name="QgsAttributeRelationEdit">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Relation</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Cardinality</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="coCardinality"/>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,225 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QgsAttributesFormInitCode</class>
<widget class="QDialog" name="QgsAttributesFormInitCode">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Python Init Code Configuration</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<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>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>50</height>
</size>
</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>Function name</string>
</property>
</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>External file</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="mInitFilePathLineEdit"/>
</item>
<item>
<widget class="QToolButton" name="pbtnSelectInitFilePath">
<property name="text">
<string>…</string>
</property>
</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>
<item row="4" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>50</height>
</size>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QgsCodeEditorPython" name="mInitCodeEditorPython" native="true"/>
</item>
<item row="0" column="0">
<widget class="QWidget" name="mInitCodeSourceContainter" native="true">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>50</height>
</size>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_3">
<property name="toolTip">
<string>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:
rom qgis.PyQt.QtWidgets import QWidget
def my_form_open(dialog, layer, feature):
geom = feature.geometry()
control = dialog.findChild(QWidget,&quot;MyLineEdit&quot;)
Reference in function name: my_form_open
</string>
</property>
<property name="text">
<string>Python Init function</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="mInitCodeSourceComboBox">
<property name="toolTip">
<string>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:
rom qgis.PyQt.QtWidgets import QWidget
def my_form_open(dialog, layer, feature):
geom = feature.geometry()
control = dialog.findChild(QWidget,&quot;MyLineEdit&quot;)
Reference in function name: my_form_open
</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="3" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QgsCodeEditorPython</class>
<extends>QWidget</extends>
<header>qgscodeeditorpython.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>QgsAttributesFormInitCode</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>254</x>
<y>293</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>QgsAttributesFormInitCode</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -0,0 +1,202 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QgsAttributesFormProperties</class>
<widget class="QWidget" name="QgsAttributesFormProperties">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>653</width>
<height>556</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QWidget" name="widget_2" native="true">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>50</height>
</size>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QComboBox" name="mEditorLayoutComboBox">
<item>
<property name="text">
<string>Autogenerate</string>
</property>
</item>
<item>
<property name="text">
<string>Drag and drop designer</string>
</property>
</item>
<item>
<property name="text">
<string>Provide ui-file</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QToolButton" name="mTbInitCode">
<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.</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/processingScript.svg</normaloff>:/images/themes/default/processingScript.svg</iconset>
</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>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QWidget" name="mUiFileFrame" native="true">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>50</height>
</size>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Edit UI</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="mEditFormLineEdit"/>
</item>
<item>
<widget class="QToolButton" name="pbnSelectEditForm">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0">
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QWidget" name="widget" native="true">
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="2">
<widget class="QToolButton" name="mAddTabOrGroupButton">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/symbologyAdd.svg</normaloff>:/images/themes/default/symbologyAdd.svg</iconset>
</property>
</widget>
</item>
<item row="0" column="1" rowspan="6">
<widget class="QWidget" name="mFormLayoutWidget" native="true">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QToolButton" name="mRemoveTabOrGroupButton">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/symbologyRemove.svg</normaloff>:/images/themes/default/symbologyRemove.svg</iconset>
</property>
</widget>
</item>
<item row="3" column="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0" rowspan="6">
<widget class="QWidget" name="mAvailableWidgetsWidget" native="true">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QScrollArea" name="scrollArea_2">
<property name="minimumSize">
<size>
<width>600</width>
<height>0</height>
</size>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents_5">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>596</width>
<height>428</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<widget class="QWidget" name="mAttributeTypeFrame" native="true">
<layout class="QGridLayout" name="gridLayout_2"/>
</widget>
</item>
</layout>
</widget>
</widget>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../../images/images.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -1,20 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QgsAttributeTypeDialog</class>
<widget class="QDialog" name="QgsAttributeTypeDialog">
<widget class="QWidget" name="QgsAttributeTypeDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>751</width>
<height>487</height>
<height>620</height>
</rect>
</property>
<property name="windowTitle">
<string>Edit Widget Properties</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="1">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>General</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Alias</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Comment</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLineEdit" name="leAlias">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="laComment">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="isFieldEditableCheckBox">
<property name="text">
<string>Editable</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QCheckBox" name="labelOnTopCheckBox">
<property name="text">
<string>Label on top</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Widget Type</string>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<item row="1" column="1">
<widget class="QStackedWidget" name="stackedWidget"/>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="mWidgetTypeComboBox"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QgsCollapsibleGroupBox" name="groupBox">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
@ -104,28 +176,8 @@
</layout>
</widget>
</item>
<item row="1" column="0">
<item>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<widget class="QCheckBox" name="isFieldEditableCheckBox">
<property name="text">
<string>Editable</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="labelOnTopCheckBox">
<property name="text">
<string>Label on top</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
@ -175,31 +227,6 @@
</item>
</layout>
</item>
<item row="0" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Widget Type</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QListWidget" name="selectionListWidget"/>
</item>
<item>
<widget class="QStackedWidget" name="stackedWidget"/>
</item>
</layout>
</widget>
</item>
<item row="6" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
@ -223,9 +250,6 @@
</customwidget>
</customwidgets>
<tabstops>
<tabstop>selectionListWidget</tabstop>
<tabstop>isFieldEditableCheckBox</tabstop>
<tabstop>labelOnTopCheckBox</tabstop>
<tabstop>mExpressionWidget</tabstop>
<tabstop>groupBox</tabstop>
<tabstop>notNullCheckBox</tabstop>
@ -237,38 +261,5 @@
<tabstop>mCheckBoxEnforceExpression</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>QgsAttributeTypeDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>520</x>
<y>435</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>QgsAttributeTypeDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>588</x>
<y>435</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
<connections/>
</ui>

View File

@ -0,0 +1,116 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QgsSourceFieldsProperties</class>
<widget class="QWidget" name="QgsSourceFieldsProperties">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>384</width>
<height>315</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<widget class="QTableWidget" name="mFieldsList"/>
</item>
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout_3">
<property name="rightMargin">
<number>0</number>
</property>
<item row="0" column="4">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="2">
<widget class="QToolButton" name="mToggleEditingButton">
<property name="toolTip">
<string>Toggle editing mode</string>
</property>
<property name="whatsThis">
<string>Click to toggle table editing</string>
</property>
<property name="text">
<string/>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QToolButton" name="mAddAttributeButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>New field</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<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>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QToolButton" name="mDeleteAttributeButton">
<property name="toolTip">
<string>Delete field</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<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>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QToolButton" name="mCalculateFieldButton">
<property name="toolTip">
<string>Field calculator</string>
</property>
<property name="whatsThis">
<string>Click to toggle table editing</string>
</property>
<property name="text">
<string/>
</property>
<property name="checkable">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -23,8 +23,8 @@
<iconset resource="../../images/images.qrc">
<normaloff>:/images/icons/qgis-icon-16x16.png</normaloff>:/images/icons/qgis-icon-16x16.png</iconset>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QSplitter" name="mOptionsSplitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@ -155,14 +155,26 @@
</item>
<item>
<property name="text">
<string>Fields</string>
<string>Source Fields</string>
</property>
<property name="toolTip">
<string>Fields</string>
<string>Source Fields</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/propertyicons/attributes.png</normaloff>:/images/themes/default/propertyicons/attributes.png</iconset>
<normaloff>:/images/themes/default/mSourceFields.svg</normaloff>:/images/themes/default/mSourceFields.svg</iconset>
</property>
</item>
<item>
<property name="text">
<string>Attributes Form</string>
</property>
<property name="toolTip">
<string>Form</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mActionFormView.svg</normaloff>:/images/themes/default/mActionFormView.svg</iconset>
</property>
</item>
<item>
@ -321,7 +333,7 @@
</sizepolicy>
</property>
<property name="currentIndex">
<number>2</number>
<number>5</number>
</property>
<widget class="QWidget" name="mOptsPage_Information">
<layout class="QVBoxLayout" name="verticalLayout_5">
@ -397,8 +409,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>644</width>
<height>522</height>
<width>662</width>
<height>534</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_9">
@ -415,11 +427,11 @@
<number>0</number>
</property>
<item>
<widget class="QgsCollapsibleGroupBox" name="groupBox_6">
<widget class="QgsCollapsibleGroupBox" name="groupBox_60">
<property name="title">
<string>Settings</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_26">
<layout class="QVBoxLayout" name="verticalLayout_260">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_13">
<item>
@ -686,8 +698,8 @@ border-radius: 2px;</string>
<rect>
<x>0</x>
<y>0</y>
<width>644</width>
<height>522</height>
<width>662</width>
<height>534</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_18">
@ -760,62 +772,30 @@ border-radius: 2px;</string>
</item>
</layout>
</widget>
<widget class="QWidget" name="mOptsPage_Fields">
<layout class="QVBoxLayout" name="verticalLayout_15">
<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>
<widget class="QWidget" name="mOptsPage_SourceFields">
<layout class="QVBoxLayout" name="verticalLayout_29">
<item>
<widget class="QgsScrollArea" name="scrollArea_5">
<widget class="QFrame" name="mSourceFieldsFrame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
<enum>QFrame::StyledPanel</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="mOptsPage_AttributesForm">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QFrame" name="mAttributesFormFrame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents_5">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>644</width>
<height>522</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_20">
<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="QFrame" name="mFieldsFrame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
@ -847,8 +827,8 @@ border-radius: 2px;</string>
<rect>
<x>0</x>
<y>0</y>
<width>673</width>
<height>507</height>
<width>725</width>
<height>394</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_32">
@ -1271,8 +1251,8 @@ border-radius: 2px;</string>
<rect>
<x>0</x>
<y>0</y>
<width>100</width>
<height>30</height>
<width>662</width>
<height>534</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_21">
@ -1337,8 +1317,8 @@ border-radius: 2px;</string>
<rect>
<x>0</x>
<y>0</y>
<width>199</width>
<height>123</height>
<width>662</width>
<height>534</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_23">
@ -1526,7 +1506,7 @@ border-radius: 2px;</string>
</layout>
</widget>
<widget class="QWidget" name="mOptsPage_DataDependencies">
<layout class="QVBoxLayout" name="verticalLayout_29">
<layout class="QVBoxLayout" name="verticalLayout_30">
<property name="leftMargin">
<number>0</number>
</property>
@ -1617,8 +1597,8 @@ border-radius: 2px;</string>
<rect>
<x>0</x>
<y>0</y>
<width>359</width>
<height>527</height>
<width>648</width>
<height>608</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_13">
@ -2026,7 +2006,7 @@ border-radius: 2px;</string>
<property name="checkable">
<bool>false</bool>
</property>
<property name="syncGroup">
<property name="syncGroup" stdset="0">
<string notr="true">vectormeta</string>
</property>
<layout class="QGridLayout" name="gridLayout_11">
@ -2241,7 +2221,7 @@ border-radius: 2px;</string>
</widget>
</widget>
</item>
<item>
<item row="1" column="0">
<widget class="QFrame" name="mButtonBoxFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
@ -2296,6 +2276,18 @@ border-radius: 2px;</string>
<header>qgsfieldexpressionwidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsScrollArea</class>
<extends>QScrollArea</extends>
<header>qgsscrollarea.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsLayerTreeView</class>
<extends>QTreeView</extends>
<header>qgslayertreeview.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsFilterLineEdit</class>
<extends>QLineEdit</extends>
@ -2312,24 +2304,12 @@ border-radius: 2px;</string>
<extends>QWidget</extends>
<header>qgsscalerangewidget.h</header>
</customwidget>
<customwidget>
<class>QgsScrollArea</class>
<extends>QScrollArea</extends>
<header>qgsscrollarea.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsLayerTreeEmbeddedConfigWidget</class>
<extends>QWidget</extends>
<header>qgslayertreeembeddedconfigwidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsLayerTreeView</class>
<extends>QTreeView</extends>
<header>qgslayertreeview.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsVariableEditorWidget</class>
<extends>QWidget</extends>
@ -2374,7 +2354,6 @@ border-radius: 2px;</string>
<tabstop>txtSubsetSQL</tabstop>
<tabstop>pbnQueryBuilder</tabstop>
<tabstop>scrollArea_3</tabstop>
<tabstop>scrollArea_5</tabstop>
<tabstop>scrollArea_19</tabstop>
<tabstop>mScaleVisibilityGroupBox</tabstop>
<tabstop>mScaleRangeWidget</tabstop>