19 #include <QPushButton> 
   22 #include <QInputDialog> 
   23 #include <QStringListModel> 
   39   tabWidget->setCurrentIndex( 0 );
 
   42   encodingFrame->setHidden( 
true );
 
   45   mDefaultCategories << tr( 
"Farming" ) << tr( 
"Climatology Meteorology Atmosphere" ) << tr( 
"Location" ) << tr( 
"Intelligence Military" ) << tr( 
"Transportation" ) << tr( 
"Structure" ) << tr( 
"Boundaries" );
 
   46   mDefaultCategories << tr( 
"Inland Waters" ) << tr( 
"Planning Cadastre" ) << tr( 
"Geoscientific Information" ) << tr( 
"Elevation" ) << tr( 
"Health" ) << tr( 
"Biota" ) << tr( 
"Oceans" ) << tr( 
"Environment" );
 
   47   mDefaultCategories << tr( 
"Utilities Communication" ) << tr( 
"Economy" ) << tr( 
"Society" ) << tr( 
"Imagery Base Maps Earth Cover" );
 
   48   mDefaultCategoriesModel = 
new QStringListModel( mDefaultCategories, 
this );
 
   49   mDefaultCategoriesModel->sort( 0 );  
 
   50   listDefaultCategories->setModel( mDefaultCategoriesModel );
 
   53   mCategoriesModel = 
new QStringListModel( listCategories );
 
   54   listCategories->setModel( mCategoriesModel );
 
   57   mRightsModel = 
new QStringListModel( listRights );
 
   58   listRights->setModel( mRightsModel );
 
   61   mConstraintsModel = 
new QStandardItemModel( tabConstraints );
 
   62   mConstraintsModel->setColumnCount( 2 );
 
   63   QStringList constraintheaders;
 
   64   constraintheaders << tr( 
"Type" ) << tr( 
"Constraint" );
 
   65   mConstraintsModel->setHorizontalHeaderLabels( constraintheaders );
 
   66   tabConstraints->setModel( mConstraintsModel );
 
   67   tabConstraints->setItemDelegate( 
new ConstraintItemDelegate( 
this ) );
 
   70   dateTimeFrom->setAllowNull( 
true );
 
   71   dateTimeTo->setAllowNull( 
true );
 
   74   mLinksModel = 
new QStandardItemModel( tabLinks );
 
   75   mLinksModel->setColumnCount( 7 );
 
   76   QStringList headers = QStringList();
 
   77   headers << tr( 
"Name" ) << tr( 
"Type" ) << tr( 
"URL" ) << tr( 
"Description" ) << tr( 
"Format" ) << tr( 
"MIME" ) << tr( 
"Size" );
 
   78   mLinksModel->setHorizontalHeaderLabels( headers );
 
   79   tabLinks->setModel( mLinksModel );
 
   80   tabLinks->setItemDelegate( 
new LinkItemDelegate( 
this ) );
 
   83   mHistoryModel = 
