add missing metadata fields about contacts and extent (#5878)

This commit is contained in:
Etienne Trimaille 2017-12-15 13:16:49 +01:00 committed by Tim Sutton
parent 0c7cf21fe2
commit 9eb938c61c
3 changed files with 392 additions and 189 deletions

View File

@ -23,6 +23,7 @@
#include <QInputDialog>
#include <QStringListModel>
#include "qgsbox3d.h"
#include "qgsmetadatawidget.h"
#include "qgslogger.h"
#include "qgslayermetadatavalidator.h"
@ -36,9 +37,8 @@ QgsMetadataWidget::QgsMetadataWidget( QWidget *parent, QgsMapLayer *layer )
mMetadata = layer->metadata();
tabWidget->setCurrentIndex( 0 );
// Disable the encoding and contacts
// Disable the encoding
encodingFrame->setHidden( true );
tabWidget->removeTab( 5 );
// Default categories, we want them translated, so we are not using a CSV.
mDefaultCategories << tr( "Farming" ) << tr( "Climatology Meteorology Atmosphere" ) << tr( "Location" ) << tr( "Intelligence Military" ) << tr( "Transportation" ) << tr( "Structure" ) << tr( "Boundaries" );
@ -65,6 +65,11 @@ QgsMetadataWidget::QgsMetadataWidget( QWidget *parent, QgsMapLayer *layer )
tabConstraints->setModel( mConstraintsModel );
tabConstraints->setItemDelegate( new ConstraintItemDelegate( this ) );
// Extent
selectionCrs->setOptionVisible( QgsProjectionSelectionWidget::CrsNotSet, true );
dateTimeFrom->setAllowNull( true );
dateTimeTo->setAllowNull( true );
// Setup the link view
mLinksModel = new QStandardItemModel( tabLinks );
mLinksModel->setColumnCount( 7 );
@ -90,9 +95,9 @@ QgsMetadataWidget::QgsMetadataWidget( QWidget *parent, QgsMapLayer *layer )
connect( btnAddConstraint, &QPushButton::clicked, this, &QgsMetadataWidget::addConstraint );
connect( btnRemoveConstraint, &QPushButton::clicked, this, &QgsMetadataWidget::removeSelectedConstraint );
connect( btnAutoCrs, &QPushButton::clicked, this, &QgsMetadataWidget::fillCrsFromLayer );
connect( btnAddContact, &QPushButton::clicked, this, &QgsMetadataWidget::addContact );
connect( btnRemoveContact, &QPushButton::clicked, this, &QgsMetadataWidget::removeSelectedContact );
connect( tabContacts, &QTableWidget::itemSelectionChanged, this, &QgsMetadataWidget::updateContactDetails );
connect( selectionCrs, &QgsProjectionSelectionWidget::crsChanged, this, &QgsMetadataWidget::toggleExtentSelector );
connect( btnAddAddress, &QPushButton::clicked, this, &QgsMetadataWidget::addAddress );
connect( btnRemoveAddress, &QPushButton::clicked, this, &QgsMetadataWidget::removeSelectedAddress );
connect( btnAddLink, &QPushButton::clicked, this, &QgsMetadataWidget::addLink );
connect( btnRemoveLink, &QPushButton::clicked, this, &QgsMetadataWidget::removeSelectedLink );
connect( btnAddHistory, &QPushButton::clicked, this, &QgsMetadataWidget::addHistory );
@ -103,7 +108,6 @@ QgsMetadataWidget::QgsMetadataWidget( QWidget *parent, QgsMapLayer *layer )
fillComboBox();
setPropertiesFromLayer();
updateContactDetails();
}
void QgsMetadataWidget::fillSourceFromLayer() const
@ -196,56 +200,51 @@ void QgsMetadataWidget::removeSelectedConstraint() const
mConstraintsModel->removeRow( selectedRows[0].row() );
}
void QgsMetadataWidget::fillCrsFromLayer() const
void QgsMetadataWidget::toggleExtentSelector() const
{
selectionCrs->setCrs( mLayer->crs() );
spatialExtentSelector->setEnabled( selectionCrs->crs().isValid() );
spatialExtentSelector->setOutputCrs( selectionCrs->crs() );
}
void QgsMetadataWidget::addContact() const
void QgsMetadataWidget::addAddress() const
{
int row = tabContacts->rowCount();
tabContacts->setRowCount( row + 1 );
int row = tabAddresses->rowCount();
tabAddresses->setRowCount( row + 1 );
QTableWidgetItem *pCell = nullptr;
// Name
pCell = new QTableWidgetItem( QString( tr( "unnamed %1" ) ).arg( row + 1 ) );
tabContacts->setItem( row, 0, pCell );
// Type
pCell = new QTableWidgetItem( QString( tr( "postal" ) ) );
tabAddresses->setItem( row, 0, pCell );
// Organization
pCell = new QTableWidgetItem();
tabContacts->setItem( row, 1, pCell );
// Address
tabAddresses->setItem( row, 1, new QTableWidgetItem() );
// Set last item selected
tabContacts->selectRow( row );
// postal code
tabAddresses->setItem( row, 2, new QTableWidgetItem() );
// City
tabAddresses->setItem( row, 3, new QTableWidgetItem() );
// Admin area
tabAddresses->setItem( row, 4, new QTableWidgetItem() );
// Country
tabAddresses->setItem( row, 5, new QTableWidgetItem() );
}
void QgsMetadataWidget::removeSelectedContact() const
void QgsMetadataWidget::removeSelectedAddress() const
{
QItemSelectionModel *selectionModel = tabContacts->selectionModel();
QItemSelectionModel *selectionModel = tabAddresses->selectionModel();
const QModelIndexList selectedRows = selectionModel->selectedRows();
for ( int i = 0; i < selectedRows.size() ; i++ )
{
tabContacts->model()->removeRow( selectedRows[i].row() );
tabAddresses->model()->removeRow( selectedRows[i].row() );
}
}
void QgsMetadataWidget::updateContactDetails() const
void QgsMetadataWidget::fillCrsFromLayer() const
{
QItemSelectionModel *selectionModel = tabContacts->selectionModel();
const QModelIndexList selectedRows = selectionModel->selectedRows();
if ( ! selectedRows.isEmpty() )
{
panelDetails->setDisabled( false );
lineEditContactName->setText( tabContacts->item( selectedRows[0].row(), 0 )->text() );
lineEditContactOrganization->setText( tabContacts->item( selectedRows[0].row(), 1 )->text() );
}
else
{
panelDetails->setDisabled( true );
lineEditContactName->clear();
lineEditContactOrganization->clear();
}
selectionCrs->setCrs( mLayer->crs() );
}
void QgsMetadataWidget::addLink() const
@ -414,9 +413,57 @@ void QgsMetadataWidget::setPropertiesFromLayer() const
{
selectionCrs->setCrs( mMetadata.crs() );
}
else
toggleExtentSelector();
// Spatial extent
const QList<QgsLayerMetadata::SpatialExtent> &spatialExtents = mMetadata.extent().spatialExtents();
if ( ! spatialExtents.isEmpty() )
{
selectionCrs->setOptionVisible( QgsProjectionSelectionWidget::CrsNotSet, true );
// Even if it's a list, it's supposed to store the same extent in different CRS.
spatialExtentSelector->setCurrentExtent( spatialExtents.at( 0 ).bounds.toRectangle(), spatialExtents.at( 0 ).extentCrs );
spatialExtentSelector->setOutputCrs( spatialExtents.at( 0 ).extentCrs );
spinBoxZMaximum->setValue( spatialExtents.at( 0 ).bounds.zMaximum() );
spinBoxZMinimum->setValue( spatialExtents.at( 0 ).bounds.zMinimum() );
}
// Temporal extent
const QList<QgsDateTimeRange> &temporalExtents = mMetadata.extent().temporalExtents();
if ( ! temporalExtents.isEmpty() )
{
// Even if it's a list, it seems we use only one for now (cf discussion with Tom)
dateTimeFrom->setDateTime( temporalExtents.at( 0 ).begin() );
dateTimeFrom->setDateTime( temporalExtents.at( 0 ).end() );
}
// Contacts
const QList<QgsLayerMetadata::Contact> &contacts = mMetadata.contacts();
if ( ! contacts.isEmpty() )
{
// Only one contact supported in the UI for now
const QgsLayerMetadata::Contact &contact = contacts.at( 0 );
lineEditContactName->setText( contact.name );
lineEditContactEmail->setText( contact.email );
lineEditContactFax->setText( contact.fax );
lineEditContactOrganization->setText( contact.organization );
lineEditContactPosition->setText( contact.position );
lineEditContactVoice->setText( contact.voice );
if ( comboContactRole->findText( contact.role ) == -1 )
{
comboContactRole->addItem( contact.role );
}
comboContactRole->setCurrentIndex( comboContactRole->findText( contact.role ) );
tabAddresses->setRowCount( 0 );
const QList<QgsLayerMetadata::Address> &addresses = contact.addresses;
for ( const QgsLayerMetadata::Address &address : addresses )
{
int currentRow = tabKeywords->rowCount() - 1;
tabAddresses->item( currentRow, 0 )->setText( address.type );
tabAddresses->item( currentRow, 1 )->setText( address.address );
tabAddresses->item( currentRow, 2 )->setText( address.postalCode );
tabAddresses->item( currentRow, 3 )->setText( address.city );
tabAddresses->item( currentRow, 4 )->setText( address.administrativeArea );
tabAddresses->item( currentRow, 5 )->setText( address.country );
}
}
// Links
@ -483,6 +530,50 @@ void QgsMetadataWidget::saveMetadata( QgsLayerMetadata &layerMetadata ) const
// CRS
layerMetadata.setCrs( selectionCrs->crs() );
// Extent
struct QgsLayerMetadata::SpatialExtent spatialExtent = QgsLayerMetadata::SpatialExtent();
spatialExtent.bounds = QgsBox3d( spatialExtentSelector->outputExtent() );
spatialExtent.bounds.setZMinimum( spinBoxZMinimum->value() );
spatialExtent.bounds.setZMaximum( spinBoxZMaximum->value() );
spatialExtent.extentCrs = spatialExtentSelector->outputCrs();
QList<QgsLayerMetadata::SpatialExtent> spatialExtents;
spatialExtents.append( spatialExtent );
QList<QgsDateTimeRange> temporalExtents;
temporalExtents.append( QgsDateTimeRange( dateTimeFrom->dateTime(), dateTimeTo->dateTime() ) );
struct QgsLayerMetadata::Extent extent = QgsLayerMetadata::Extent();
extent.setSpatialExtents( spatialExtents );
extent.setTemporalExtents( temporalExtents );
layerMetadata.setExtent( extent );
// Contacts, only one contact supported in the UI for now.
// We don't want to lost data if more than one contact, so we update only the first one.
QList<QgsLayerMetadata::Contact> contacts = mMetadata.contacts();
if ( contacts.size() > 0 )
contacts.removeFirst();
struct QgsLayerMetadata::Contact contact = QgsLayerMetadata::Contact();
contact.email = lineEditContactEmail->text();
contact.position = lineEditContactPosition->text();
contact.fax = lineEditContactFax->text();
contact.voice = lineEditContactVoice->text();
contact.name = lineEditContactName->text();
contact.organization = lineEditContactOrganization->text();
contact.role = comboContactRole->currentText();
QList<QgsLayerMetadata::Address> addresses;
for ( int i = 0; i < tabAddresses->rowCount() ; i++ )
{
struct QgsLayerMetadata::Address address = QgsLayerMetadata::Address();
address.type = tabAddresses->item( i, 0 )->text();
address.address = tabAddresses->item( i, 1 )->text();
address.postalCode = tabAddresses->item( i, 2 )->text();
address.city = tabAddresses->item( i, 3 )->text();
address.administrativeArea = tabAddresses->item( i, 4 )->text();
address.country = tabAddresses->item( i, 5 )->text();
addresses.append( address );
}
contact.addresses = addresses;
contacts.insert( 0, contact );
layerMetadata.setContacts( contacts );
// Links
QList<QgsLayerMetadata::Link> links;
for ( int row = 0; row < mLinksModel->rowCount() ; row++ )

