892 changes: 892 additions & 0 deletions src/app/qgsfieldsproperties.cpp

Large diffs are not rendered by default.

158 changes: 158 additions & 0 deletions src/app/qgsfieldsproperties.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
/***************************************************************************
qgsfieldsproperties.h
---------------------
begin : September 2012
copyright : (C) 2012 by Matthias Kuhn
email : matthias dot kuhn at gmx 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 <QWidget>
#include <QPushButton>
#include <QTreeWidget>
#include <QTableWidget>

#include "qgsvectorlayer.h"
#include "ui_qgsfieldspropertiesbase.h"

class QgsAttributesList : public QTableWidget
{
Q_OBJECT
public:
QgsAttributesList( QWidget* parent = 0 )
: QTableWidget( parent )
{}

protected:
// virtual void dragMoveEvent( QDragMoveEvent *event );
//QMimeData *mimeData( const QList<QTableWidgetItem *> items ) const;
//Qt::DropActions supportedDropActions() const;
};

class QgsAttributesTree : public QTreeWidget
{
Q_OBJECT
public:
QgsAttributesTree( QWidget* parent = 0 )
: QTreeWidget( parent )
{}
QTreeWidgetItem* addContainer( QTreeWidgetItem* parent , QString title );
QTreeWidgetItem* addItem( QTreeWidgetItem* parent , QString fieldName );

protected:
virtual void dragMoveEvent( QDragMoveEvent *event );
virtual void dropEvent( QDropEvent *event );
virtual bool dropMimeData( QTreeWidgetItem * parent, int index, const QMimeData * data, Qt::DropAction action );
/* Qt::DropActions supportedDropActions() const;*/
};


class QgsFieldsProperties : public QWidget, private Ui_QgsFieldsPropertiesBase
{
Q_OBJECT

public:
QgsFieldsProperties( QgsVectorLayer *layer, QWidget* parent = 0 );

/**Adds an attribute to the table (but does not commit it yet)
@param field the field to add
@return false in case of a name conflict, true in case of success */
bool addAttribute( const QgsField &field );

/**Deletes an attribute (but does not commit it)
@param name attribute name
@return false in case of a non-existing attribute.*/
bool deleteAttribute( int attr );

/**Creates the a proper item to save from the tree
* @param item The tree widget item to process
* @return A widget definition. Containing another container or the final field
*/
QgsAttributeEditorElement* createAttributeEditorWidget( QTreeWidgetItem* item, QObject *parent );

void init();
void apply();

void updateButtons();
void loadRows();
void setRow( int row, int idx, const QgsField &field );

void loadAttributeEditorTree();
QTreeWidgetItem *loadAttributeEditorTreeItem( QgsAttributeEditorElement* const widgetDef, QTreeWidgetItem* parent );

signals:
void toggleEditing( QgsMapLayer * );

public slots:
void on_mAddAttributeButton_clicked();
void on_mDeleteAttributeButton_clicked();
void on_mCalculateFieldButton_clicked();
void on_attributeSelectionChanged();
void on_mAttributesList_cellChanged( int row, int column );
void on_pbnSelectEditForm_clicked();
void on_mEditorLayoutComboBox_currentIndexChanged ( int index );
void addAttribute();
void deleteAttribute();

void attributeAdded( int idx );
void attributeDeleted( int idx );
void attributeTypeDialog();

void on_mAddTabOrGroupButton_clicked();
void on_mAddItemButton_clicked();
void on_mRemoveTabGroupItemButton_clicked();
void on_mMoveDownItem_clicked();
void on_mMoveUpItem_clicked();



protected:
QgsVectorLayer* mLayer;
QgsAttributesTree* mAttributesTree;
QgsAttributesList* mAttributesList;

/** toggle editing of layer */
void toggleEditing();

/** editing of layer was toggled */
void editingToggled();

QMap<int, QgsVectorLayer::ValueRelationData> mValueRelationData;
QMap<int, QMap<QString, QVariant> > mValueMaps;
QMap<int, QgsVectorLayer::RangeData> mRanges;
QMap<int, QPair<QString, QString> > mCheckedStates;
QMap<int, QgsVectorLayer::EditType> mEditTypeMap;
QMap<int, QPushButton*> mButtonMap;

enum attrColumns
{
attrIdCol = 0,
attrNameCol,
attrTypeCol,
attrLengthCol,
attrPrecCol,
attrCommentCol,
attrEditTypeCol,
attrAliasCol,
attrWMSCol,
attrWFSCol,
attrColCount,
};

static QMap< QgsVectorLayer::EditType, QString > editTypeMap;
static void setupEditTypes();
static QString editTypeButtonText( QgsVectorLayer::EditType type );
static QgsVectorLayer::EditType editTypeFromButtonText( QString text );

};