new QStringListModel( listHistory );
 
   84   listHistory->setModel( mHistoryModel );
 
   87   connect( tabWidget, &QTabWidget::currentChanged, 
this, &QgsMetadataWidget::updatePanel );
 
   88   connect( btnAutoSource, &QPushButton::clicked, 
this, &QgsMetadataWidget::fillSourceFromLayer );
 
   89   connect( btnAddVocabulary, &QPushButton::clicked, 
this, &QgsMetadataWidget::addVocabulary );
 
   90   connect( btnRemoveVocabulary, &QPushButton::clicked, 
this, &QgsMetadataWidget::removeSelectedVocabulary );
 
   91   connect( btnAddRight, &QPushButton::clicked, 
this, &QgsMetadataWidget::addRight );
 
   92   connect( btnRemoveRight, &QPushButton::clicked, 
this, &QgsMetadataWidget::removeSelectedRight );
 
   93   connect( btnAddLicence, &QPushButton::clicked, 
this, &QgsMetadataWidget::addLicence );
 
   94   connect( btnRemoveLicence, &QPushButton::clicked, 
this, &QgsMetadataWidget::removeSelectedLicence );
 
   95   connect( btnAddConstraint, &QPushButton::clicked, 
this, &QgsMetadataWidget::addConstraint );
 
   96   connect( btnRemoveConstraint, &QPushButton::clicked, 
this, &QgsMetadataWidget::removeSelectedConstraint );
 
   97   connect( btnSetCrsFromLayer, &QPushButton::clicked, 
this, &QgsMetadataWidget::fillCrsFromLayer );
 
   98   connect( btnSetCrsFromProvider, &QPushButton::clicked, 
this, &QgsMetadataWidget::fillCrsFromProvider );
 
   99   connect( btnAddAddress, &QPushButton::clicked, 
this, &QgsMetadataWidget::addAddress );
 
  100   connect( btnRemoveAddress, &QPushButton::clicked, 
this, &QgsMetadataWidget::removeSelectedAddress );
 
  101   connect( btnAddLink, &QPushButton::clicked, 
this, &QgsMetadataWidget::addLink );
 
  102   connect( btnRemoveLink, &QPushButton::clicked, 
this, &QgsMetadataWidget::removeSelectedLink );
 
  103   connect( btnAddHistory, &QPushButton::clicked, 
this, &QgsMetadataWidget::addHistory );
 
  104   connect( btnRemoveHistory, &QPushButton::clicked, 
this, &QgsMetadataWidget::removeSelectedHistory );
 
  105   connect( btnNewCategory, &QPushButton::clicked, 
this, &QgsMetadataWidget::addNewCategory );
 
  106   connect( btnAddDefaultCategory, &QPushButton::clicked, 
this, &QgsMetadataWidget::addDefaultCategories );
 
  107   connect( btnRemoveCategory, &QPushButton::clicked, 
this, &QgsMetadataWidget::removeSelectedCategories );
 
  112     btnAutoSource->setEnabled( 
false );
 
  113     btnAutoEncoding->setEnabled( 
false );
 
  114     btnSetCrsFromLayer->setEnabled( 
false );
 
  135       type = tr( 
"dataset" );
 
  136       typeUpper = tr( 
"Dataset" );
 
  137       mEncodingFrame->show();
 
  138       mAuthorFrame->hide();
 
  139       btnAutoSource->setEnabled( mLayer );
 
  143       type = tr( 
"project" );
 
  144       typeUpper = tr( 
"Project" );
 
  145       mEncodingFrame->hide();
 
  146       mAuthorFrame->show();
 
  147       tabWidget->removeTab( 4 );
 
  148       tabWidget->removeTab( 3 );
 
  149       btnAutoSource->setEnabled( 
true );
 
  153   mIdLabel->setText( tr( 
"This page describes the basic attribution of the %1. Please use the tooltips for more information." ).arg( type ) );
 
  154   mLabelCategories->setText( tr( 
"%1 categories." ).arg( typeUpper ) );
 
  155   mLabelContact->setText( tr( 
"Contacts related to the %1." ).arg( type ) );
 
  156   mLabelLinks->setText( tr( 
"Links describe ancillary resources and information related to this %1." ).arg( type ) );
 
  157   mLabelHistory->setText( tr( 
"History about the %1." ).arg( type ) );
 
  158   labelKeywords->setText( tr( 
"<html><head/><body><p>Keywords are optional, and provide a way to provide additional descriptive information about " 
  159                               "the %1. Edits made in the categories tab will update the category entry below. For the concept, we suggest " 
  160                               "to use a standard based vocabulary such as <a href=\"https://www.eionet.europa.eu/gemet/en/inspire-themes/\">" 
  161                               "<span style=\" text-decoration: underline; color:#0000ff;\">GEMET.</span></a></p></body></html>" ).arg( type ) );
 
  162   btnAutoSource->setText( tr( 
"Set from %1" ).arg( mMode == 
LayerMetadata ? tr( 
"layer" ) : tr( 
"project" ) ) );
 
  181   std::unique_ptr< QgsAbstractMetadataBase > md;
 
  185       md = std::make_unique< QgsLayerMetadata >();
 
  189       md = std::make_unique< QgsProjectMetadata >();
 
  197 void QgsMetadataWidget::fillSourceFromLayer()
 
  215 void QgsMetadataWidget::addVocabulary()
 
  217   const int row = tabKeywords->rowCount();
 
  218   tabKeywords->setRowCount( row + 1 );
 
  219   QTableWidgetItem *pCell = 
nullptr;
 
  222   pCell = 
new QTableWidgetItem( tr( 
"undefined %1" ).arg( row + 1 ) );
 
  223   tabKeywords->setItem( row, 0, pCell );
 
  226   pCell = 
new QTableWidgetItem();
 
  227   tabKeywords->setItem( row, 1, pCell );
 
  230 void QgsMetadataWidget::removeSelectedVocabulary()
 
  232   QItemSelectionModel *selectionModel = tabKeywords->selectionModel();
 
  233   const QModelIndexList selectedRows = selectionModel->selectedRows();
 
  234   for ( 
int i = 0; i < selectedRows.size() ; i++ )
 
  236     tabKeywords->model()->removeRow( selectedRows[i].row() );
 
  240 void QgsMetadataWidget::addLicence()
 
  242   QString newLicence = QInputDialog::getItem( 
this, tr( 
"New Licence" ), tr( 
"New Licence" ), 
parseLicenses(), 0, 
true );
 
  243   if ( tabLicenses->findItems( newLicence, Qt::MatchExactly ).isEmpty() )
 
  245     const int row = tabLicenses->rowCount();
 
  246     tabLicenses->setRowCount( row + 1 );
 
  247     QTableWidgetItem *pCell = 
