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   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     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   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   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   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       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     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       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 );
 
static QString reportStyleSheet(QgsApplication::StyleSheetType styleSheetType=QgsApplication::StyleSheetType::Qt)
Returns a css style sheet for reports, the styleSheetType argument determines what type of stylesheet...
static QString metadataPath()
Returns the path to the metadata directory.
A 3-dimensional box composed of x, y, z coordinates.
void setZMinimum(double z) SIP_HOLDGIL
Sets the minimum z value.
void setZMaximum(double z) SIP_HOLDGIL
Sets the maximum z value.
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
QString userFriendlyIdentifier(IdentifierType type=MediumString) const
Returns a user friendly identifier for the CRS.
virtual QgsCoordinateReferenceSystem crs() const =0
Returns the coordinate system for the data source.
Map canvas is a class for displaying all GIS data types on a canvas.
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
QgsRectangle extent() const
Returns the current zoom extent of the map canvas.
Base class for all map layer types.
QString publicSource() const
Gets a version of the internal layer definition that has sensitive bits removed (for example,...
QgsCoordinateReferenceSystem crs
QgsLayerMetadata metadata
virtual void setMetadata(const QgsLayerMetadata &metadata)
Sets the layer's metadata store.
virtual Q_INVOKABLE QgsDataProvider * dataProvider()
Returns the layer's data provider, it may be nullptr.
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system for the map render.
static QgsProject * instance()
Returns the QgsProject singleton instance.
void setMetadata(const QgsProjectMetadata &metadata)
Sets the project's metadata store.
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.