#endif // QGSFIELDSPROPERTIES_H
426 changes: 9 additions & 417 deletions src/app/qgsvectorlayerproperties.cpp

Large diffs are not rendered by default.

52 changes: 6 additions & 46 deletions src/app/qgsvectorlayerproperties.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class QgsVectorLayer;
class QgsVectorOverlayPlugin;
class QgsLabelingGui;
class QgsDiagramProperties;
class QgsFieldsProperties;

class QgsVectorLayerProperties : public QDialog, private Ui::QgsVectorLayerPropertiesBase
{
Expand Down Expand Up @@ -80,8 +81,6 @@ class QgsVectorLayerProperties : public QDialog, private Ui::QgsVectorLayerPrope

void insertExpression();

void attributeTypeDialog();

void alterLayerDialog( const QString& string );

/** Reset to original (vector layer) values */
Expand All @@ -99,12 +98,6 @@ class QgsVectorLayerProperties : public QDialog, private Ui::QgsVectorLayerPrope
/** Called when apply button is pressed or dialog is accepted */
void apply();

/** toggle editing of layer */
void toggleEditing();

/** editing of layer was toggled */
void editingToggled();

//
//methods reimplemented from qt designer base class
//
Expand All @@ -116,19 +109,11 @@ class QgsVectorLayerProperties : public QDialog, private Ui::QgsVectorLayerPrope
void on_pbnSaveDefaultStyle_clicked();
void on_pbnLoadStyle_clicked();
void on_pbnSaveStyleAs_clicked();
void on_tblAttributes_cellChanged( int row, int column );
void on_mCalculateFieldButton_clicked();
void on_pbnSelectEditForm_clicked();
void on_tabWidget_currentChanged( int idx );
void on_buttonBox_helpRequested() { QgsContextHelp::run( metaObject()->className() ); }
void on_pbnUpdateExtents_clicked();

void enableLabelOptions( bool theFlag );
void addAttribute();
void deleteAttribute();

void attributeAdded( int idx );
void attributeDeleted( int idx );

void useNewSymbology();
void setUsingNewSymbology( bool useNewSymbology );
Expand All @@ -148,6 +133,8 @@ class QgsVectorLayerProperties : public QDialog, private Ui::QgsVectorLayerPrope
void toggleEditing( QgsMapLayer * );

private slots:
/** toggle editing of layer */
void toggleEditing();

/** save the style based on selected format from the menu */
void saveStyleAsMenuTriggered( QAction * );
Expand All @@ -158,21 +145,6 @@ class QgsVectorLayerProperties : public QDialog, private Ui::QgsVectorLayerPrope

void updateSymbologyPage();

enum attrColumns
{
attrIdCol = 0,
attrNameCol,
attrTypeCol,
attrLengthCol,
attrPrecCol,
attrCommentCol,
attrEditTypeCol,
attrAliasCol,
attrWMSCol,
attrWFSCol,
attrColCount,
};

QgsVectorLayer *layer;

bool mMetadataFilled;
Expand All @@ -191,18 +163,11 @@ class QgsVectorLayerProperties : public QDialog, private Ui::QgsVectorLayerPrope
QgsAttributeActionDialog* actionDialog;
/**Diagram dialog. If apply is pressed, options are applied to vector's diagrams*/
QgsDiagramProperties* diagramPropertiesDialog;
/**Fields dialog. If apply is pressed, options are applied to vector's diagrams*/
QgsFieldsProperties* mFieldsPropertiesDialog;

QList<QgsApplyDialog*> mOverlayDialogs;
QMap<int, QPushButton*> mButtonMap;
QMap<int, QgsVectorLayer::EditType> mEditTypeMap;
QMap<int, QMap<QString, QVariant> > mValueMaps;
QMap<int, QgsVectorLayer::RangeData> mRanges;
QMap<int, QgsVectorLayer::ValueRelationData> mValueRelationData;
QMap<int, QPair<QString, QString> > mCheckedStates;

void updateButtons();
void loadRows();
void setRow( int row, int idx, const QgsField &field );
QList<QgsApplyDialog*> mOverlayDialogs;

void initDiagramTab();

Expand All @@ -214,11 +179,6 @@ class QgsVectorLayerProperties : public QDialog, private Ui::QgsVectorLayerPrope

/**Adds a new join to mJoinTreeWidget*/
void addJoinToTreeWidget( const QgsVectorJoinInfo& join );

static QMap< QgsVectorLayer::EditType, QString > editTypeMap;
static void setupEditTypes();
static QString editTypeButtonText( QgsVectorLayer::EditType type );
static QgsVectorLayer::EditType editTypeFromButtonText( QString text );
};