new QTableWidgetItem( newLicence );
 
  248     tabLicenses->setItem( row, 0, pCell );
 
  252 void QgsMetadataWidget::removeSelectedLicence()
 
  254   QItemSelectionModel *selectionModel = tabLicenses->selectionModel();
 
  255   const QModelIndexList selectedRows = selectionModel->selectedRows();
 
  256   for ( 
int i = 0; i < selectedRows.size() ; i++ )
 
  258     tabLicenses->model()->removeRow( selectedRows[i].row() );
 
  262 void QgsMetadataWidget::addRight()
 
  264   QString newRight = QInputDialog::getText( 
this, tr( 
"New Right" ), tr( 
"New Right" ) );
 
  265   QStringList existingRights = mRightsModel->stringList();
 
  266   if ( ! existingRights.contains( newRight ) )
 
  268     existingRights.append( newRight );
 
  269     mRightsModel->setStringList( existingRights );
 
  273 void QgsMetadataWidget::removeSelectedRight()
 
  275   QItemSelectionModel *selection = listRights->selectionModel();
 
  276   if ( selection->hasSelection() )
 
  278     QModelIndex indexElementSelectionne = selection->currentIndex();
 
  280     QVariant item = mRightsModel->data( indexElementSelectionne, Qt::DisplayRole );
 
  281     QStringList list = mRightsModel->stringList();
 
  282     list.removeOne( item.toString() );
 
  283     mRightsModel->setStringList( list );
 
  287 void QgsMetadataWidget::addConstraint()
 
  289   const int row = mConstraintsModel->rowCount();
 
  290   mConstraintsModel->setItem( row, 0, 
new QStandardItem( tr( 
"undefined %1" ).arg( row + 1 ) ) );
 
  291   mConstraintsModel->setItem( row, 1, 
new QStandardItem( tr( 
"undefined %1" ).arg( row + 1 ) ) );
 
  294 void QgsMetadataWidget::removeSelectedConstraint()
 
  296   const QModelIndexList selectedRows = tabConstraints->selectionModel()->selectedRows();
 
  297   if ( selectedRows.empty() )
 
  299   mConstraintsModel->removeRow( selectedRows[0].row() );
 
  304   if ( ( mCrs.
isValid() ) && ( mLayer ) )
 
  307     spatialExtentSelector->setEnabled( 
true );
 
  308     spatialExtentSelector->setOutputCrs( mCrs );
 
  312       lblCurrentCrsStatus->setText( tr( 
"Same as layer properties and provider." ) );
 
  316       lblCurrentCrsStatus->setText( tr( 
"Same as layer properties but different than the provider." ) );
 
  320       lblCurrentCrsStatus->setText( tr( 
"Same as the provider but different than the layer properties." ) );
 
  324       lblCurrentCrsStatus->setText( tr( 
"Does not match either layer properties or the provider." ) );
 
  329     lblCurrentCrs->setText( tr( 
"CRS: Not set." ) );
 
  330     lblCurrentCrsStatus->setText( QString() );
 
  331     spatialExtentSelector->setEnabled( 
false );
 
  335 void QgsMetadataWidget::addAddress()
 
  337   const int row = tabAddresses->rowCount();
 
  338   tabAddresses->setRowCount( row + 1 );
 
  339   QTableWidgetItem *pCell = 
nullptr;
 
  342   pCell = 
new QTableWidgetItem( tr( 
"postal" ) );
 
  343   tabAddresses->setItem( row, 0, pCell );
 
  346   tabAddresses->setItem( row, 1, 
new QTableWidgetItem() );
 
  349   tabAddresses->setItem( row, 2, 
new QTableWidgetItem() );
 
  352   tabAddresses->setItem( row, 3, 
new QTableWidgetItem() );
 
  355   tabAddresses->setItem( row, 4, 
new QTableWidgetItem() );
 
  358   tabAddresses->setItem( row, 5, 
new QTableWidgetItem() );
 
  361 void QgsMetadataWidget::removeSelectedAddress()
 
  363   QItemSelectionModel *selectionModel = tabAddresses->selectionModel();
 
  364   const QModelIndexList selectedRows = selectionModel->selectedRows();
 
  365   for ( 
int i = 0; i < selectedRows.size() ; i++ )
 
  367     tabAddresses->model()->removeRow( selectedRows[i].row() );
 
  371 void QgsMetadataWidget::fillCrsFromLayer()
 
  373   mCrs = mLayer->