View File

@ -101,13 +101,13 @@ class GUI_EXPORT QgsMetadataWidget : public QWidget, private Ui::QgsMetadataWidg
void removeSelectedRight() const;
void addConstraint() const;
void removeSelectedConstraint() const;
void addContact() const;
void removeSelectedContact() const;
void toggleExtentSelector() const;
void addAddress() const;
void removeSelectedAddress() const;
void addLink() const;
void removeSelectedLink() const;
void addHistory();
void removeSelectedHistory() const;
void updateContactDetails() const;
void fillComboBox() const;
void setPropertiesFromLayer() const;
void syncFromCategoriesTabToKeywordsTab() const;

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>797</width>
<height>568</height>
<width>804</width>
<height>697</height>
</rect>
</property>
<property name="windowTitle">
@ -35,7 +35,7 @@
<enum>QTabWidget::Rounded</enum>
</property>
<property name="currentIndex">
<number>0</number>
<number>4</number>
</property>
<widget class="QWidget" name="tabIdentificationDialog">
<attribute name="title">
@ -67,8 +67,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>777</width>
<height>596</height>
<width>798</width>
<height>668</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_15">
@ -222,7 +222,7 @@
<item>
<widget class="QFrame" name="encodingFrame">
<property name="enabled">
<bool>false</bool>
<bool>true</bool>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
@ -571,8 +571,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>767</width>
<height>521</height>
<width>798</width>
<height>668</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_16">
@ -802,7 +802,7 @@
<item>
<widget class="QLabel" name="label_9">
<property name="text">
<string>Coordinate Reference System, spatial and temporal extent(s) for this dataset.</string>
<string>Coordinate Reference System and spatial extent for this dataset.</string>
</property>
</widget>
</item>
@ -838,6 +838,76 @@
</layout>
</widget>
</item>
<item>
<widget class="QgsExtentGroupBox" name="spatialExtentSelector">
<property name="title">
<string/>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_14">
<item>
<widget class="QLabel" name="label_32">
<property name="text">
<string>Z Maximum</string>
</property>
</widget>
</item>
<item>
<widget class="QgsSpinBox" name="spinBoxZMaximum"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_13">
<item>
<widget class="QLabel" name="label_31">
<property name="text">
<string>Z Minimum</string>
</property>
</widget>
</item>
<item>
<widget class="QgsSpinBox" name="spinBoxZMinimum"/>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label_35">
<property name="text">
<string>Temporal extent for this dataset.</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_15">
<item>
<widget class="QLabel" name="label_33">
<property name="text">
<string>From</string>
</property>
</widget>
</item>
<item>
<widget class="QgsDateTimeEdit" name="dateTimeFrom"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_16">
<item>
<widget class="QLabel" name="label_34">
<property name="text">
<string>To</string>
</property>
</widget>
</item>
<item>
<widget class="QgsDateTimeEdit" name="dateTimeTo"/>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
@ -854,93 +924,19 @@
</layout>
</widget>
<widget class="QWidget" name="tabContactsDialog">
<property name="enabled">
<bool>false</bool>
</property>
<attribute name="title">
<string>Contacts</string>
<string>Contact</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_10">
<item>
<widget class="QLabel" name="label_16">
<property name="text">
<string>Contacts, HELP TEXT</string>
<string>Contact describe the owner of the dataset.</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_10">
<item>
<spacer name="horizontalSpacer_6">
<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>
<widget class="QPushButton" name="btnAddContact">
<property name="toolTip">
<string>Add class</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>
<widget class="QPushButton" name="btnRemoveContact">
<property name="toolTip">
<string>Delete</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>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QTableWidget" name="tabContacts">
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<column>
<property name="text">
<string>Name</string>
</property>
</column>
<column>
<property name="text">
<string>Organization</string>
</property>
</column>
</widget>
</item>
<item>
<widget class="QScrollArea" name="panelDetails">
<property name="sizePolicy">
@ -957,80 +953,142 @@
<rect>
<x>0</x>
<y>0</y>
<width>513</width>
<height>419</height>
<width>754</width>
<height>608</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Name</string>
<item row="3" column="2" colspan="2">
<widget class="QLineEdit" name="lineEditContactPosition">
<property name="toolTip">
<string>Position/title of contact</string>
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QLineEdit" name="lineEditContactName"/>
<item row="0" column="2" colspan="2">
<widget class="QLineEdit" name="lineEditContactName">
<property name="toolTip">
<string>Name of contact</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_15">
<property name="toolTip">
<string>Role of contact</string>
</property>
<property name="text">
<string>Role</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<widget class="QComboBox" name="comboContactRole"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>Organization</string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="QLineEdit" name="lineEditContactOrganization"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_14">
<property name="toolTip">
<string>Position/title of contact</string>
</property>
<property name="text">
<string>Position</string>
</property>
</widget>
</item>
<item row="3" column="1" colspan="2">
<widget class="QLineEdit" name="lineEditContactPosition"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_18">
<property name="text">
<string>Email</string>
<item row="2" column="2" colspan="2">
<widget class="QLineEdit" name="lineEditContactOrganization">
<property name="toolTip">
<string>Organization contact belongs to/represents</string>
</property>
</widget>
</item>
<item row="4" column="1" colspan="2">
<widget class="QLineEdit" name="lineEditContactEmail"/>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_19">
<item row="0" column="0">
<widget class="QLabel" name="label_10">
<property name="toolTip">
<string>Name of contact</string>
</property>
<property name="text">
<string>Voice</string>
<string>Name</string>
</property>
</widget>
</item>
<item row="5" column="1" colspan="2">
<widget class="QLineEdit" name="lineEditContactVoice"/>
<item row="5" column="2" colspan="2">
<widget class="QLineEdit" name="lineEditContactVoice">
<property name="toolTip">
<string>Phone number</string>
</property>
</widget>
</item>
<item row="6" column="2" colspan="2">
<widget class="QLineEdit" name="lineEditContactFax">
<property name="toolTip">
<string>Fax number</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_20">
<property name="toolTip">
<string>Fax number</string>
</property>
<property name="text">
<string>Fax</string>
</property>
</widget>
</item>
<item row="6" column="1" colspan="2">
<widget class="QLineEdit" name="lineEditContactFax"/>
<item row="2" column="0">
<widget class="QLabel" name="label_12">
<property name="toolTip">
<string>Organization contact belongs to/represents</string>
</property>
<property name="text">
<string>Organization</string>
</property>
</widget>
</item>
<item row="1" column="2" colspan="2">
<widget class="QComboBox" name="comboContactRole">
<property name="toolTip">
<string>Role of contact</string>
</property>
<property name="editable">
<bool>true</bool>
</property>
<item>
<property name="text">
<string/>
</property>
</item>
<item>
<property name="text">
<string>custodian</string>
</property>
</item>
<item>
<property name="text">
<string>distributor</string>
</property>
</item>
<item>
<property name="text">
<string>owner</string>
</property>
</item>
</widget>
</item>
<item row="4" column="2" colspan="2">
<widget class="QLineEdit" name="lineEditContactEmail">
<property name="toolTip">
<string>Electronic mail address</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_19">
<property name="toolTip">
<string>Phone number</string>
</property>
<property name="text">
<string>Voice</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_21">
@ -1039,30 +1097,14 @@
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QPushButton" name="btnAddAddress">
<property name="toolTip">
<string>Add class</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="7" column="2">
<widget class="QPushButton" name="btnRemoveAddress">
<property name="toolTip">
<string>Delete</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="8" column="0" colspan="3">
<item row="8" column="0" colspan="4">
<widget class="QTableWidget" name="tabAddresses">
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
@ -1070,34 +1112,88 @@
<property name="text">
<string>Type</string>
</property>
<property name="toolTip">
<string>Type of address, e.g 'postal'</string>
</property>
</column>
<column>
<property name="text">
<string>Address</string>
</property>
<property name="toolTip">
<string>Free-form physical address component</string>
</property>
</column>
<column>
<property name="text">
<string>Postal Code</string>
</property>
<property name="toolTip">
<string>Postal (or ZIP) code</string>
</property>
</column>
<column>
<property name="text">
<string>City</string>
</property>
<property name="toolTip">
<string>City or locality name</string>
</property>
</column>
<column>
<property name="text">
<string>Administrative Area</string>
</property>
<property name="toolTip">
<string>Administrative area (state, provice/territory, etc.)</string>
</property>
</column>
<column>
<property name="text">
<string>Country</string>
</property>
<property name="toolTip">
<string>Free-form country</string>
</property>
</column>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_18">
<property name="toolTip">
<string>Electronic mail address</string>
</property>
<property name="text">
<string>Email</string>
</property>
</widget>
</item>
<item row="7" column="3">
<layout class="QHBoxLayout" name="horizontalLayout_10">
<item>
<widget class="QPushButton" name="btnAddAddress">
<property name="toolTip">
<string>Add address</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>
<widget class="QPushButton" name="btnRemoveAddress">
<property name="toolTip">
<string>Remove Address</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>
</layout>
</item>
</layout>
</widget>
</widget>
@ -1280,6 +1376,22 @@
<header>qgsprojectionselectionwidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsExtentGroupBox</class>
<extends>QGroupBox</extends>
<header>qgsextentgroupbox.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsSpinBox</class>
<extends>QSpinBox</extends>
<header>qgsspinbox.h</header>
</customwidget>
<customwidget>
<class>QgsDateTimeEdit</class>
<extends>QDateTimeEdit</extends>
<header>qgsdatetimeedit.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../../images/images.qrc"/>