inline QString QgsVectorLayerProperties::displayName()
Expand Down
147 changes: 147 additions & 0 deletions src/core/qgsvectorlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3057,6 +3057,28 @@ bool QgsVectorLayer::readSymbology( const QDomNode& node, QString& errorMessage
//also restore custom properties (for labeling-ng)
readCustomProperties( node, "labeling" );

// tab display
QDomNode editorLayoutNode = node.namedItem( "editorlayout" );
if ( editorLayoutNode.isNull() )
{
mEditorLayout = GeneratedLayout;
}
else
{
if ( editorLayoutNode.toElement().text() == "uifilelayout" )
{
mEditorLayout = UiFileLayout;
}
else if ( editorLayoutNode.toElement().text() == "tablayout" )
{
mEditorLayout = TabLayout;
}
else
{
mEditorLayout = GeneratedLayout;
}
}

// Test if labeling is on or off
QDomNode labelnode = node.namedItem( "label" );
QDomElement element = labelnode.toElement();
Expand Down Expand Up @@ -3236,6 +3258,7 @@ bool QgsVectorLayer::readSymbology( const QDomNode& node, QString& errorMessage
}
}


//Attributes excluded from WMS and WFS
mExcludeAttributesWMS.clear();
QDomNode excludeWMSNode = node.namedItem( "excludeAttributesWMS" );
Expand All @@ -3258,9 +3281,49 @@ bool QgsVectorLayer::readSymbology( const QDomNode& node, QString& errorMessage
mExcludeAttributesWFS.insert( attributeNodeList.at( i ).toElement().text() );
}
}

// tabs and groups display info
mAttributeEditorElements.clear();
QDomNode attributeEditorFormNode = node.namedItem( "attributeEditorForm" );
QDomNodeList attributeEditorFormNodeList = attributeEditorFormNode.toElement().childNodes();

for ( int i = 0; i < attributeEditorFormNodeList.size(); i++ )
{
QDomElement elem = attributeEditorFormNodeList.at( i ).toElement();

QgsAttributeEditorElement *attributeEditorWidget = attributeEditorElementFromDomElement( elem, this );
mAttributeEditorElements.append( attributeEditorWidget );
}
return true;
}

QgsAttributeEditorElement* QgsVectorLayer::attributeEditorElementFromDomElement( QDomElement &elem, QObject* parent )
{
QgsAttributeEditorElement* newElement = NULL;

if ( elem.tagName() == "attributeEditorContainer" )
{
QgsAttributeEditorContainer* container = new QgsAttributeEditorContainer( elem.attribute( "name" ), parent );

QDomNodeList childNodeList = elem.childNodes();

for ( int i = 0; i < childNodeList.size(); i++ )
{
QDomElement childElem = childNodeList.at( i ).toElement();
QgsAttributeEditorElement* myElem = attributeEditorElementFromDomElement( childElem, container );
container->addChildElement( myElem );
}

newElement = container;
}
else if ( elem.tagName() == "attributeEditorField" )
{
newElement = new QgsAttributeEditorField( elem.attribute( "name" ), elem.attribute( "idx" ).toInt(), parent );
}

return newElement;
}