crs();
 
  377 void QgsMetadataWidget::fillCrsFromProvider()
 
  383 void QgsMetadataWidget::addLink()
 
  385   const int row = mLinksModel->rowCount();
 
  386   mLinksModel->setItem( row, 0, 
new QStandardItem( tr( 
"undefined %1" ).arg( row + 1 ) ) );
 
  387   mLinksModel->setItem( row, 1, 
new QStandardItem() );
 
  388   mLinksModel->setItem( row, 2, 
new QStandardItem() );
 
  389   mLinksModel->setItem( row, 3, 
new QStandardItem() );
 
  390   mLinksModel->setItem( row, 4, 
new QStandardItem() );
 
  391   mLinksModel->setItem( row, 5, 
new QStandardItem() );
 
  392   mLinksModel->setItem( row, 6, 
new QStandardItem() );
 
  395 void QgsMetadataWidget::removeSelectedLink()
 
  397   const QModelIndexList selectedRows = tabLinks->selectionModel()->selectedRows();
 
  398   if ( selectedRows.empty() )
 
  401   mLinksModel->removeRow( selectedRows[0].row() );
 
  404 void QgsMetadataWidget::addHistory()
 
  406   QString newHistory = QInputDialog::getText( 
this, tr( 
"New History" ), tr( 
"New History" ) );
 
  407   QStringList existingHistory = mHistoryModel->stringList();
 
  408   if ( ! existingHistory.contains( newHistory ) )
 
  410     existingHistory.append( newHistory );
 
  411     mHistoryModel->setStringList( existingHistory );
 
  415 void QgsMetadataWidget::removeSelectedHistory()
 
  417   QItemSelectionModel *selection = listHistory->selectionModel();
 
  418   if ( selection->hasSelection() )
 
  420     QModelIndex indexElementSelectionne = selection->currentIndex();
 
  422     QVariant item = mHistoryModel->data( indexElementSelectionne, Qt::DisplayRole );
 
  423     QStringList list = mHistoryModel->stringList();
 
  424     list.removeOne( item.toString() );
 
  425     mHistoryModel->setStringList( list );
 
  429 void QgsMetadataWidget::fillComboBox()
 
  434   comboType->setEditable( 
true );
 
  437   const QStringList &keys = types.keys();
 
  439   for ( 
const QString &type : keys )
 
  441     comboType->insertItem( i, type );
 
  442     comboType->setItemData( i, types.value( type ), Qt::ToolTipRole );
 
  448   comboLanguage->setEditable( 
true );
 
  449   comboLanguage->clear();
 
  451   const QStringList &k = countries.keys();
 
  453   for ( 
const QString &countryCode : k )
 
  455     comboLanguage->insertItem( i, countryCode );
 
  456     comboLanguage->setItemData( i, countries.value( countryCode ), Qt::ToolTipRole );
 
  461 void QgsMetadataWidget::setUiFromMetadata()
 
  464   lineEditParentId->setText( mMetadata->parentIdentifier() );
 
  467   if ( ! mMetadata->identifier().isEmpty() )
 
  469     lineEditIdentifier->setText( mMetadata->identifier() );
 
  473   if ( ! mMetadata->title().isEmpty() )
 
  475     whileBlocking( lineEditTitle )->setText( mMetadata->title() );
 
  479   if ( ! mMetadata->type().isEmpty() )
 
  481     if ( comboType->findText( mMetadata->type() ) == -1 )
 
  483       comboType->addItem( mMetadata->type() );
 
  485     comboType->setCurrentIndex( comboType->findText( mMetadata->type() ) );
 
  489   if ( ! mMetadata->language().isEmpty() )
 
  491     if ( comboLanguage->findText( mMetadata->language() ) == -1 )
 
  493       comboLanguage->addItem( mMetadata->language() );
 
  495     comboLanguage->setCurrentIndex( comboLanguage->findText( mMetadata->language() ) );
 
  499   textEditAbstract->setPlainText( mMetadata->abstract() );
 
  502   mCategoriesModel->setStringList( mMetadata->categories() );
 
  505   tabKeywords->setRowCount( 0 );
 
  506   QMapIterator<QString, QStringList> i( mMetadata->keywords() );
 
  507   while ( i.hasNext() )
 
  511     int currentRow = tabKeywords->rowCount() - 1;
 
  512     tabKeywords->item( currentRow, 0 )->setText( i.key() );
 
  513     tabKeywords->item( currentRow, 1 )->setText( i.value().join( QLatin1Char( 
',' ) ) );
 
  519     comboEncoding->setCurrentText( layerMetadata->encoding() );
 
  522     lineEditFees->setText( layerMetadata->fees() );
 
  525     tabLicenses->setRowCount( 0 );
 
  526     const QStringList &licenses = layerMetadata->licenses();
 
  527     for ( 
const QString &licence : licenses )
 
  529       int currentRow = tabLicenses->rowCount();
 
  530       tabLicenses->setRowCount( currentRow + 1 );
 
  531       QTableWidgetItem *pCell = tabLicenses->item( currentRow, 0 );
 
  534         pCell = 
new QTableWidgetItem;
 
  535         tabLicenses->setItem( currentRow, 0, pCell );
 
  537       pCell->setText( licence );
 
  541     mRightsModel->setStringList( layerMetadata->rights() );
 
  544     mConstraintsModel->clear();
 
  545     const QList<QgsLayerMetadata::Constraint> &constraints = layerMetadata->constraints();
 
  548       const int row = mConstraintsModel->rowCount();
 
  549       mConstraintsModel->setItem( row, 0, 
new QStandardItem( constraint.type ) );
 
  550       mConstraintsModel->setItem( row, 1, 
new QStandardItem( constraint.constraint ) );
 
  554     mCrs = layerMetadata->crs();
 
  558     const QList<QgsLayerMetadata::SpatialExtent> &spatialExtents = layerMetadata->extent().spatialExtents();
 
  559     if ( ! spatialExtents.isEmpty() )
 
  562       spatialExtentSelector->setOutputCrs( spatialExtents.at( 0 ).extentCrs );
 
  563       spatialExtentSelector->setOriginalExtent( spatialExtents.at( 0 ).bounds.toRectangle(), spatialExtents.at( 0 ).extentCrs );
 
  564       spatialExtentSelector->setOutputExtentFromOriginal();
 
  565       spinBoxZMaximum->setValue( spatialExtents.at( 0 ).bounds.zMaximum() );
 
  566       spinBoxZMinimum->setValue( spatialExtents.at( 0 ).bounds.zMinimum() );
 
  570     const QList<QgsDateTimeRange> &temporalExtents = layerMetadata->extent().temporalExtents();
 
  571     if ( ! temporalExtents.isEmpty() )
 
  574       dateTimeFrom->setDateTime( temporalExtents.at( 0 ).begin() );
 
  575       dateTimeTo->setDateTime( temporalExtents.at( 0 ).end() );
 
  579       dateTimeFrom->clear();
 
  585     mLineEditAuthor->setText( projectMetadata->author() );
 
  586     mCreationDateTimeEdit->setDateTime( projectMetadata->creationDateTime() );
 
  590   const QList<QgsAbstractMetadataBase::Contact> &contacts = mMetadata->contacts();
 
  591   if ( ! contacts.isEmpty() )
 
  595     lineEditContactName->setText( contact.
name );
 
  596     lineEditContactEmail->setText( contact.
email );
 
  597     lineEditContactFax->setText( contact.
fax );
 
  598     lineEditContactOrganization->setText( contact.
organization );
 
  599     lineEditContactPosition->setText( contact.
position );
 
  600     lineEditContactVoice->setText( contact.
voice );
 
  601     if ( comboContactRole->findText( contact.
role ) == -1 )
 
  603       comboContactRole->addItem( contact.
role );
 
  605     comboContactRole->setCurrentIndex( comboContactRole->findText( contact.
role ) );
 
  606     tabAddresses->setRowCount( 0 );
 
  607     const QList<QgsAbstractMetadataBase::Address> &addresses = contact.
addresses;
 
  610       int currentRow = tabAddresses->rowCount();
 
  611       tabAddresses->setRowCount( currentRow + 1 );
 
  612       tabAddresses->setItem( currentRow, 0,  
new QTableWidgetItem( address.type ) );
 
  613       tabAddresses->setItem( currentRow, 1,  
new QTableWidgetItem( address.address ) );
 
  614       tabAddresses->setItem( currentRow, 2,  
new QTableWidgetItem( address.postalCode ) );
 
  615       tabAddresses->setItem( currentRow, 3,  
new QTableWidgetItem( address.city ) );
 
  616       tabAddresses->setItem( currentRow, 4,  
new QTableWidgetItem( address.administrativeArea ) );
 
  617       tabAddresses->setItem( currentRow, 5,  
new QTableWidgetItem( address.country ) );
 
  622   const QList<QgsAbstractMetadataBase::Link> &links = mMetadata->links();
 
  623   mLinksModel->setRowCount( 0 );
 
  626     const int row = mLinksModel->rowCount();
 
  627     mLinksModel->setItem( row, 0, 
new QStandardItem( link.name ) );
 
  628     mLinksModel->setItem( row, 1, 
new QStandardItem( link.type ) );
 
  629     mLinksModel->setItem( row, 2, 
new QStandardItem( link.url ) );
 
  630     mLinksModel->setItem( row, 3, 
new QStandardItem( link.description ) );
 
  631     mLinksModel->setItem( row, 4, 
new QStandardItem( link.format ) );
 
  632     mLinksModel->setItem( row, 5, 
new QStandardItem( link.mimeType ) );
 
  633     mLinksModel->setItem( row, 6, 
new QStandardItem( link.size ) );
 
  637   mHistoryModel->setStringList( mMetadata->history() );
 
  653   syncFromCategoriesTabToKeywordsTab();
 
  654   QMap<QString, QStringList> keywords;
 
  655   for ( 
int i = 0; i < tabKeywords->rowCount() ; i++ )
 
  657     keywords.insert( tabKeywords->item( i, 0 )->text(), tabKeywords->item( i, 1 )->text().split( 
',' ) );
 
  667       layerMetadata->