bool QgsVectorLayer::writeSymbology( QDomNode& node, QDomDocument& doc, QString& errorMessage ) const
{
QDomElement mapLayerNode = node.toElement();
Expand Down Expand Up @@ -3311,6 +3374,26 @@ bool QgsVectorLayer::writeSymbology( QDomNode& node, QDomDocument& doc, QString&
//save customproperties (for labeling ng)
writeCustomProperties( node, doc );

// tab display
QDomElement editorLayoutElem = doc.createElement( "editorlayout" );
switch ( mEditorLayout )
{
case UiFileLayout:
editorLayoutElem.appendChild( doc.createTextNode( "uifilelayout" ) );
break;

case TabLayout:
editorLayoutElem.appendChild( doc.createTextNode( "tablayout" ) );
break;

case GeneratedLayout:
default:
editorLayoutElem.appendChild( doc.createTextNode( "generatedlayout" ) );
break;
}

node.appendChild( editorLayoutElem );

// add the display field
QDomElement dField = doc.createElement( "displayfield" );
QDomText dFieldText = doc.createTextNode( displayField() );
Expand Down Expand Up @@ -3497,6 +3580,20 @@ bool QgsVectorLayer::writeSymbology( QDomNode& node, QDomDocument& doc, QString&
}
node.appendChild( excludeWFSElem );

// tabs and groups of edit form
if ( mAttributeEditorElements.size() > 0 )
{
QDomElement tabsElem = doc.createElement( "attributeEditorForm" );

for ( QList< QgsAttributeEditorElement* >::const_iterator it = mAttributeEditorElements.begin(); it != mAttributeEditorElements.end(); it++ )
{
QDomElement attributeEditorWidgetElem = ( *it )->toDomElement( doc );
tabsElem.appendChild( attributeEditorWidgetElem );
}

node.appendChild( tabsElem );
}

// add attribute actions
mActions->writeXML( node, doc );

Expand Down Expand Up @@ -3646,6 +3743,11 @@ void QgsVectorLayer::addAttributeAlias( int attIndex, QString aliasString )
emit layerModified( false );
}

void QgsVectorLayer::addAttributeEditorWidget( QgsAttributeEditorElement* data )
{
mAttributeEditorElements.append( data );
}

QString QgsVectorLayer::attributeAlias( int attributeIndex ) const
{
if ( !pendingFields().contains( attributeIndex ) )
Expand Down Expand Up @@ -4706,6 +4808,16 @@ void QgsVectorLayer::setEditType( int idx, EditType type )
mEditTypes[ fields[idx].name()] = type;
}

QgsVectorLayer::EditorLayout QgsVectorLayer::editorLayout()
{
return mEditorLayout;
}

void QgsVectorLayer::setEditorLayout( EditorLayout editorLayout )
{
mEditorLayout = editorLayout;
}

QString QgsVectorLayer::editForm()
{
return mEditForm;
Expand Down Expand Up @@ -5798,3 +5910,38 @@ QgsVectorLayer::ValueRelationData &QgsVectorLayer::valueRelation( int idx )

return mValueRelations[ fields[idx].name()];
}

QList<QgsAttributeEditorElement*> &QgsVectorLayer::attributeEditorElements()
{
return mAttributeEditorElements;
}

void QgsVectorLayer::clearAttributeEditorWidgets()
{
mAttributeEditorElements.clear();
}

QDomElement QgsAttributeEditorContainer::toDomElement( QDomDocument& doc ) const
{
QDomElement elem = doc.createElement( "attributeEditorContainer" );
elem.setAttribute( "name", mName );
for ( QList< QgsAttributeEditorElement* >::const_iterator it = mChildren.begin(); it != mChildren.end(); ++it )
{
elem.appendChild(( *it )->toDomElement( doc ) );
}
return elem;
}


void QgsAttributeEditorContainer::addChildElement( QgsAttributeEditorElement *widget )
{
mChildren.append( widget );
}

QDomElement QgsAttributeEditorField::toDomElement( QDomDocument& doc ) const
{
QDomElement elem = doc.createElement( "attributeEditorField" );
elem.setAttribute( "name", mName );
elem.setAttribute( "index", mIdx );
return elem;
}
123 changes: 121 additions & 2 deletions src/core/qgsvectorlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,67 @@ class QgsDiagramLayerSettings;
typedef QList<int> QgsAttributeList;
typedef QSet<int> QgsAttributeIds;

/** @note Added in 1.9 */
class QgsAttributeEditorElement : public QObject
{
Q_OBJECT
public:

enum AttributeEditorType
{
AeTypeContainer,
AeTypeField,
AeTypeInvalid
};

QgsAttributeEditorElement( AttributeEditorType type, QString name, QObject *parent = NULL )
: QObject( parent ), mType( type ), mName( name ) {}

virtual ~QgsAttributeEditorElement() {}

QString name() const { return mName; }
AttributeEditorType type() const { return mType; }

virtual QDomElement toDomElement( QDomDocument& doc ) const = 0;

protected:
AttributeEditorType mType;
QString mName;
};

/** @note Added in 1.9 */
class QgsAttributeEditorContainer : public QgsAttributeEditorElement
{
public:
QgsAttributeEditorContainer( QString name, QObject *parent )
: QgsAttributeEditorElement( AeTypeContainer, name, parent ) {}

~QgsAttributeEditorContainer() {}

virtual QDomElement toDomElement( QDomDocument& doc ) const;
virtual void addChildElement( QgsAttributeEditorElement *widget );
QList<QgsAttributeEditorElement*> children() const { return mChildren; }

private:
QList<QgsAttributeEditorElement*> mChildren;
};

/** @note Added in 1.9 */
class QgsAttributeEditorField : public QgsAttributeEditorElement
{
public:
QgsAttributeEditorField( QString name , int idx, QObject *parent )
: QgsAttributeEditorElement( AeTypeField, name, parent ), mIdx( idx ) {}

~QgsAttributeEditorField() {}

virtual QDomElement toDomElement( QDomDocument& doc ) const;
int idx() const { return mIdx; }

private:
int mIdx;
};

/** @note added in 1.7 */
struct CORE_EXPORT QgsVectorJoinInfo
{
Expand Down Expand Up @@ -89,6 +150,14 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
Q_OBJECT

public:
/** The different types to layout the attribute editor. @note added in 1.9 */
enum EditorLayout
{
GeneratedLayout = 0,
TabLayout = 1,
UiFileLayout = 2
};

enum EditType
{
LineEdit,
Expand Down Expand Up @@ -148,6 +217,25 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
bool mAllowMulti; /* allow selection of multiple keys @added in 1.9 */
};

struct GroupData
{
GroupData() {}
GroupData( QString name , QList<QString> fields )
: mName ( name ), mFields( fields ) {}
QString mName;
QList<QString> mFields;
};

struct TabData
{
TabData() {}
TabData( QString name , QList<QString> fields , QList<GroupData> groups)
: mName ( name ), mFields( fields ), mGroups( groups ) {}
QString mName;
QList<QString> mFields;
QList<GroupData> mGroups;
};

/** Constructor */
QgsVectorLayer( QString path = QString::null, QString baseName = QString::null,
QString providerLib = QString::null, bool loadDefaultStyleFlag = true );
Expand Down Expand Up @@ -296,6 +384,12 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
*/
virtual bool writeXml( QDomNode & layer_node, QDomDocument & doc );

/** convert a saved attribute editor element into a AttributeEditor structure as it's used internally.
* @param elem the DOM element
* @param parent the QObject which will own this object
*/
static QgsAttributeEditorElement* attributeEditorElementFromDomElement( QDomElement &elem, QObject* parent );

/** Read the symbology for the current layer from the Dom node supplied.
* @param node node that will contain the symbology definition for this layer.
* @param errorMessage reference to string that will be updated with any error messages
Expand Down Expand Up @@ -564,6 +658,16 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
@note added in version 1.2*/
void addAttributeAlias( int attIndex, QString aliasString );

/**Adds a tab (for the attribute editor form) holding groups and fields
@note added in version 1.9*/
void addAttributeEditorWidget( QgsAttributeEditorElement* data );
/**Returns a list of tabs holding groups and fields
@note added in version 1.9*/
QList< QgsAttributeEditorElement* > &attributeEditorElements();
/**Clears all the tabs for the attribute editor form
@note added in version 1.9*/
void clearAttributeEditorWidgets();

/**Returns the alias of an attribute name or an empty string if there is no alias
@note added in version 1.2*/
QString attributeAlias( int attributeIndex ) const;
Expand Down Expand Up @@ -616,6 +720,12 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
/**set edit type*/
void setEditType( int idx, EditType edit );

/** get the active layout for the attribute editor for this layer (added in 1.9) */
EditorLayout editorLayout();

/** set the active layout for the attribute editor for this layer (added in 1.9) */
void setEditorLayout( EditorLayout editorLayout );

/** set string representing 'true' for a checkbox (added in 1.4) */
void setCheckedState( int idx, QString checked, QString notChecked );

Expand Down Expand Up @@ -974,11 +1084,17 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
/**Map that stores the aliases for attributes. Key is the attribute name and value the alias for that attribute*/
QMap< QString, QString > mAttributeAliasMap;

/**Stores a list of attribute editor elements (Each holding a tree structure for a tab in the attribute editor)*/
QList< QgsAttributeEditorElement* > mAttributeEditorElements;

/**Attributes which are not published in WMS*/
QSet<QString> mExcludeAttributesWMS;
/**Attributes which are not published in WFS*/
QSet<QString> mExcludeAttributesWFS;

/**Map that stores the tab for attributes in the edit form. Key is the tab order and value the tab name*/
QList< TabData > mTabs;

/** max field index */
int mMaxUpdatedIndex;

Expand Down Expand Up @@ -1008,10 +1124,10 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
/** The current size of editing marker */
int mCurrentVertexMarkerSize;

/**Flag if the vertex markers should be drawn only for selection (true) or for all features (false)*/
/** Flag if the vertex markers should be drawn only for selection (true) or for all features (false) */
bool mVertexMarkerOnlyForSelection;

/**List of overlays. Vector overlays will be rendered on top of all maplayers*/
/** List of overlays. Vector overlays will be rendered on top of all maplayers */
QList<QgsVectorOverlay*> mOverlays;

QStringList mCommitErrors;
Expand All @@ -1022,6 +1138,9 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
QMap< QString, QPair<QString, QString> > mCheckedStates;
QMap< QString, ValueRelationData > mValueRelations;

/** Defines the default layout to use for the attribute editor (Drag and drop, UI File, Generated) */
EditorLayout mEditorLayout;

QString mEditForm, mEditFormInit;
//annotation form for this layer
QString mAnnotationForm;
Expand Down
106 changes: 105 additions & 1 deletion src/gui/qgsattributeeditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
#include <QSettings>
#include <QDir>
#include <QUuid>
#include <QGroupBox>
#include <QLabel>

void QgsAttributeEditor::selectFileName()
{
Expand Down Expand Up @@ -124,10 +126,17 @@ QListWidget *QgsAttributeEditor::listWidget( QWidget *editor, QWidget *parent )
}

QWidget *QgsAttributeEditor::createAttributeEditor( QWidget *parent, QWidget *editor, QgsVectorLayer *vl, int idx, const QVariant &value )
{
QMap<int, QWidget*> dummyProxyWidgets;
return createAttributeEditor( parent, editor, vl, idx, value, dummyProxyWidgets );
}

QWidget *QgsAttributeEditor::createAttributeEditor( QWidget *parent, QWidget *editor, QgsVectorLayer *vl, int idx, const QVariant &value, QMap<int, QWidget*> &proxyWidgets )
{
if ( !vl )
return 0;

bool synchronized = false;
QWidget *myWidget = 0;
QgsVectorLayer::EditType editType = vl->editType( idx );
const QgsField &field = vl->pendingFields()[idx];
Expand Down Expand Up @@ -447,7 +456,6 @@ QWidget *QgsAttributeEditor::createAttributeEditor( QWidget *parent, QWidget *ed

if ( le )
{

if ( editType == QgsVectorLayer::UniqueValuesEditable )
{
QList<QVariant> values;
Expand All @@ -468,6 +476,7 @@ QWidget *QgsAttributeEditor::createAttributeEditor( QWidget *parent, QWidget *ed
}

le->setValidator( new QgsFieldValidator( le, field ) );

myWidget = le;
}

Expand All @@ -485,6 +494,13 @@ QWidget *QgsAttributeEditor::createAttributeEditor( QWidget *parent, QWidget *ed
if ( myWidget )
{
myWidget->setDisabled( editType == QgsVectorLayer::Immutable );

QMap<int, QWidget*>::const_iterator it = proxyWidgets.find( idx );
if ( it != proxyWidgets.end() )
{
synchronized = connect( *it, SIGNAL( textChanged( QString ) ), myWidget, SLOT( setText( QString ) ) );
synchronized &= connect( myWidget, SIGNAL( textChanged( QString ) ), *it, SLOT( setText( QString ) ) );
}
}
}
break;
Expand Down Expand Up @@ -535,6 +551,19 @@ QWidget *QgsAttributeEditor::createAttributeEditor( QWidget *parent, QWidget *ed
break;
}

QMap<int, QWidget*>::const_iterator it = proxyWidgets.find( idx );
if ( it != proxyWidgets.end() )
{
if ( !synchronized )
{
myWidget->setEnabled( false );
}
}
else
{
proxyWidgets.insert( idx, myWidget );
}

setValue( myWidget, vl, idx, value );

return myWidget;
Expand Down Expand Up @@ -877,3 +906,78 @@ bool QgsAttributeEditor::setValue( QWidget *editor, QgsVectorLayer *vl, int idx,

return true;
}

QWidget* QgsAttributeEditor::createWidgetFromDef( const QgsAttributeEditorElement* widgetDef, QWidget* parent, QgsVectorLayer* vl, QgsAttributeMap &attrs, QMap<int, QWidget*> &proxyWidgets, bool createGroupBox )
{
QWidget *newWidget = 0;

switch ( widgetDef->type() )
{
case QgsAttributeEditorElement::AeTypeField:
{
const QgsAttributeEditorField* fieldDef = dynamic_cast<const QgsAttributeEditorField*>( widgetDef );
newWidget = createAttributeEditor( parent, 0, vl, fieldDef->idx(), attrs.value( fieldDef->idx(), QVariant() ), proxyWidgets );


if ( vl->editType( fieldDef->idx() ) != QgsVectorLayer::Immutable )
{
newWidget->setEnabled( newWidget->isEnabled() && vl->isEditable() );
}

break;
}

case QgsAttributeEditorElement::AeTypeContainer:
{
const QgsAttributeEditorContainer* container = dynamic_cast<const QgsAttributeEditorContainer*>( widgetDef );
QWidget* myContainer;

if ( createGroupBox )
{
QGroupBox* groupBox = new QGroupBox( parent );
groupBox->setTitle( container->name() );
myContainer = groupBox;
}
else
{
myContainer = new QWidget( parent );
}

QGridLayout* gbLayout = new QGridLayout( myContainer );

int index = 0;

QList<QgsAttributeEditorElement*>children = container->children();

for ( QList<QgsAttributeEditorElement*>::const_iterator it = children.begin(); it != children.end(); ++it )
{
QgsAttributeEditorElement* childDef = *it;
QWidget* editor = createWidgetFromDef( childDef, myContainer, vl, attrs, proxyWidgets, true );

if ( childDef->type() == QgsAttributeEditorElement::AeTypeContainer )
{
gbLayout->addWidget( editor, index, 0, 1, 2 );
}
else
{
QLabel * mypLabel = new QLabel( myContainer );
gbLayout->addWidget( mypLabel, index, 0 );
mypLabel->setText( childDef->name() );
gbLayout->addWidget( editor, index, 1 );
}

++index;
}
gbLayout->addItem( new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding ), index , 0 );

newWidget = myContainer;
break;
}

default:
QgsDebugMsg( "Unknown attribute editor widget type encountered..." );
break;
}

return newWidget;
}
35 changes: 35 additions & 0 deletions src/gui/qgsattributeeditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@

#include <QVariant>

#include "qgsfeature.h"

class QObject;
class QWidget;
class QgsVectorLayer;
class QComboBox;
class QListWidget;
class QgsAttributeEditorElement;

/* \brief create attribute widget for editing */
class GUI_EXPORT QgsAttributeEditor : public QObject
Expand All @@ -32,7 +35,39 @@ class GUI_EXPORT QgsAttributeEditor : public QObject

public:
QgsAttributeEditor( QObject *parent ) : QObject( parent ) {};
/**
* Creates or prepares a attributre editor widget
* @param parent The parent object
* @param editor The widget to prepare. Set to null if it should be generated
* @param vl The vector layer to use as data source
* @param idx The field index this widget refers to
* @param value the value to initiate this widget with
* @param proxyWidgets an array of widgets, which will act as a value proxy if the same field is inserted multiple times
*
*/
static QWidget *createAttributeEditor( QWidget *parent, QWidget *editor, QgsVectorLayer *vl, int idx, const QVariant &value, QMap<int, QWidget*> &proxyWidgets );
/**
* Creates or prepares a attributre editor widget
* @param parent The parent object
* @param editor The widget to prepare. Set to null if it should be generated
* @param vl The vector layer to use as data source
* @param idx The field index this widget refers to
* @param value the value to initiate this widget with
*
*/
static QWidget *createAttributeEditor( QWidget *parent, QWidget *editor, QgsVectorLayer *vl, int idx, const QVariant &value );
/**
* Creates a widget form a QgsAttributeEditorElement definition. Will recursively generate containers and widgets.
* @param widgetDef The definition for the widget
* @param parent The parent object
* @param editor The widget to prepare. Set to null if it should be generated
* @param vl The vector layer to use as data source
* @param attrs Attributes for the current feature.
* @param proxyWidgets An array of widgets, which will act as a value proxy if the same field is inserted multiple times
* @param createGroupBox If the element is a container, should a GroupBox be created to hold the children?
*
*/
static QWidget *createWidgetFromDef( const QgsAttributeEditorElement* widgetDef, QWidget* parent, QgsVectorLayer* vl, QgsAttributeMap &attrs, QMap<int, QWidget*> &proxyWidgets, bool createGroupBox );
static bool retrieveValue( QWidget *widget, QgsVectorLayer *vl, int idx, QVariant &value );
static bool setValue( QWidget *widget, QgsVectorLayer *vl, int idx, const QVariant &value );

Expand Down
134 changes: 134 additions & 0 deletions src/ui/qgsaddtaborgroupbase.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QgsAddTabOrGroupBase</class>
<widget class="QDialog" name="QgsAddTabOrGroupBase">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>447</width>
<height>164</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="3" column="1">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Create category</string>
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QLineEdit" name="mName"/>
</item>
<item row="0" column="3">
<widget class="QLabel" name="label_2">
<property name="text">
<string>as</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QRadioButton" name="mTabButton">
<property name="text">
<string>a tab</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup</string>
</attribute>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QRadioButton" name="mGroupButton">
<property name="text">
<string>a group in container</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup</string>
</attribute>
</widget>
</item>
<item row="2" column="2" colspan="2">
<widget class="QComboBox" name="mTabList">
<property name="enabled">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0" rowspan="3" colspan="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>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>QgsAddTabOrGroupBase</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>QgsAddTabOrGroupBase</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>
<buttongroups>
<buttongroup name="buttonGroup"/>
</buttongroups>
</ui>
1 change: 0 additions & 1 deletion src/ui/qgscptcitycolorrampv2dialogbase.ui
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,6 @@
<zorder>lblLicenseName</zorder>
<zorder>lblAuthorName</zorder>
<zorder>pbtnLicenseDetails</zorder>
<zorder>horizontalSpacer_5</zorder>
<zorder>label_3</zorder>
</widget>
</widget>
Expand Down
330 changes: 330 additions & 0 deletions src/ui/qgsfieldspropertiesbase.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,330 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QgsFieldsPropertiesBase</class>
<widget class="QWidget" name="QgsFieldsPropertiesBase">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>782</width>
<height>663</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_6">
<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>
<item row="0" column="4">
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>100</width>
<height>19</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 column</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normaloff>.designer/xpm/new_attribute.png</normaloff>.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 column</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normaloff>.designer/xpm/delete_attribute.png</normaloff>.designer/xpm/delete_attribute.png</iconset>
</property>
<property name="shortcut">
<string>Ctrl+X</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="7">
<layout class="QHBoxLayout" name="horizontalLayout_15">
<item>
<widget class="QWidget" name="mAttributesListFrame" native="true"/>
</item>
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QGridLayout" name="gridLayout_18">
<property name="margin">
<number>0</number>
</property>
<item row="1" column="0" colspan="3">
<widget class="QStackedWidget" name="mAttributeEditorOptionsWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="page">
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLineEdit" name="leEditForm"/>
</item>
<item>
<widget class="QToolButton" name="pbnSelectEditForm">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Init function</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="leEditFormInit"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Edit UI</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="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>
</layout>
</widget>
<widget class="QWidget" name="page_2">
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="1">
<widget class="QWidget" name="mAttributesTreeButtonFrame" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>30</width>
<height>16777215</height>
</size>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>186</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="mAddTabOrGroupButton">
<property name="text">
<string>+</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mActionSignPlus.png</normaloff>:/images/themes/default/mActionSignPlus.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="mRemoveTabGroupItemButton">
<property name="text">
<string>-</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mActionSignMinus.png</normaloff>:/images/themes/default/mActionSignMinus.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="mAddItemButton">
<property name="text">
<string>&gt;</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mActionArrowRight.png</normaloff>:/images/themes/default/mActionArrowRight.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="mMoveUpItem">
<property name="text">
<string>^</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mActionArrowUp.png</normaloff>:/images/themes/default/mActionArrowUp.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="mMoveDownItem">
<property name="text">
<string>v</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mActionArrowDown.png</normaloff>:/images/themes/default/mActionArrowDown.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>176</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="1" column="2">
<widget class="QWidget" name="mAttributesTreeFrame" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item row="0" column="6">
<widget class="QComboBox" name="mEditorLayoutComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<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 row="0" column="5">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Attribute editor layout:</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../../images/images.qrc"/>
</resources>
<connections/>
</ui>
187 changes: 37 additions & 150 deletions src/ui/qgsvectorlayerpropertiesbase.ui
Original file line number Diff line number Diff line change
Expand Up @@ -248,116 +248,22 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="tabWidgetPage3">
<widget class="QWidget" name="mFieldsPage">
<attribute name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/propertyicons/attributes.png</normaloff>:/images/themes/default/propertyicons/attributes.png</iconset>
</attribute>
<attribute name="title">
<string>Fields</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_6">
<layout class="QGridLayout" name="mFieldsGridLayout">
<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 column</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normaloff>.designer/xpm/new_attribute.png</normaloff>.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 column</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normaloff>.designer/xpm/delete_attribute.png</normaloff>.designer/xpm/delete_attribute.png</iconset>
</property>
<property name="shortcut">
<string>Ctrl+X</string>
</property>
</widget>
</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="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>
<item row="0" column="4">
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>658</width>
<height>19</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0" colspan="5">
<widget class="QTableWidget" name="tblAttributes">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>256</width>
<height>0</height>
</size>
<widget class="QFrame" name="mFieldsFrame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="sortingEnabled">
<bool>false</bool>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
</widget>
</item>
Expand Down Expand Up @@ -402,66 +308,28 @@
<string>Options</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Edit UI</string>
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLineEdit" name="leEditForm"/>
</item>
<item>
<widget class="QToolButton" name="pbnSelectEditForm">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="3">
<widget class="QPushButton" name="pbnIndex">
<property name="text">
<string>Create Spatial Index</string>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QPushButton" name="pbnUpdateExtents">
<property name="text">
<string>Update Extents</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<widget class="QLineEdit" name="leEditFormInit"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Init function</string>
<item row="0" column="2" colspan="3">
<widget class="QLineEdit" name="leSpatialRefSys">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>CRS</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="leSpatialRefSys">
<property name="readOnly">
<bool>true</bool>
<item row="2" column="0" colspan="3">
<widget class="QPushButton" name="pbnIndex">
<property name="text">
<string>Create Spatial Index</string>
</property>
</widget>
</item>
<item row="2" column="3">
<item row="0" column="5">
<widget class="QPushButton" name="pbnChangeSpatialRefSys">
<property name="toolTip">
<string>Specify the coordinate reference system of the layer's geometry.</string>
Expand All @@ -474,6 +342,26 @@
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QPushButton" name="pbnUpdateExtents">
<property name="text">
<string>Update Extents</string>
</property>
</widget>
</item>
<item row="2" column="4">
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
Expand Down Expand Up @@ -1032,7 +920,6 @@
</customwidget>
</customwidgets>
<tabstops>
<tabstop>pbnIndex</tabstop>
<tabstop>cbMinimumScale</tabstop>
<tabstop>cbMaximumScale</tabstop>
<tabstop>txtSubsetSQL</tabstop>
Expand Down