setFees( lineEditFees->text() );
 
  670       QStringList licenses;
 
  671       for ( 
int i = 0; i < tabLicenses->rowCount() ; i++ )
 
  673         licenses.append( tabLicenses->item( i, 0 )->text() );
 
  678       layerMetadata->
setRights( mRightsModel->stringList() );
 
  681       layerMetadata->
setEncoding( comboEncoding->currentText() );
 
  684       QList<QgsLayerMetadata::Constraint> constraints;
 
  685       for ( 
int row = 0; row < mConstraintsModel->rowCount() ; row++ )
 
  688         constraint.
type = mConstraintsModel->item( row, 0 )->text();
 
  689         constraint.
constraint = mConstraintsModel->item( row, 1 )->text();
 
  690         constraints.append( constraint );
 
  697         layerMetadata->
setCrs( mCrs );
 
  702       spatialExtent.
bounds = 
QgsBox3d( spatialExtentSelector->outputExtent() );
 
  705       spatialExtent.
extentCrs = spatialExtentSelector->outputCrs();
 
  706       QList<QgsLayerMetadata::SpatialExtent> spatialExtents;
 
  707       spatialExtents.append( spatialExtent );
 
  708       QList<QgsDateTimeRange> temporalExtents;
 
  709       temporalExtents.append( QgsDateTimeRange( dateTimeFrom->dateTime(), dateTimeTo->dateTime() ) );
 
  720       projectMetadata->
setAuthor( mLineEditAuthor->text() );
 
  728   QList<QgsAbstractMetadataBase::Contact> contacts = mMetadata->contacts();
 
  729   if ( contacts.size() > 0 )
 
  730     contacts.removeFirst();
 
  732   contact.
email = lineEditContactEmail->text();
 
  733   contact.
position = lineEditContactPosition->text();
 
  734   contact.
fax = lineEditContactFax->text();
 
  735   contact.
voice = lineEditContactVoice->text();
 
  736   contact.
name = lineEditContactName->text();
 
  737   contact.
organization = lineEditContactOrganization->text();
 
  738   contact.
role = comboContactRole->currentText();
 
  739   QList<QgsAbstractMetadataBase::Address> addresses;
 
  740   for ( 
int i = 0; i < tabAddresses->rowCount() ; i++ )
 
  743     address.
type = tabAddresses->item( i, 0 )->text();
 
  744     address.
address = tabAddresses->item( i, 1 )->text();
 
  745     address.
postalCode = tabAddresses->item( i, 2 )->text();
 
  746     address.
city = tabAddresses->item( i, 3 )->text();
 
  748     address.
country = tabAddresses->item( i, 5 )->text();
 
  749     addresses.append( address );
 
  752   contacts.insert( 0, contact );
 
  756   QList<QgsAbstractMetadataBase::Link> links;
 
  757   for ( 
int row = 0; row < mLinksModel->rowCount() ; row++ )
 
  760     link.
name = mLinksModel->item( row, 0 )->text();
 
  761     link.
type = mLinksModel->item( row, 1 )->text();
 
  762     link.
url = mLinksModel->item( row, 2 )->text();
 
  763     link.
description = mLinksModel->item( row, 3 )->text();
 
  764     link.
format = mLinksModel->item( row, 4 )->text();
 
  765     link.
mimeType = mLinksModel->item( row, 5 )->text();
 
  766     link.
size = mLinksModel->item( row, 6 )->text();
 
  767     links.append( link );
 
  777   std::unique_ptr< QgsAbstractMetadataBase > md( 
metadata() );
 
  779   std::unique_ptr< QgsNativeMetadataBaseValidator > validator;
 
  783       validator = std::make_unique< QgsNativeMetadataValidator>();
 
  787       validator = std::make_unique< QgsNativeProjectMetadataValidator>();
 
  791   QList<QgsAbstractMetadataBaseValidator::ValidationResult> validationResults;
 
  792   bool results = validator->validate( md.get(), validationResults );
 
  799       errors += QLatin1String( 
"<b>" ) % result.section;
 
  800       if ( ! result._identifier().isNull() )
 
  802         errors += QLatin1Char( 
' ' ) % QVariant( result._identifier().toInt() + 1 ).toString();
 
  804       errors += QLatin1String( 
"</b>: " ) % result.note % QLatin1String( 
"<br />" );
 
  809     errors = tr( 
"Ok, it seems valid according to the QGIS Schema." );
 
  813   myStyle.append( QStringLiteral( 
"body { margin: 10px; }\n " ) );
 
  814   resultsCheckMetadata->clear();
 
  815   resultsCheckMetadata->document()->setDefaultStyleSheet( myStyle );
 
  816   resultsCheckMetadata->setHtml( errors );
 
  823   QMap<QString, QString> countries;
 
  824   countries.insert( QString(), QString() ); 
 
  828   if ( !file.open( QIODevice::ReadOnly ) )
 
  830     QgsDebugMsg( QStringLiteral( 
"Error while opening the CSV file: %1, %2 " ).arg( path, file.errorString() ) );
 
  836   while ( !file.atEnd() )
 
  838     QByteArray line = file.readLine();
 
  839     QList<QByteArray> items = line.split( 
',' );
 
  840     countries.insert( QString( items.at( 0 ).constData() ).trimmed(), QString( items.at( 1 ).constData() ).trimmed() );
 
  845   QFile secondFile( path );
 
  846   if ( !secondFile.open( QIODevice::ReadOnly ) )
 
  848     QgsDebugMsg( QStringLiteral( 
"Error while opening the CSV file: %1, %2 " ).arg( path, file.errorString() ) );
 
  853   secondFile.readLine();
 
  854   while ( !secondFile.atEnd() )
 
  856     QByteArray line = secondFile.readLine();
 
  857     QList<QByteArray> items = line.split( 
',' );
 
  858     countries.insert( QString( items.at( 2 ).constData() ).trimmed(), QString( items.at( 0 ).constData() ).trimmed() );
 
  866   QStringList wordList;
 
  867   wordList.append( QString() ); 
 
  871   if ( !file.open( QIODevice::ReadOnly ) )
 
  873     QgsDebugMsg( QStringLiteral( 
"Error while opening the CSV file: %1, %2 " ).arg( path, file.errorString() ) );
 
  879   while ( !file.atEnd() )
 
  881     QByteArray line = file.readLine();
 
  882     wordList.append( line.split( 
',' ).at( 0 ).trimmed() );
 
  890   QStringList wordList;
 
  891   wordList.append( QString() ); 
 
  895   if ( !file.open( QIODevice::ReadOnly ) )
 
  897     QgsDebugMsg( QStringLiteral( 
"Error while opening the CSV file: %1, %2 " ).arg( path, file.errorString() ) );
 
  903   while ( !file.atEnd() )
 
  905     QByteArray line = file.readLine();
 
  906     wordList.append( line.split( 
',' ).at( 0 ).trimmed() );
 
  914   QStringList wordList;
 
  915   wordList.append( QString() ); 
 
  919   if ( !file.open( QIODevice::ReadOnly ) )
 
  921     QgsDebugMsg( QStringLiteral( 
"Error while opening the CSV file: %1, %2 " ).arg( path, file.errorString() ) );
 
  925   while ( !file.atEnd() )
 
  927     QByteArray line = file.readLine();
 
  928     wordList.append( line.split( 
',' ).at( 0 ).trimmed() );
 
  936   QMap<QString, QString> types;
 
  937   types.insert( QString(), QString() ); 
 
  940   if ( !file.open( QIODevice::ReadOnly ) )
 
  942     QgsDebugMsg( QStringLiteral( 
"Error while opening the CSV file: %1, %2 " ).arg( path, file.errorString() ) );
 
  946   types.insert( QString(), QString() ); 
 
  947   while ( !file.atEnd() )
 
  949     QByteArray line = file.readLine();
 
  950     QList<QByteArray> items = line.split( 
';' );
 
  951     types.insert( items.at( 0 ).constData(), items.at( 1 ).constData() );
 
  965   return lineEditTitle->text();
 
  970   if ( 
title != lineEditTitle->text() )
 
  996 void QgsMetadataWidget::syncFromCategoriesTabToKeywordsTab()
 
  998   if ( mCategoriesModel->rowCount() > 0 )
 
 1000     QList<QTableWidgetItem *> categories = tabKeywords->findItems( QStringLiteral( 
"gmd:topicCategory" ), Qt::MatchExactly );
 
 1002     if ( !categories.isEmpty() )
 
 1004       row = categories.at( 0 )->row();
 
 1010       row = tabKeywords->rowCount() - 1;
 
 1011       tabKeywords->item( row, 0 )->setText( QStringLiteral( 
"gmd:topicCategory" ) );
 
 1013     tabKeywords->item( row, 1 )->setText( mCategoriesModel->stringList().join( QLatin1Char( 
',' ) ) );
 
 1017 void QgsMetadataWidget::updatePanel()
 
 1019   int index = tabWidget->currentIndex();
 
 1020   QString currentTabText = tabWidget->widget( index )->objectName();
 
 1021   if ( currentTabText == QLatin1String( 
"tabCategoriesDialog" ) )
 
 1025     QList<QTableWidgetItem *> categories = tabKeywords->findItems( QStringLiteral( 
"gmd:topicCategory" ), Qt::MatchExactly );
 
 1026     if ( !categories.isEmpty() )
 
 1028       const int row = categories.at( 0 )->row();
 
 1029       mCategoriesModel->setStringList( tabKeywords->item( row, 1 )->text().split( 
',' ) );
 
 1033       mCategoriesModel->setStringList( QStringList() );
 
 1036   else if ( currentTabText == QLatin1String( 
"tabKeywordsDialog" ) )
 
 1040     syncFromCategoriesTabToKeywordsTab();
 
 1042   else if ( currentTabText == QLatin1String( 
"tabValidationDialog" ) )
 
 1048 void QgsMetadataWidget::addNewCategory()
 
 1051   QString text = QInputDialog::getText( 
this, tr( 
"New Category" ),
 
 1052                                         tr( 
"New Category:" ), QLineEdit::Normal,
 
 1054   if ( ok && !text.isEmpty() )
 
 1056     QStringList list = mCategoriesModel->stringList();
 
 1057     if ( ! list.contains( text ) )
 
 1059       list.append( text );
 
 1060       mCategoriesModel->setStringList( list );
 
 1061       mCategoriesModel->sort( 0 );
 
 1066 void QgsMetadataWidget::addDefaultCategories()
 
 1068   const QModelIndexList selectedIndexes = listDefaultCategories->selectionModel()->selectedIndexes();
 
 1069   QStringList defaultCategoriesList = mDefaultCategoriesModel->stringList();
 
 1070   QStringList selectedCategories = mCategoriesModel->stringList();
 
 1072   for ( 
const QModelIndex &selection : selectedIndexes )
 
 1074     QVariant item = mDefaultCategoriesModel->data( selection, Qt::DisplayRole );
 
 1075     defaultCategoriesList.removeOne( item.toString() );
 
 1077     selectedCategories.append( item.toString() );
 
 1080   mDefaultCategoriesModel->setStringList( defaultCategoriesList );
 
 1081   mCategoriesModel->setStringList( selectedCategories );
 
 1082   mCategoriesModel->sort( 0 );
 
 1085 void QgsMetadataWidget::removeSelectedCategories()
 
 1087   const QModelIndexList selectedIndexes = listCategories->selectionModel()->selectedIndexes();
 
 1088   QStringList categories = mCategoriesModel->stringList();
 
 1089   QStringList defaultList = mDefaultCategoriesModel->stringList();
 
 1091   for ( 
const QModelIndex &selection : selectedIndexes )
 
 1093     QVariant item = mCategoriesModel->data( selection, Qt::DisplayRole );
 
 1094     categories.removeOne( item.toString() );
 
 1096     if ( mDefaultCategories.contains( item.toString() ) )
 
 1098       defaultList.append( item.toString() );
 
 1101   mCategoriesModel->setStringList( categories );
 
 1103   mDefaultCategoriesModel->setStringList( defaultList );
 
 1104   mDefaultCategoriesModel->sort( 0 );
 
 1108 LinkItemDelegate::LinkItemDelegate( QObject *parent )
 
 1109   : QStyledItemDelegate( parent )
 
 1114 QWidget *LinkItemDelegate::createEditor( QWidget *parent, 
const QStyleOptionViewItem &option, 
const QModelIndex &index )
 const 
 1116   if ( index.column() == 1 )
 
 1119     QComboBox *typeEditor = 
new QComboBox( parent );
 
 1120     typeEditor->setEditable( 
true );
 
 1121     QStringListModel *model = 
new QStringListModel( parent );
 
 1123     typeEditor->setModel( model );
 
 1126   else if ( index.column() == 5 )
 
 1129     QComboBox *mimeEditor = 
new QComboBox( parent );
 
 1130     mimeEditor->setEditable( 
true );
 
 1131     QStringListModel *model = 
new QStringListModel( parent );
 
 1133     mimeEditor->setModel( model );
 
 1137   return QStyledItemDelegate::createEditor( parent, option, index );
 
 1140 ConstraintItemDelegate::ConstraintItemDelegate( QObject *parent )
 
 1141   : QStyledItemDelegate( parent )
 
 1146 QWidget *ConstraintItemDelegate::createEditor( QWidget *parent, 
const QStyleOptionViewItem &option, 
const QModelIndex &index )
 const 
 1148   if ( index.column() == 0 )
 
 1151     QComboBox *typeEditor = 
new QComboBox( parent );
 
 1152     typeEditor->setEditable( 
true );
 
 1154     types << QStringLiteral( 
"access" ) << QStringLiteral( 
"use" ) << QStringLiteral( 
"other" );
 
 1155     QStringListModel *model = 
new QStringListModel( parent );
 
 1156     model->setStringList( types );
 
 1157     typeEditor->setModel( model );
 
 1161   return QStyledItemDelegate::createEditor( parent, option, index );